Learning Quick Sort in C#

I read a sentence recently. It said that in real life, people who can write may not necessarily write good articles. Learning a programming language is like learning to write. Learning a programming language may not necessarily lead to good programs.

I think it makes sense. In the past, when I was studying, I basically finished the grammar knowledge in C#, which is considered to be a door, but when I write a program, I have no clue. Some simple APIs cobble together functions without any logic or beauty.

So I decided to slowly start learning algorithm knowledge. Although my math is bad and my logic ability is extremely poor, I have an explosion in my mind when I look at the code of these algorithms, and my scalp is really numb. slowly progressed.

 

Quick sort is a common sorting algorithm in the divide and conquer method, which mainly uses recursion to solve.

The idea of ​​the algorithm is to divide an array into sub-arrays that are less than or equal to the reference number and sub-arrays that are greater than the reference number, and then recursively call the two sub-arrays until there are only 0 or 1 elements in the array, and stop. Recursively, adding up the sorted subarrays, and finally getting the sorted array.

 

Proceed as follows:

1. Choose a base value

2. Divide the array into two subarrays: elements smaller than the base value and elements larger than the base value

3. Sort the two subarrays

 

Then repeat the above 3 steps for the sub-array until the sub-array cannot be decomposed (when the sub-array has only 0 or 1 element)

 

The above process can be repeated using function recursion, 2 conditions must be met in the recursive function

1. Baseline condition - means that after a certain condition is met, the function does not call itself for recursion

2. Recursive condition - call its own function to recurse when the recursive condition is met

 

The example of the book I read is a quick sort implemented using Python code, the code is as follows:

1  def quicksort(array):
 2      if len(array) < 2: #baseline condition: empty or an array with only one element is "sorted" 
3          return array 
 4      else : #recursive condition 
5          pivot = array[0 ] 
 6          less = [i for i in array[1:] if i<= pivot] #array consisting of all elements less than or equal to the reference value 
7          greater = [i for i in array[1:] if i> pivot] #subarray 8 consisting of all elements greater than the pivot value 
return quicksort(less) + [pivot] +          quicksort(greater)
 9 
10 
11 print(quicksort([10, 5, 2, 3]))

 

In this code, when the recursive condition is first met, a reference number is obtained, which is usually the first element of the array, and then divided into two sub-arrays, one is a sub-array less than or equal to the reference number and a sub-array greater than the reference number , keep recursive calls to sort the two subarrays, and finally get the sorted array.

After reading the explanation in the book, I have thoughts in my mind very quickly, but when I want to convert the above code into C#, I can't figure it out, and I can't stand it, because it can't be like the above in C# It is simple to implement, the most important thing is that arrays in C# cannot be merged by direct addition.

 

So after reading a lot of detailed explanations of C# quick sort on the Internet, I wrote the following code:

1          ///  <summary> 
2          /// Quicksort sorts the array in ascending order
 3          ///  </summary> 
4          ///  <param name="array">array to be sorted </param> 
5          ///  <param name="leftIndex"> The index of the first number traversed from the left </param> 
6          ///  <param name="rightIndex"> The index of the first number traversed from the right </param> 
7          public  static  void QuickSort( int [] array, int leftIndex, int rightIndex)
 8          {
 9              if (leftIndex >= rightIndex) // baseline condition
10                 return;
11             int n = leftIndex;
12             int m = rightIndex;
13             int pivot = array[leftIndex];
14             while (n != m)
15             {
16                 for (; n < m; m--)
17                 {
18                     if (array[m] < pivot)
19                     {
20                         array[n] = array[m];//交换位置
21                         break;
22                     }
23                 }
 24                  for (; n < m; n++ )
 25                  {
 26                      if (array[n] > pivot)
 27                      {
 28                          array[m] = array[n];
 29                          break ;
 30                      }
 31                  }
 32              }
 33              array[n] = pivot; // After the loop is completed, it has been sorted according to the number less than the benchmark number and the number greater than the benchmark number, and the benchmark number is placed in the middle. 
34              QuickSort(array, leftIndex, n - 1 ); // recurse on two subarrays 
35             QuickSort(array, n + 1, rightIndex);
36         }

 

The idea of ​​online quicksort is as above, and even the baseline conditions are completely different from what I saw in the book, and the logic in the book is not the same, but it is still a divide-and-conquer method to solve the problem.

It is not only to separate two sub-arrays, but to sort the current array, and the sorting process is not easy to understand. Cycle from right to left to find the number larger than the reference number, and then cycle from left to right to find the number larger than the reference number. Count the small numbers, and then swap the two numbers. When there is only one number left at the end, it is the position where the reference number should be, and put the reference number in this position.

So I thought about it for 2 days before I was able to write the above quick sort code independently, but I don't know if I really understood the idea of ​​sorting, or if I had read the sorting method for too long. It's really sad to have it in my head. A smart little friend can learn it at once, but I thought about it for two days and I didn't even know if I wanted to understand it.

 

Finally, I still have a question, the time complexity of quicksort is O(nlogn), so is the above Python code still O(nlogn)?

Newly declare arrays, then assign them, and then merge, will this operation affect the time complexity?

even i want to use linq syntax

1             int[] less = (from i in array where i < pivot select i).ToArray();
2             int[] greater = (from i in array where i > pivot select i).ToArray();

The returned array is even sorted, so wouldn't it be simpler if I just added the two arrays and the base number? I'm completely confused, I don't know how the time complexity is calculated, the long way to learn is really long!

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325149465&siteId=291194637