`
ravenex
  • 浏览: 10913 次
  • 性别: Icon_minigender_1
  • 来自: 体育仓库
社区版块
存档分类
最新评论

几种排序算法的对比

阅读更多
引用
Programming: Sort Testing

Your task this week is to implement four sorts, and do experiments to see how fast they run for different sizes and types of input data sets. The sorts are: selection sort, insertion sort, bubble sort and merge sort.

We're interested in two "modes" for your program:

A demonstration mode takes in a data set from the user, sorts it with each sorting algorithm, and prints out the data set at each step during each sort. In particular, it prints the entire set after each selection, each insertion, and each bubble swap. For merge sort, it describes each split into smaller subsets, and each merge into a unified subset. (Your output should match example output below.)
A comparison mode does not take a data set from the user or print out any data sets. Rather, it takes a single integer from the user, which is a set size. The program then constructs four data sets of that size: an already sorted set, a reverse-sorted set, a random set, and an "almost-sorted set" where approximately 20% of the elements are out of sort order. The program then uses all four sorts (insertion, selection, bubble, merge) to sort each of the four sets, and times how long each sort took to complete. The program then repeats the entire process for ten trials, and finds an average time for each sort, for each set type. Each of these averages (16 in all, from 160 trials) is then printed out for the user.
The usage of the program is:

$ java SortTester [1 or more integers]

If one integer is given, the program goes into comparison mode for input sets of the given size. If more than one integer is given, the program goes into demonstration mode and sorts the given set of integers.

You do not have to implement the user interface or even the code that collects and reports running-time data. That is all provided. Your only job is to fill in the actual routines that run the four sorts. However, please look over the provided code carefully so that you understand what it is doing, and why.


Please work from the following files:

SortTester.java is the driver class. It accepts and parses integer input from the user, and contains code to perform both demonstration and comparison modes. In the case of comparison mode, it generates sample sets, runs the sorts, and reports the average running times. You do not need to modify this file.
Sorters.java is the back-end that contains functions for performing the four sorts. There is one function set up for you for each sort. The functions take the form of
public static double sortType (int[] set, boolean printSteps)

The first argument, set, is the set of integers you are to sort. The second argument, printSteps, is true if the driver wants step-by-step printouts of how the function is sorting the array (i.e., demonstration mode), and false if the driver wants no printed output whatsoever (i.e., comparison mode). It is critical that if printSteps is false, no output is printed. This is because the act of printing is very, very slow, enough to dwarf the time it actually takes to sort. You will end up timing how long it takes to print, rather than how long it takes to sort.

The function returns a double of the number of milliseconds it takes to perform the sort. You do not need to figure out how to calculate the running time of the function; that is already provided in the framework. At the beginning of the function, the current system time is recorded. At the end of the function, the current system time is recorded again, and the difference between those two times is returned. Do not alter these lines, or else you may return erroneous running time results.


Once you have completed the code, perform experiments to see how long the four sorts take on different sizes and styles of input. Specifically, run your program in comparison mode for sets of 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000 and 10000. Plot the results on four graphs, one for each set type. Each set type graph should contain four plots, one for each sort type. The x axis of all four graphs should be the set size, from 1000 to 10000. The y axis should be the running time in milliseconds reported by your program, from 0 to the maximum time encountered in your experiment. (All four graphs should be scaled the same on both axes.)

You may use Microsoft Excel or any other plotting program to do your graphs. Feel free to modify the formatting of the output (in SortTester.java) so that it can be easily copied into Excel -- 160 numbers is a lot to copy by hand. If you like, you can try gnuplot, a free graphing program installed on Cunix. The usage would be

$ gnuplot HW3Sorted.gp

where HW3Sorted.gp is an input file that contains instructions about how to set up the graph, as well as the actual data to plot. The output is stored in a postscript file HW3Sorted.ps. Here is a sample gnuplot file that you can modify to fit your needs. (The output file name, and file format, are set as options in that file.)

Include your graphs, in PS (postscript), TIF or PDF files, as well as the output data from which you constructed your graphs, with your submission. Name the graphs and output file(s) so it is clear which is which. Do not submit graphs in any other format.

Example Output
$ java SortTester 9 5 1 7 9 20 2 5 6
SELECTION SORT 
9 5 1 7 9 20 2 5 6 
1 5 9 7 9 20 2 5 6 
1 2 9 7 9 20 5 5 6 
1 2 5 7 9 20 5 9 6 
1 2 5 5 9 20 7 9 6 
1 2 5 5 6 20 7 9 9 
1 2 5 5 6 7 20 9 9 
1 2 5 5 6 7 9 9 20 
1 2 5 5 6 7 9 9 20 
-=-=-=-=-=-=-=- 
INSERTION 
9 5 1 7 9 20 2 5 6 
5 9 1 7 9 20 2 5 6 
1 5 9 7 9 20 2 5 6 
1 5 7 9 9 20 2 5 6 
1 5 7 9 9 20 2 5 6 
1 5 7 9 9 20 2 5 6 
1 2 5 7 9 9 20 5 6 
1 2 5 5 7 9 9 20 6 
1 2 5 5 6 7 9 9 20 
-=-=-=-=-=-=-=- 
BUBBLE 
9 5 1 7 9 20 2 5 6 
Round 1 
5 9 1 7 9 20 2 5 6 
5 1 9 7 9 20 2 5 6 
5 1 7 9 9 20 2 5 6 
5 1 7 9 9 2 20 5 6 
5 1 7 9 9 2 5 20 6 
5 1 7 9 9 2 5 6 20 
Round 2 
1 5 7 9 9 2 5 6 20 
1 5 7 9 2 9 5 6 20 
1 5 7 9 2 5 9 6 20 
1 5 7 9 2 5 6 9 20 
Round 3 
1 5 7 2 9 5 6 9 20 
1 5 7 2 5 9 6 9 20 
1 5 7 2 5 6 9 9 20 
Round 4 
1 5 2 7 5 6 9 9 20 
1 5 2 5 7 6 9 9 20 
1 5 2 5 6 7 9 9 20 
Round 5 
1 2 5 5 6 7 9 9 20 
Round 6 
No swaps. Final set: 
1 2 5 5 6 7 9 9 20 
-=-=-=-=-=-=-=- 
MERGE 
9 5 1 7 9 20 2 5 6 
Divided 9 5 1 7 9 20 2 5 6 into 9 5 1 7 and 9 20 2 5 6 
Divided 9 5 1 7 into 9 5 and 1 7 
Divided 9 5 into 9 and 5 
Merged 9 and 5 into 5 9 
Divided 1 7 into 1 and 7 
Merged 1 and 7 into 1 7 
Merged 5 9 and 1 7 into 1 5 7 9 
Divided 9 20 2 5 6 into 9 20 and 2 5 6 
Divided 9 20 into 9 and 20 
Merged 9 and 20 into 9 20 
Divided 2 5 6 into 2 and 5 6 
Divided 5 6 into 5 and 6 
Merged 5 and 6 into 5 6 
Merged 2 and 5 6 into 2 5 6 
Merged 9 20 and 2 5 6 into 2 5 6 9 20 
Merged 1 5 7 9 and 2 5 6 9 20 into 1 2 5 5 6 7 9 9 20 
1 2 5 5 6 7 9 9 20


$ java SortTester 10000 
Testing performance for sets of 10000, 10 trials... 
SELECTION SORTED 10000 130.6 
SELECTION ALMOST-SORTED 10000 130.4 
SELECTION REVERSE 10000 131.0 
SELECTION RANDOM 10000 131.0 
INSERTION SORTED 10000 0.2 
INSERTION ALMOST-SORTED 10000 25.6 
INSERTION REVERSE 10000 218.2 
INSERTION RANDOM 10000 109.5 
BUBBLE SORTED 10000 0.0 
BUBBLE ALMOST-SORTED 10000 523.9 
BUBBLE REVERSE 10000 676.1 
BUBBLE RANDOM 10000 689.3 
MERGE SORTED 10000 5.3 
MERGE ALMOST-SORTED 10000 4.2 
MERGE REVERSE 10000 3.9 
MERGE RANDOM 10000 5.2



Programming Analysis

Answer the following questions in your README (each worth 5 points):


For already sorted input, why did the running time for each sort grow as it did with respect to set size? Which sort(s) were able to efficiently recognize already-sorted input, and which continued to take quadratic time as sets grew larger? Why?

What was the ranking of your sorts from fastest to slowest for random input? Why did the slowest sorts perform slowest, and the fastest ones perform fastest? Did your results here match up with expectations?

What differences, if any, do you see between the performances of your sorts over reverse-sorted input and random input? How do you explain these differences or lack of differences?

What differences, if any, do you notice between random input and almost-sorted input? (One of your sorts should have performed surprisingly differently, where the other three performed more or less the same.) How can you explain this? What can you conclude about the suitability of different sorts for different types of input data?


Extra Credit

10 points extra credit for including two variations of Shellsort (Shellsort-A and Shellsort-B) throughout the entire programming assignment (and analysis). This will require adjusting both Java files and adding new plots to all four graphs. Shellsort-A should start with an interval of 1/2 input size and reduce the interval by half on each iteration. (Recall that Shellsort reverts to insertion sort once the interval is 1, and while sorting every "slice" as we discussed in class.) Shellsort-B should start with an interval of 1/2 input size and each iteration should reduce the interval by 2/3 (e.g., 120 goes to 40). For demonstration mode, both should first print the gap sequence they will use, then, for each interval in the gap sequence, each slice, before and after sorting that slice, and then the complete list after the slices are reassembled. (You do not need to print the details of insertion sort for each individual slice). Be sure to test on lists with duplicate elements! (You can modify the driver code, SortTester, to create such lists to test on.) What differences do you see between the performance of Shellsort-A and Shellsort-B, if any? How do you explain these differences by the interval reduction strategy? Do you notice anything unusual if the input size is a power of 2? (Recall our discussion of Shell's gap sequence, which goes by powers of 2.)

10 points extra credit for including four variations of quicksort (quicksort-A through quicksort-D) throughout the entire programming assignment (and analysis). This will require adjusting both Java files and adding new plots to all four graphs. Quicksort-A should use the middle element as the pivot; quicksort-B should use median-of-three pivot selection; quicksort-C should use median-of-five, and quicksort-D should (update) use the actual median element (i.e., scan the entire list and calculate the optimal pivot). For demonstration mode, each recursive call to quicksort should print the original list, the pivot selected, each pair of elements that are swapped, and the final list, with a clear distinction between left partition, pivot and right partition. Be sure to test on lists with duplicate elements! (You can modify the driver code, SortTester, to create such lists to test on.) How does quicksort match up against the other sorts, mergesort in particular? For each type of input set, how did pivot selection affect quicksort running time? How do you explain these differences? (Note: quicksort-A may crash on Cunix for large data sets due to running out of memory. Don't panic if this happens. Document the set size where quicksort runs out of memeory, and include quicksort-A on your graph only up until that set size.)


SortTester.java:
import java.util.Random;

/**
 * Sort-tester driver class for 3134 S08 HW3. DKE, 2/2008
 */
public class SortTester {

    /**
     * Constructor receives command-line arguments.
     */
    public SortTester(String[] args) throws Exception {

        // At least one argument required.
        if (args.length < 1) {
            throw new Exception(
                    "SortTester must be run with at least 1 integer argument.");
        }

        if (args.length == 1) {

            // If the user gave one argument it is assumed to be a set
            // size for comparison mode.
            comparison(Integer.parseInt(args[0]));
        } else {

            // Otherwise, the multiple arguments are assumed to be
            // a set for demonstration mode.
            demonstration(args);
        }

    }

    /**
     * Main function constructs a SortTester object.
     */
    public static void main(String[] args) throws Exception {
        try {
            new SortTester(args);
        } catch (Exception e) {
            //System.err.println(e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * Sort the set provided the user. Demonstrate how the various sets work.
     */
    public void demonstration(String[] stringSet) throws Exception {

        int[] set;

        /**
         * Prepare an array of ints that is the same size as the array of
         * strings given at the command line.
         */
        set = new int[stringSet.length];

        // Convert the strings to ints..
        // For each string in the input set...
        for (int i = 0; i < stringSet.length; i++) {

            String token = stringSet[i];

            try {
                // Convert the string to int.
                set[i] = Integer.parseInt(token);
            } catch (NumberFormatException e) {
                throw new Exception("Bad integer in position " + (i + 1) + ": "
                        + token);
            }
        }

        System.out.println("Ready to sort " + set.length + " integers.");

        // Run selection sort
        Sorters.selectionSort(makeCopy(set), true);

        // Run insertion sort
        Sorters.insertionSort(makeCopy(set), true);

        // Run bubble sort
        Sorters.bubbleSort(makeCopy(set), true);

        // Run merge sort
        Sorters.mergeSort(makeCopy(set), true);

        // Run Shellsort-A
        Sorters.shellSortA(makeCopy(set), true);
        
        // Run Shellsort-B
        Sorters.shellSortB(makeCopy(set), true);
        
        // Run Quicksort-A
        Sorters.quickSortA(makeCopy(set), true);
        
        // Run Quicksort-B
        Sorters.quickSortB(makeCopy(set), true);
        
        // Run Quicksort-C
        Sorters.quickSortC(makeCopy(set), true);
        
        // Run Quicksort-D
        Sorters.quickSortD(makeCopy(set), true);
    }

    public static int[] makeCopy(int[] set) {

        int[] result = new int[set.length];
        for (int i = 0; i < set.length; i++) {
            result[i] = set[i];
        }
        return result;
    }

    /**
     * Run each the sorts 10 times on a user-given set size and report the
     * average time it took for each sort to run.
     */
    public void comparison(int setSize) throws Exception {

        // Number of trials
        int trials = 10;
        // Matrix stores the times for each experiment
        // First [] stores the sort type, from 0 to 9
        // Second [] stores the set type, from 0 to 3
        double[][] times = new double[10][4];

        int[] set;

        System.out.println("Testing performance for sets of " + setSize + ", "
                + trials + " trials...");

        // For each trial...
        for (int i = 0; i < trials; i++) {

            // Make a sorted set and do selection sort
            set = makeSortedSet(setSize);
            times[0][0] += Sorters.selectionSort(set, false);

            // Make a sorted set and do insertion sort
            set = makeSortedSet(setSize);
            times[1][0] += Sorters.insertionSort(set, false);

            // Make a sorted set and do bubble sort
            set = makeSortedSet(setSize);
            times[2][0] += Sorters.bubbleSort(set, false);

            // Make an sorted set and do merge sort
            set = makeSortedSet(setSize);
            times[3][0] += Sorters.mergeSort(set, false);
            
            // Make an sorted set and do Shellsort-A
            set = makeSortedSet(setSize);
            times[4][0] += Sorters.shellSortA(set, false);
            
            // Make an sorted set and do Shellsort-B
            set = makeSortedSet(setSize);
            times[5][0] += Sorters.shellSortB(set, false);
            
            // Make an sorted set and do Quicksort-A
            set = makeSortedSet(setSize);
            times[6][0] += Sorters.quickSortA(set, false);
            
            // Make an sorted set and do Quicksort-B
            set = makeSortedSet(setSize);
            times[7][0] += Sorters.quickSortB(set, false);
            
            // Make an sorted set and do Quicksort-C
            set = makeSortedSet(setSize);
            times[8][0] += Sorters.quickSortC(set, false);
            
            // Make an sorted set and do Quicksort-D
            set = makeSortedSet(setSize);
            times[9][0] += Sorters.quickSortD(set, false);

            // Make an almost sorted set and do selection sort
            set = makeAlmostSortedSet(setSize);
            times[0][1] += Sorters.selectionSort(set, false);

            // Make an almost sorted set and do insertion sort
            set = makeAlmostSortedSet(setSize);
            times[1][1] += Sorters.insertionSort(set, false);

            // Make an almost sorted set and do bubble sort
            set = makeAlmostSortedSet(setSize);
            times[2][1] += Sorters.bubbleSort(set, false);

            // Make an almost sorted set and do merge sort
            set = makeAlmostSortedSet(setSize);
            times[3][1] += Sorters.mergeSort(set, false);
            
            // Make an almost sorted set and do Shellsort-A
            set = makeAlmostSortedSet(setSize);
            times[4][1] += Sorters.shellSortA(set, false);
            
            // Make an almost sorted set and do Shellsort-B
            set = makeAlmostSortedSet(setSize);
            times[5][1] += Sorters.shellSortB(set, false);
            
            // Make an almost sorted set and do Quicksort-A
            set = makeAlmostSortedSet(setSize);
            times[6][1] += Sorters.quickSortA(set, false);
            
            // Make an almost sorted set and do Quicksort-B
            set = makeAlmostSortedSet(setSize);
            times[7][1] += Sorters.quickSortB(set, false);
            
            // Make an almost sorted set and do Quicksort-C
            set = makeAlmostSortedSet(setSize);
            times[8][1] += Sorters.quickSortC(set, false);
            
            // Make an almost sorted set and do Quicksort-D
            set = makeAlmostSortedSet(setSize);
            times[9][1] += Sorters.quickSortD(set, false);

            // Make a reverse sorted set and do selection sort
            set = makeReverseSet(setSize);
            times[0][2] += Sorters.selectionSort(set, false);

            // Make a reverse sorted set and do insertion sort
            set = makeReverseSet(setSize);
            times[1][2] += Sorters.insertionSort(set, false);

            // Make a reverse sorted set and do bubble sort
            set = makeReverseSet(setSize);
            times[2][2] += Sorters.bubbleSort(set, false);

            // Make a reverse sorted set and do merge sort
            set = makeReverseSet(setSize);
            times[3][2] += Sorters.mergeSort(set, false);
            
            // Make an reverse sorted set and do Shellsort-A
            set = makeReverseSet(setSize);
            times[4][2] += Sorters.shellSortA(set, false);
            
            // Make an reverse sorted set and do Shellsort-B
            set = makeReverseSet(setSize);
            times[5][2] += Sorters.shellSortB(set, false);
            
            // Make an reverse sorted set and do Quicksort-A
            set = makeReverseSet(setSize);
            times[6][2] += Sorters.quickSortA(set, false);
            
            // Make an reverse sorted set and do Quicksort-B
            set = makeReverseSet(setSize);
            times[7][2] += Sorters.quickSortB(set, false);
            
            // Make an reverse sorted set and do Quicksort-C
            set = makeReverseSet(setSize);
            times[8][2] += Sorters.quickSortC(set, false);
            
            // Make an reverse sorted set and do Quicksort-D
            set = makeReverseSet(setSize);
            times[9][2] += Sorters.quickSortD(set, false);

            // Make a random set and do selection sort
            set = makeRandomSet(setSize);
            times[0][3] += Sorters.selectionSort(set, false);

            // Make a random set and do insertion sort
            set = makeRandomSet(setSize);
            times[1][3] += Sorters.insertionSort(set, false);

            // Make a random set and do bubble sort
            set = makeRandomSet(setSize);
            times[2][3] += Sorters.bubbleSort(set, false);

            // Make a random set and do merge sort
            set = makeRandomSet(setSize);
            times[3][3] += Sorters.mergeSort(set, false);
            
            // Make an random set and do Shellsort-A
            set = makeRandomSet(setSize);
            times[4][3] += Sorters.shellSortA(set, false);
            
            // Make an random set and do Shellsort-B
            set = makeRandomSet(setSize);
            times[5][3] += Sorters.shellSortB(set, false);
            
            // Make an random set and do Quicksort-A
            set = makeRandomSet(setSize);
            times[6][3] += Sorters.quickSortA(set, false);
            
            // Make an random set and do Quicksort-B
            set = makeRandomSet(setSize);
            times[7][3] += Sorters.quickSortB(set, false);
            
            // Make an random set and do Quicksort-C
            set = makeRandomSet(setSize);
            times[8][3] += Sorters.quickSortC(set, false);
            
            // Make an random set and do Quicksort-D
            set = makeRandomSet(setSize);
            times[9][3] += Sorters.quickSortD(set, false);
        }

        // Now we need to compile and print the results.
        // For each sort type...
        for (int sortType = 0; sortType < 10; sortType++) {

            // Choose the string that represents the sort type
            String sortTypeString;
            if (sortType == 0) {
                sortTypeString = "SELECTION";
            } else if (sortType == 1) {
                sortTypeString = "INSERTION";
            } else if (sortType == 2) {
                sortTypeString = "BUBBLE";
            } else if (sortType == 3) {
                sortTypeString = "MERGE";
            } else if (sortType == 4) {
                sortTypeString = "SHELLSORT-A";
            } else if (sortType == 5) {
                sortTypeString = "SHELLSORT-B";
            } else if (sortType == 6) {
                sortTypeString = "QUICKSORT-A";
            } else if (sortType == 7) {
                sortTypeString = "QUICKSORT-B";
            } else if (sortType == 8) {
                sortTypeString = "QUICKSORT-C";
            } else {
                sortTypeString = "QUICKSORT-D";
            }

            // For each set type..
            for (int setType = 0; setType < 4; setType++) {

                // Find the AVERAGE time among the trials by dividing the
                // running sum by the number of trials
                times[sortType][setType] /= trials;

                // Choose the string that represents the set type
                String setTypeString;
                if (setType == 0) {
                    setTypeString = "SORTED";
                } else if (setType == 1) {
                    setTypeString = "ALMOST-SORTED";
                } else if (setType == 2) {
                    setTypeString = "REVERSE";
                } else {
                    setTypeString = "RANDOM";
                }

                // Print the results
                System.out.println(sortTypeString + " " + setTypeString + " "
                        + setSize + " " + times[sortType][setType]);

            }
        }

    }

    /**
     * Make a sorted set of integers.
     */
    public static int[] makeSortedSet(int size) {

        int[] result = new int[size];

        for (int i = 0; i < size; i++) {
            result[i] = i + 1;
        }

        return result;
    }

    /**
     * Make an almost-sorted set of integers.
     */
    public static int[] makeAlmostSortedSet(int size) {

        int[] result = new int[size];

        for (int i = 0; i < size; i++) {
            result[i] = i + 1;
        }

        Random r = new Random();

        // Swap one-fifth of the elements with other elements
        for (int i = 0; i < (size / 10); i++) {

            // Pick two random elements and swap them
            int firstToSwap = r.nextInt(size);
            int secondToSwap = r.nextInt(size);

            int crossover = result[firstToSwap];
            result[firstToSwap] = result[secondToSwap];
            result[secondToSwap] = crossover;
        }

        return result;
    }

    /**
     * Make a reverse-sorted set of integers.
     */
    public static int[] makeReverseSet(int size) {

        int[] result = new int[size];

        for (int i = 0; i < size; i++) {
            result[i] = size - i;
        }

        return result;
    }

    /**
     * Make a random set of integers.
     */
    public static int[] makeRandomSet(int size) {

        Random r = new Random();

        int[] result = new int[size];

        for (int i = 0; i < size; i++) {
            result[i] = r.nextInt();
        }

        return result;
    }
}


Sorters.java:
/**
 * Back-end class for 3134 HW3. This is the one you edit.
 */
public class Sorters {

    /**
     * Run selection sort on a set.
     */
    public static double selectionSort(int[] set, boolean printSteps) {

        // Mark the start time.
        double startTime = System.currentTimeMillis();

        // Print the input set if we are asked to.
        if (printSteps) {
            System.out.println("SELECTION SORT");
            System.out.println(printList(set));
        }

        // DO SELECTION SORT HERE!
        // Print progress if printSteps is set to true.
        int length = set.length;
        for (int i = 0; i < length - 1; ++i) {
            int minIdx = i;
            for (int j = i + 1; j < length; ++j) {
                if (set[minIdx] > set[j]) {
                    minIdx = j;
                }
            }
            swap(set, i, set, minIdx);

            // print progress
            if (printSteps) {
                System.out.println(printList(set));
            }
        }

        // Print the output set if we are asked to.
        if (printSteps) {
            System.out.println("-=-=-=-=-=-=-=-");
        }

        // Mark the finish time and return the time it took to sort.
        return System.currentTimeMillis() - startTime;
    }

    /**
     * Run insertion sort on a set.
     */
    public static double insertionSort(int[] set, boolean printSteps) {

        // Mark the start time.
        double startTime = System.currentTimeMillis();

        insertionSort(set, 0, set.length - 1, printSteps);

        // Mark the finish time and return the time it took to sort.
        return System.currentTimeMillis() - startTime;
    }

    /**
     * Internal method shared by insertion sort and Quicksort methods.
     * 
     * @param set
     * @param left
     * @param right
     * @param printSteps
     */
    private static void insertionSort(int[] set, int left, int right,
            boolean printSteps) {

        int length = right - left + 1;

        // Print the input set if we are asked to.
        if (printSteps) {
            System.out.println("INSERTION");
            System.out.println(printList(set, left, length));
            ;
        }

        // DO INSERTION SORT HERE!
        // Print progress if printSteps is set to true.
        int j = 0;

        for (int i = left + 1; i <= right; ++i) {
            // avoids explicit swap
            int min = set[i];
            for (j = i; (j > left) && (set[j - 1] > min); --j) {
                set[j] = set[j - 1];
            }
            set[j] = min;

            // print progress
            if (printSteps) {
                System.out.println(printList(set, left, length));
            }
        }

        // Print the output set if we are asked to.
        if (printSteps) {
            System.out.println("-=-=-=-=-=-=-=-");
        }
    }

    /**
     * Run bubble sort on a set.
     */
    public static double bubbleSort(int[] set, boolean printSteps) {

        // Mark the start time.
        double startTime = System.currentTimeMillis();

        // Print the input set if we are asked to.
        if (printSteps) {
            System.out.println("BUBBLE");
            System.out.println(printList(set));
        }

        // DO BUBBLE SORT HERE!
        // Print progress if printSteps is set to true.
        int length = set.length;
        for (int round = 1; round < length; ++round) {
            boolean hasSwap = false;
            if (printSteps) {
                System.out.println("Round " + round);
            }
            for (int j = 0; j < length - round; ++j) {
                if (set[j] > set[j + 1]) {
                    swap(set, j, set, j + 1);
                    hasSwap = true;
                    if (printSteps) {
                        System.out.println(printList(set));
                    }
                }
            }

            // the array is already sorted, end loop
            if (!hasSwap) {
                break;
            }
        }

        // Print the output set if we are asked to.
        if (printSteps) {
            System.out.println("No swaps.  Final set:");
            System.out.println(printList(set));
            ;
            System.out.println("-=-=-=-=-=-=-=-");
        }

        // Mark the finish time and return the time it took to sort.
        return System.currentTimeMillis() - startTime;

    }

    /**
     * Run merge sort on a set.
     */
    public static double mergeSort(int[] set, boolean printSteps) {

        // Mark the start time.
        double startTime = System.currentTimeMillis();

        // Print the input set if we are asked to.
        if (printSteps) {
            System.out.println("MERGE");
            System.out.println(printList(set));
        }

        // DO MERGE SORT HERE!
        // (You will need to call other functions, recursively)
        // Print progress if printSteps is set to true.
        int length = set.length;
        int[] copy = new int[length];
        mergeSort(set, copy, 0, length - 1, printSteps);

        // Print the output set if we are asked to.
        if (printSteps) {
            System.out.println(printList(set));
            System.out.println("-=-=-=-=-=-=-=-");
        }

        // Mark the finish time and return the time it took to sort.
        return System.currentTimeMillis() - startTime;
    }

    /**
     * Internal method that makes resursive calls.
     * 
     * @param array
     *            the original array to sort.
     * @param tempArray
     *            an array to place the merged result.
     * @param left
     *            the left-most index of the subarray.
     * @param right
     *            the right-most index of the subarray.
     * @param printSteps
     *            whether to print sort progress.
     */
    private static void mergeSort(int[] array, int[] tempArray, int left,
            int right, boolean printSteps) {
        if (left < right) {
            int center = (left + right) / 2;
            if (printSteps) {
                System.out.print("Divided ");
                System.out.print(printList(array, left, right - left + 1));
                System.out.print(" into ");
                System.out.print(printList(array, left, center - left + 1));
                System.out.print(" and ");
                System.out
                        .println(printList(array, center + 1, right - center));
            }
            mergeSort(array, tempArray, left, center, printSteps);
            mergeSort(array, tempArray, center + 1, right, printSteps);
            merge(array, tempArray, left, center + 1, right, printSteps);
        }
    }

    /**
     * Internal method to merge two sorted halves of a subarray.
     * 
     * @param array
     *            the original array to sort.
     * @param tempArray
     *            an array to place the merged result.
     * @param leftIdx
     *            the left-most index of the subarray.
     * @param rightIdx
     *            the index of the start of the second half.
     * @param rightEnd
     *            the right-most index of the subarray.
     * @param printSteps
     *            whether to print sort progress.
     */
    private static void merge(int[] array, int[] tempArray, int leftIdx,
            int rightIdx, int rightEnd, boolean printSteps) {
        int leftEnd = rightIdx - 1;
        int tempIdx = leftIdx;
        int tempIdx2 = tempIdx;
        int numElements = rightEnd - leftIdx + 1;

        if (printSteps) {
            System.out.print("Merged ");
            System.out.print(printList(array, leftIdx, leftEnd - leftIdx + 1));
            System.out.print(" and ");
            System.out
                    .print(printList(array, rightIdx, rightEnd - rightIdx + 1));
        }

        // main loop
        while (leftIdx <= leftEnd && rightIdx <= rightEnd) {
            if (array[leftIdx] < array[rightIdx]) {
                tempArray[tempIdx++] = array[leftIdx++];
            } else {
                tempArray[tempIdx++] = array[rightIdx++];
            }
        }

        // copy rest of left half
        while (leftIdx <= leftEnd) {
            tempArray[tempIdx++] = array[leftIdx++];
        }

        // copy rest of right half
        while (rightIdx <= rightEnd) {
            tempArray[tempIdx++] = array[rightIdx++];
        }

        if (printSteps) {
            System.out.print(" into ");
            System.out.println(printList(tempArray, tempIdx2, tempIdx
                    - tempIdx2));
        }

        // copy tempArray back
        for (int i = 0; i < numElements; ++i, --rightEnd) {
            array[rightEnd] = tempArray[rightEnd];
        }
    }

    /**
     * Run Shellsort-A on a set.
     */
    public static double shellSortA(int[] set, boolean printSteps) {

        // Print the input set if we are asked to.
        if (printSteps) {
            System.out.println("SHELLSORT-A");
            System.out.println(printList(set));
        }

        // DO SHELLSORT-A HERE!
        // Print progress if printSteps is set to true.
        double result = shellSort(set, 1.0 / 2.0, printSteps);

        // Print the output set if we are asked to.
        if (printSteps) {
            System.out.println(printList(set));
            System.out.println("-=-=-=-=-=-=-=-");
        }

        return result;
    }

    /**
     * Run Shellsort-B on a set.
     */
    public static double shellSortB(int[] set, boolean printSteps) {

        // Print the input set if we are asked to.
        if (printSteps) {
            System.out.println("SHELLSORT-B");
            System.out.println(printList(set));
        }

        // DO SHELLSORT-B HERE!
        // Print progress if printSteps is set to true.
        double result = shellSort(set, 1.0 / 3.0, printSteps);

        // Print the output set if we are asked to.
        if (printSteps) {
            System.out.println(printList(set));
            System.out.println("-=-=-=-=-=-=-=-");
        }

        return result;
    }

    /**
     * Internal method, run Shellsort on a set.
     */
    private static double shellSort(int[] set, double reductionRatio,
            boolean printSteps) {

        // Mark the start time.
        double startTime = System.currentTimeMillis();

        int length = set.length;

        // print gap sequence
        if (printSteps) {
            System.out.print("GAP SEQUENCE:");
            for (int gap = length / 2; gap > 0; gap *= reductionRatio) {
                System.out.print(" " + gap);
            }
            System.out.println();
        }

        for (int gap = length / 2; gap > 0; gap *= reductionRatio) {

            // print the slices before sort in current interval
            if (printSteps) {
                System.out.println("Gap: " + gap);
                for (int i = 0; i < gap; ++i) {
                    if (printSteps) {
                        System.out.print("Slice before:");
                        for (int j = i; j < length; j += gap) {
                            System.out.print(" " + set[j]);
                        }
                        System.out.println();
                    }
                }
            }

            // sort the slices
            for (int i = gap; i < length; ++i) {

                // avoids explicit swap
                int temp = set[i];
                int j = i;

                for (; (j >= gap) && (temp < set[j - gap]); j -= gap) {
                    set[j] = set[j - gap];
                }
                set[j] = temp;
            }

            // print the slices after sort in current interval
            if (printSteps) {
                for (int i = 0; i < gap; ++i) {
                    if (printSteps) {
                        System.out.print("Slice after:");
                        for (int j = i; j < length; j += gap) {
                            System.out.print(" " + set[j]);
                        }
                        System.out.println();
                    }
                }
            }
        }

        // Mark the finish time and return the time it took to sort.
        return System.currentTimeMillis() - startTime;
    }

    private static final int CUTOFF = 10;

    public static double quickSortA(int[] set, boolean printSteps) {
        // Mark the start time.
        double startTime = System.currentTimeMillis();

        // Print the input set if we are asked to.
        if (printSteps) {
            System.out.println("QUICKSORT-A");
            System.out.println(printList(set));
        }

        // DO QUICKSORT-A HERE!
        // Print progress if printSteps is set to true.
        _quickSortA(set, 0, set.length - 1, printSteps);

        // Print the output set if we are asked to.
        if (printSteps) {
            System.out.println(printList(set));
            System.out.println("-=-=-=-=-=-=-=-");
        }

        // Mark the finish time and return the time it took to sort.
        return System.currentTimeMillis() - startTime;
    }

    private static void _quickSortA(int[] set, int left, int right,
            boolean printSteps) {
        if (printSteps) {
            System.out.println("List: " + printList(set));
        }

        if (left + CUTOFF <= right) {
            // select pivot
            int center = (left + right) / 2;
            int pivot = set[center];
            if (printSteps) {
                System.out.println("Pivot: " + pivot);
            }

            // place pivot at position right
            set[center] = set[right];
            set[right] = pivot;

            // Begin partitioning
            int i = left - 1;
            int j = right;
            while (true) {
                while (set[++i] < pivot) { }
                while ((j > left) && (set[--j] > pivot)) { }
                if (i < j) {
                    if (printSteps) {
                        System.out.println("Pair to swap: " + set[i] + ", "
                                + set[j]);
                    }
                    swap(set, i, set, j);
                } else {
                    break;
                }
            }

            if (printSteps) {
                System.out.println("Pair to swap: " + set[i] + ", "
                        + set[right]);
            }
            swap(set, i, set, right); // Restore pivot

            _quickSortA(set, left, i - 1, printSteps); // Sort small elements
            _quickSortA(set, i + 1, right, printSteps); // Sort large elements
        } else {
            insertionSort(set, left, right, false);
        }
    }

    public static double quickSortB(int[] set, boolean printSteps) {
        // Mark the start time.
        double startTime = System.currentTimeMillis();

        // Print the input set if we are asked to.
        if (printSteps) {
            System.out.println("QUICKSORT-B");
            System.out.println(printList(set));
        }

        // DO QUICKSORT-B HERE!
        // Print progress if printSteps is set to true.
        _quickSortB(set, 0, set.length - 1, printSteps);

        // Print the output set if we are asked to.
        if (printSteps) {
            System.out.println(printList(set));
            System.out.println("-=-=-=-=-=-=-=-");
        }

        // Mark the finish time and return the time it took to sort.
        return System.currentTimeMillis() - startTime;
    }

    private static void _quickSortB(int[] set, int left, int right,
            boolean printSteps) {
        if (printSteps) {
            System.out.println("List: " + printList(set));
        }

        if (left + CUTOFF <= right) {
            // median3 implicitly places pivot at position right-1
            int pivot = median3(set, left, right);
            if (printSteps) {
                System.out.println("Pivot: " + pivot);
            }

            // begin partitioning
            int i = left;
            int j = right - 1;

            while (true) {
                while (set[++i] < pivot) { }
                while (set[--j] > pivot) { }
                if (i < j) {
                    if (printSteps) {
                        System.out.println("Pair to swap: " + set[i] + ", "
                                + set[j]);
                    }
                    swap(set, i, set, j);
                } else {
                    break;
                }
            }

            if (printSteps) {
                System.out.println("Pair to swap: " + set[i] + ", "
                        + set[right - 1]);
            }
            swap(set, i, set, right - 1); // restore pivot

            _quickSortB(set, left, i - 1, printSteps);
            _quickSortB(set, i + 1, right, printSteps);
        } else {
            insertionSort(set, left, right, false);
        }
    }

    public static double quickSortC(int[] set, boolean printSteps) {
        // Mark the start time.
        double startTime = System.currentTimeMillis();

        // Print the input set if we are asked to.
        if (printSteps) {
            System.out.println("QUICKSORT-C");
            System.out.println(printList(set));
        }

        // DO QUICKSORT-C HERE!
        // Print progress if printSteps is set to true.
        _quickSortC(set, 0, set.length - 1, printSteps);

        // Print the output set if we are asked to.
        if (printSteps) {
            System.out.println(printList(set));
            System.out.println("-=-=-=-=-=-=-=-");
        }

        // Mark the finish time and return the time it took to sort.
        return System.currentTimeMillis() - startTime;
    }

    private static void _quickSortC(int[] set, int left, int right,
            boolean printSteps) {
        if (printSteps) {
            System.out.println("List: " + printList(set));
        }

        if (left + CUTOFF <= right) {
            // median5 implicitly places pivot at position right-1
            int pivot = median5(set, left, right);
            if (printSteps) {
                System.out.println("Pivot: " + pivot);
            }

            // begin partitioning
            int i = left;
            int j = right - 1;

            while (true) {
                while (set[++i] < pivot) { }
                while (set[--j] > pivot) { }
                if (i < j) {
                    if (printSteps) {
                        System.out.println("Pair to swap: " + set[i] + ", "
                                + set[j]);
                    }
                    swap(set, i, set, j);
                } else {
                    break;
                }
            }

            if (printSteps) {
                System.out.println("Pair to swap: " + set[i] + ", "
                        + set[right - 1]);
            }
            swap(set, i, set, right - 1); // restore pivot

            _quickSortC(set, left, i - 1, printSteps);
            _quickSortC(set, i + 1, right, printSteps);
        } else {
            insertionSort(set, left, right, false);
        }
    }

    public static double quickSortD(int[] set, boolean printSteps) {
        // Mark the start time.
        double startTime = System.currentTimeMillis();

        // Print the input set if we are asked to.
        if (printSteps) {
            System.out.println("QUICKSORT-D");
            System.out.println(printList(set));
        }

        // DO QUICKSORT-D HERE!
        // Print progress if printSteps is set to true.
        _quickSortD(set, 0, set.length - 1, printSteps);

        // Print the output set if we are asked to.
        if (printSteps) {
            System.out.println(printList(set));
            System.out.println("-=-=-=-=-=-=-=-");
        }

        // Mark the finish time and return the time it took to sort.
        return System.currentTimeMillis() - startTime;
    }

    private static void _quickSortD(int[] set, int left, int right,
            boolean printSteps) {
        if (printSteps) {
            System.out.println("List: " + printList(set));
        }

        if (left + CUTOFF <= right) {
            // use quick select to find the actual median as pivot
            // the pivot is placed at position center
            int pivot = quickSelectMedian(set, left, right, printSteps);
            if (printSteps) {
                System.out.println("Pivot: " + pivot);
            }

            // place pivot at position right
            int center = left + (right - left) / 2;
            set[center] = set[right];
            set[right] = pivot;

            // Begin partitioning
            int i = left - 1;
            int j = right;
            while (true) {
                while (set[++i] < pivot) { }
                while ((j > left) && (set[--j] > pivot)) { }
                if (i < j) {
                    if (printSteps) {
                        System.out.println("Pair to swap: " + set[i] + ", "
                                + set[j]);
                    }
                    swap(set, i, set, j);
                } else {
                    break;
                }
            }

            if (printSteps) {
                System.out.println("Pair to swap: " + set[i] + ", "
                        + set[right]);
            }
            swap(set, i, set, right); // Restore pivot

            _quickSortD(set, left, i - 1, printSteps); // Sort small elements
            _quickSortD(set, i + 1, right, printSteps); // Sort large elements
        } else {
            insertionSort(set, left, right, false);
        }
    }

    private static int median3(int[] set, int left, int right) {
        int center = (left + right) / 2;

        // sort the subarray of left-center-right
        if (set[center] < set[left]) {
            swap(set, left, set, center);
        }
        if (set[right] < set[left]) {
            swap(set, left, set, right);
        }
        if (set[right] < set[center]) {
            swap(set, center, set, right);
        }

        // place pivot at position right-1
        swap(set, center, set, right - 1);
        return set[right - 1];
    }

    // a hack to reduce memory allocation time
    private static int[] _tempArrayForMedian5 = new int[5];

    private static int median5(int[] set, int left, int right) {
        int center = (left + right) / 2;
        int leftCenter = (left + center) / 2;
        int rightCenter = (center + right) / 2;

        // sort the subarray of
        // left-leftCenter-center-rightCenter-rightCenter
        _tempArrayForMedian5[0] = set[left];
        _tempArrayForMedian5[1] = set[leftCenter];
        _tempArrayForMedian5[2] = set[center];
        _tempArrayForMedian5[3] = set[rightCenter];
        _tempArrayForMedian5[4] = set[right];
        insertionSort(_tempArrayForMedian5, false);

        // copy the sort results back to the input array
        // and place the pivot at position right-1
        set[left] = _tempArrayForMedian5[0];
        set[leftCenter] = _tempArrayForMedian5[1];
        set[center] = set[right - 1];
        set[right - 1] = _tempArrayForMedian5[2];
        set[rightCenter] = _tempArrayForMedian5[3];
        set[right] = _tempArrayForMedian5[4];

        return set[right - 1];
    }

    public static int quickSelectMedian(int[] set, int left, int right,
            boolean printSteps) {
        int k = (right - left) / 2 + 1; // expected median's index as k
        quickSelect(set, left, right, k, printSteps);
        return set[left + k - 1];
    }

    /**
     * Internal selection method that makes recursive calls. Uses
     * median-of-three partitioning and a cutoff of 10. Places the kth smallest
     * item in set[k-1]. NOTE: This method will modify the input array's order.
     * 
     * @param set
     *            the input array of int.
     * @param left
     *            the left-most index of the subarray.
     * @param right
     *            the right-most index of the subarray.
     * @param k
     *            the desired rank (1 is minimum) in the entire array.
     */
    private static void quickSelect(int[] set, int left, int right, int k,
            boolean printSteps) {
        if (left + CUTOFF <= right) {
            int pivot = median3(set, left, right);

            // begin partitioning
            int i = left;
            int j = right - 1;
            while (true) {
                while (set[++i] < pivot) { }
                while (set[--j] > pivot) { }
                if (i < j) {
                    if (printSteps) {
                        System.out.println("Pair to swap: " + set[i] + ", "
                                + set[j]);
                    }
                    swap(set, i, set, j);
                } else {
                    break;
                }
            }

            if (printSteps) {
                System.out.println("Pair to swap: " + set[i] + ", "
                        + set[right - 1]);
            }
            swap(set, i, set, right - 1); // restore pivot

            if (k - 1 < i) {
                quickSelect(set, left, i - 1, k, printSteps);
            } else if (k - 1 > i) {
                quickSelect(set, i + 1, right, k, printSteps);
            }
        } else {
            // do an insertion sort on the subarray
            insertionSort(set, left, right, false);
        }
    }

    /**
     * Return a rendering of a list as a StringBuffer. You can pass the buffer
     * to a System.out.println() to actually print the set.
     */
    private static StringBuffer printList(int[] set) {
        return printList(set, 0, set.length);
    }

    private static StringBuffer printList(int[] set, int beginIdx, int length) {
        StringBuffer result = new StringBuffer();

        for (int i = 0; i < length; i++) {
            result.append(set[beginIdx++]);

            // Add spaces between elements
            if (i < (length - 1)) {
                result.append(" ");
            }
        }

        return result;
    }

    private static final void swap(int[] src, int srcIdx, int[] dst, int dstIdx) {
        int temp = src[srcIdx];
        src[srcIdx] = dst[dstIdx];
        dst[dstIdx] = temp;
    }
}


AutomateSortComparisonReport.java: see attached file.

Uses JFreeChart 1.0.1 for charting. Visit http://www.jfree.org/jfreechart/ for more information on JFreeChart.

Sample plot graphs of this project can be found here: http://rednaxelafx.iteye.com/blog/174063
分享到:
评论
1 楼 beyondqinghua 2008-03-25  
有时间慢慢看,收藏先!

相关推荐

    关于几种排序算法的比较分析

    关于数据的几种排序算法的程序对比分析,结合具体案例

    c语言实现的各种排序算法效率分析与比较及源代码

    各种排序算法效率分析比较及源代码 C语言实现 各种排序包括: 直接插入排序,折半插入排序,2—路插入排序和表插入排序;希尔排序和链式基数排序;起泡排序,快速排序,归并排序;简单选择排序,树形选择排序和堆...

    排序算法及效率

    在排序中使用到的几种算法及效率对比

    【排序算法】几种经典排序算法的python实现

    冒泡排序法通常作为时间效率较差的排序法,作为其他算法的对比基准,其效率差在每个数据项在找到其最终位置前必须经过多次无效的交换。 优势是无需任何额外的存储空间开销,在源列表的空间内进行。 冒泡排序法优化 ...

    基于Java的不同排序算法的实现及其性能比较

    基于java语言,通过实验,详细对比了几种常见的排序算法的性能

    一种基于用户标记的搜索结果排序算法

    随着计算机网络的快速发展,...然后提出了一种基于用户反馈的语义标记的新方法,最后采用多种评估方法与Google搜索结果进行对比分析。实验结果表明,利用本文的方法所得到的排序结果比Google的排序结果更接近用户需求。

    数据结构讲义(严蔚敏版)(含算法源码)

    数据结构讲义(严蔚敏版)(含算法源码) 1. 经典算法 单链表:遍历、插入、删除 循环队列:队列空、队列满的条件 二叉树:递归遍历及应用 有序表的二分法查找 快速排序 ...各种排序算法的对比结论(O)

    基于层次分析法的MD0算法性能评价 (2007年)

    通过对几种常见MDO算法的设计变量、约束、计算精度和计算复杂度进行分析,给出了改良的序列二次规划算法(NLPQL)、自适应模拟退火算法(ASA)、多岛遗传算法(MIGA)和序列二次规划算法(DONLP)在涡轮叶片多学科优化中选择...

    程序员为什么还要刷题-tw101-reading:Lisa和Betsy的技术写作研讨会的预读

    程序员常刷题这是技术写作 101课程的预读,让您快速了解一些基本的技术写作概念。...会自动在十几种排序算法中进行选择,而 Foobar 只能在两种算法之间切换。 读者喜欢包含示例的定义,例如: 例如,Carambola Serve

    计算机二级C语言考试题预测

    (54) 在下列几种排序方法中,要求内存量最大的是(D) 注:要牢记,书中没有提到。 A. 插入排序 B. 选择排序 C. 快速排序 D. 归并排序 (55) 在设计程序时,应采纳的原则之一是(A) 注:和设计风格有关 A. 程序结构应有...

    C语言进阶-牟海军.pdf

    第11章则对所有程序员必须掌握的几种算法进行了详细的讲解;附录经验性地总结了如何养成良好的编码习惯,这对所有开发者都尤为重要。 本书主要内容:  堆和栈、全局变量和局部变量、生存期和作用域、内部函数和...

    C语言进阶 作者 Wrestle.Wu

    第11章则对所有程序员必须掌握的几种算法进行了详细的讲解;附录经验性地总结了如何养成良好的编码习惯,这对所有开发者都尤为重要。 本书主要内容:  堆和栈、全局变量和局部变量、生存期和作用域、内部函数和...

    传智播客扫地僧视频讲义源码

    06_学员学习标准_排序及问题抛出 07_数组做函数参数退化问题剖析_传智扫地僧 08_数据类型基础提高 09_数据类型引申和思考 10_变量本质剖析和内存四区模型引出_传智扫地僧 11_c的学习重理解到位_对初学者_传智扫地僧 ...

    java面试题,180多页,绝对良心制作,欢迎点评,涵盖各种知识点,排版优美,阅读舒心

    【基础】Java 中定义常量的几种方法 25 【基础】什么时候使用字节流?什么时候用字符流? 26 【基础】GBK与UTF-8的区别 26 【基础】static、final、const的区别 26 final: 26 static: 27 【基础】如何实现对象克隆?...

    优考试 v3.3.2官方版.zip

    优考试通过对考试数据进行统计分析,诸如考试分数分布,考试用时分布,错排行等,让你从整体上了解你的学员(员工)状态, 同时你也可以对学员(员工)一段时间的考试进行对比, 让你发现他的变化,并适当的进行指导...

    城市CBD地区公交动态查询及行人诱导系统设计 (2011年)

    首先分析城市CBD地区的公交客流特征以及公交出行人群对信息的基本需求,对比当前国内几种主流公交查询软件存在的缺陷,提出了公交动态查询及行人诱导系统的总体功能与框架,并改良了影响乘车方案排序的核心算法,...

    网络互连_网桥.路由器.交换机和互连协议

    第10章谈到在网络层报头中应出现的信息及几种协议报头的对比。第11章涉及自动配置和近邻发现,包括ARP和DHCP协议。第12章是一般的路由选择算法。第13章讨论最长前缀匹配问题,这在快速转发IP包时需要。第14章讨论...

    红图新媒体教你如何学习新媒体

    1、新媒体管家 ...  内设“通用节日”...还可以添加对比词(最多可添加4个),更直观的对比几个词的微信指数。  热点每分钟都发生,独到的见解却万一挑一。我们要利用热点为自己的想法加码,而不是被热点“绑架”。

    汪文君高并发编程实战视频资源全集

     高并发编程第三阶段12讲 sun.misc.Unsafe介绍以及几种Counter方案性能对比.mp4  高并发编程第三阶段13讲 一个JNI程序的编写,通过Java去调用C,C++程序.mp4  高并发编程第三阶段14讲 Unsafe中的方法使用,一半是...

    汪文君高并发编程实战视频资源下载.txt

     高并发编程第三阶段12讲 sun.misc.Unsafe介绍以及几种Counter方案性能对比.mp4  高并发编程第三阶段13讲 一个JNI程序的编写,通过Java去调用C,C++程序.mp4  高并发编程第三阶段14讲 Unsafe中的方法使用,一半是...

Global site tag (gtag.js) - Google Analytics