Sort: bubble sort vs Quick Sort, bubble sort
In the process of development, we often encounter set sorting. In general, we use list. the OrderBy () method does not need to be concerned with the implementation of the algorithm. in the past few days, I am going to review the data structure and algorithms.
First, let's take a look at the following sorting types:
Exchange sorting: Includes Bubble sorting and quick sorting.
Select sorting: includes directly selecting sorting and heap sorting.
Insert sorting: including direct insert sorting and Hill sorting.
Merge Sorting: Merge Sorting.
List. OrderBy () adopts the fast sorting method. Since Bubble Sorting is the same as it, we will compare it to see which sort is better.
I. Example (first look at the results and then talk about ideas)
Static void Test () {// compare for (int I = 1; I <= 5; I ++) {List <int> list = new List <int> (); // insert 2 k random numbers to the array for (int j = 0; j <2000; j ++) {Thread. sleep (3); list. add (new Random (int) DateTime. now. ticks ). next (0, 100000);} Console. writeLine ("\ n" + I + "Times comparison: {0 }... ", string. join (",", list. take (10); Stopwatch watch = new Stopwatch (); watch. start (); var result = list. orderBy (single => single ). toList (); Watch. stop (); Console. writeLine ("\ n fast sorting time-consuming:" + watch. elapsedMilliseconds); Console. writeLine ("Top 10 output:" + string. join (",", result. take (10 ). toList (); watch. start (); result = BubbleSort (list); watch. stop (); Console. writeLine ("\ n Bubble Sorting time-consuming:" + watch. elapsedMilliseconds); Console. writeLine ("Top 10 output:" + string. join (",", result. take (10 ). toList (); }}// static List of Bubble sorting algorithms <int> BubbleSort (List <int> lis T) {int temp; int count = list. count; // The first loop: indicates the number of times to be compared, such as list. count. You must compare count-1 times for (int I = 0; I <count-1; I ++) {// list. count-1: Take the last number subscript of the data, // j> I: The subscript from the back to the back must be greater than the subscript from the back to the back, otherwise it will surpass. For (int j = count-1; j> I; j --) {// if the previous number is greater than the next number, the switch if (list [j-1]> list [j]) {temp = list [j-1]; list [j-1] = list [j]; list [j] = temp ;}} return list ;}
This code is taken from the reference link. I am very lazy, and the Bubble Sorting Algorithm is still very simple, so I won't write it myself.
From the above results, quick sorting is faster than Bubble sorting.
After seeing the magic, let's take a deeper look at the ideas and implementations of algorithms.
Ii. Thoughts and Implementations
1. Bubble Sorting
First, let's explain how to take a bubble. In the water, let's breathe a breath and form a bubble. This bubble will gradually increase during the Rising process (caused by a smaller water pressure ). finally, the exposed face is broken.
In connection with this idea, we can think that the Bubble Sorting should be to let a large number gradually go up until it reaches the top of the number bigger than it, breaking down.
According to this idea, there is a process formed in my mind. Let's take a look at the Code: (the figure below is pretty good, so I stole it)
// Bubble Sorting Algorithm static List <int> BubbleSort1 (List <int> list) {int temp; int count = list. count; for (int I = 0; I <count-1; I ++) {for (int j = 1; j <count; j ++) {// if the previous number is greater than the next number, the switch if (list [j-1]> list [j]) {temp = list [j-1]; list [j-1] = list [j]; list [j] = temp ;}} return list ;}
First, I can determine the position of a number for each loop. How many cycles do I need? The last number does not need to be retained or compared with him. So we can just loop through n-1 times.
Next, every loop here is actually a bubble process. compare the start number with the next digit. If the number is greater than the next digit, move it to the next digit. (In fact, this is quite troublesome. Why should I move it once? Can't I find his position to switch between them? At least the change operation is reduced)
The code here is slightly different from the above example. Pay attention to it.
Let's take a look at the time complexity here, although the outside only loops n-1 times, it only loops the n-3 times, seemingly complexity is (n-1) * (n-3), but if n is big enough, -1,-3, and even-100 have little influence on the final result.
According to the worst case, the time complexity of the bubble sort here, the limit is O (n2). Is there an ideal situation? It seems that no. Even if this array has already been sorted, it seems that the program is still going to start from the beginning to the end, nothing is missing. so the average complexity here is also O (n2 ). in this case, Bubble Sorting is not an ideal sorting method.
If you cannot provide a better sorting method, you can use the List. OrderBy method to sort it.
2. Quick sorting
The quick sorting algorithm is also called the divide and conquer method. The steps can be roughly divided into the following steps:
1. First, extract a number from the sequence as the reference number Num (if it is obtained, the steps can be reduced)
2. Partition: place the number greater than Num on the right of the partition, And the number smaller than or equal to Num on the left of the partition.
3. Repeat the first two operations on the left and right intervals until each interval has only one number.
The above text may not quite understand this process, so I will use an image to describe this process.
After a round of comparison, we always feel that recursion is required here. If recursion is involved, its spatial complexity may be a little higher than that of Bubble sorting.
Now that the process is clear, write a round of code first.
static int Division(List<int> list, int left, int right){ int baseNum = list[left]; while (left < right) { while (left < right && list[right] > baseNum) { right -= 1; } list[left] = list[right];while (left < right && list[left] <= baseNum) { left += 1; } list[right] = list[left]; } list[left] = baseNum; return left;}
Both Left + = 1 and Right-= 1 have the following prerequisites: Left <Right
The next step is relatively simple. For a recursive call, the idea of recursion is very simple:
static void QuickSort(List<int> list, int left, int right){ if (left < right) { int i = Division(list, left, right); QuickSort(list, left, i - 1); QuickSort(list, i + 1, right); }}
Complexity of fast sorting:
In the worst case, the complexity is: O (n2)
In the optimal condition, the complexity is O (nlog2n)
The computation and proof of its complexity are not provided by me, but are provided by reference.
In the worst case, the time complexity of quick sorting is the same as that of Bubble sorting, but in the best case, Bubble Sorting is n * n, and fast sorting is n * log2n,
If n = 16,
The bubble value is 16*16.
Fast sorting is 16*4
It can be seen that as long as you are not back to the home, it is faster than the bubble.
Refer:
Algorithm series: 15 days-the first day of the seven classical sorting [Top]
Proof that the time complexity of quick sorting is O (n × log (n)