1. Introduction
Quicksort is an improvement on bubble sort.
Rapid sorting was proposed by C.A.R.Hoare in 1962.
Its basic idea is to divide the data to be sorted into two independent parts through one-time sorting. All the data in one part is smaller than all the data in the other part, and then quickly sort the two parts of data according to this method. The whole sorting process can be recursive to turn the whole data into an ordered sequence at one time.
2. Algorithm principle
Let the array to be sorted be A[0],A[1]... A[n-1]. First take any data (usually the first of the array) as the key data, and then put all smaller numbers in front of it and all larger numbers behind it. The whole process is called a quick sort.
It is worth noting that quick sorting is not a stable sorting algorithm, that is, the relative positions of multiple identical values may change at the end of the algorithm.
The quick sort algorithm is:
-
Set two variables left and right to indicate the index of array elements. At the beginning of sorting: left=0, right=n-1
-
Take the first element as the key data and assign it to key, that is, key=A[0]
-
Start the forward search from right, that is, start the forward search from the back (right –), find the first value A[right] less than the key, and exchange A[right] and A[left].
-
Search backward from left, that is, search backward from front (left + +), find the first A[left] greater than key, and exchange A[left] and A[right];
-
Repeat steps 3 and 4 until left=right. Note that the judgment and search are carried out at the same time, that is, judge every time you change left and right.
3. Sorting demonstration
Suppose the user enters the following array:
Create variables left = 0 (pointing to the first data), right = 5 (pointing to the last data), k=6 (assigned as the value of the first data).
To move all numbers smaller than k to the left of K, start looking for numbers smaller than 6, start from right, look from right to left, continuously decrease the value of variable right, find that the data of the first index 3 is smaller than 6, move data 3 to the position of subscript 0, move data 6 with index 0 to the position of subscript 3, and complete the first comparison. The results are as follows:
At this time, left = 0, right = 3, k = 6
Start the second comparison, this time from the left. Increment the variable left and find that the data of index 2 is larger than k, so exchange the data 7 of index 2 with the data 6 of subscript 3 pointed to by right. The results are as follows:
At this time, left=2, right=3, k=6
Call the above two comparisons a cycle.
Then, decrease the variable right and repeat the above cyclic comparison.
In this case, after a loop, you find that left and right meet: they both point to subscript 2. So the first comparison is over. All the numbers on the left of k(=6) are smaller than it, and all the numbers on the right are larger than it.
If left and right don't meet, increase left to find the big one. If not, increase right to find the small one. Repeat and cycle. Pay attention that judgment and search are carried out at the same time. Then, the data on both sides of k are grouped and the above process is carried out respectively until it can not be divided again.
Note: the first pass of quick sort will not directly get the final result, but will only divide the numbers larger than K and smaller than k to both sides of K.
python code implementation
Implement the above process
#!/usr/bin/python # -*- coding: utf-8 -*- l = [6, 2, 7, 3, 8, 9] left = 0 right = 5 key = l[0] # Find the value smaller than key from the right, and then exchange it with l[key] while left < right and l[right] >= key: right -= 1 l[right], l[left] = l[left], l[right] print('First right to left swap:') print('left=%s' % left, 'right=%s' % right) print(l) # Find a value larger than key from the left and exchange it with l[right] while left < right and l[left] < key: left += 1 l[left], l[right] = l[right], l[left] print('First left to right swap:') print('left=%s' % left, 'right=%s' % right) print(l)
Operation results:
First right to left swap: ('left=0', 'right=3') [3, 2, 7, 6, 8, 9] First left to right swap: ('left=2', 'right=3') [3, 2, 6, 7, 8, 9]
Because we know the sequence, we need to summarize the above code to adapt to any sequence. The summarized code is as follows:
def f(l): left = 0 right = len(l) - 1 key = l[0] while left < right: while left < right and l[right] >= key: # Compare right to left right -= 1 l[right], l[left] = l[left], l[right] while left < right and l[left] < key: # Compare left to right left += 1 l[left], l[right] = l[right], l[left] l = [6, 2, 7, 3, 8, 9] f(l) print(l)
Execution results:
[3, 2, 6, 7, 8, 9]
In this way, we realize the function of passing in an arbitrary sequence for quick sorting. Let's continue to summarize. What if we only want to quickly sort a part of a sequence?
In this way, we need to specify the interval of the sequence, so we modify the above function as follows:
def f(l, left=None, right=None): if left is None: left = 0 if right is None: right = len(l) - 1 key = l[left] while left < right: while left < right and l[right] >= key: # Compare right to left right -= 1 l[right], l[left] = l[left], l[right] while left < right and l[left] < key: # Compare left to right left += 1 l[left], l[right] = l[right], l[left] l = [6, 2, 7, 3, 8, 9] print(l) f(l, 0, 4) print(l)
Execution results:
[6, 2, 7, 3, 8, 9] [3, 2, 6, 7, 8, 9]
We realize the quick sorting of any interval of any sequence. Then we can solve the problem by recursion according to the idea of quick sorting. The code is as follows:
def f(l, left=None, right=None): if left is None: left = 0 if right is None: right = len(l) - 1 if right > left: # Conditions for the end of recursion index_l = left index_r = right key = l[left] while left < right: while left < right and l[right] >= key: # Compare right to left right -= 1 l[right], l[left] = l[left], l[right] while left < right and l[left] < key: # Compare left to right left += 1 l[left], l[right] = l[right], l[left] # recursion f(l, left=index_l, right=left-1) # The left half f(l, left=left+1, right=index_r) # Half on the right l = [54, 50, 43, 68, 9, 74, 91, 69, 42, 49, 18, 50, 31, 99, 79, 92, 50, 43, 46, 10, 74, 75, 13, 32, 10, 54, 32, 12, 42, 6, 20, 75, 99, 26, 48, 82, 1, 68, 15, 97, 22, 35, 8, 90, 45, 100, 20, 18, 81, 81, 69, 37, 26, 85, 69, 78, 84, 95, 42, 0, 56, 53, 20, 29, 35, 82, 86, 81, 43, 33, 44, 28, 25, 69, 45, 8, 12, 85, 87, 84, 56, 75, 12, 59, 76, 31, 62, 54, 67, 31, 71, 40, 42, 88, 100, 44, 88, 9, 36, 22] f(l) print(l)
Execution results:
[0, 1, 6, 8, 8, 9, 9, 10, 10, 12, 12, 12, 13, 15, 18, 18, 20, 20, 20, 22, 22, 25, 26, 26, 28, 29, 31, 31, 31, 32, 32, 33, 35, 35, 36, 37, 40, 42, 42, 42, 42, 43, 43, 43, 44, 44, 45, 45, 46, 48, 49, 50, 50, 50, 53, 54, 54, 54, 56, 56, 59, 62, 67, 68, 68, 69, 69, 69, 69, 71, 74, 74, 75, 75, 75, 76, 78, 79, 81, 81, 81, 82, 82, 84, 84, 85, 85, 86, 87, 88, 88, 90, 91, 92, 95, 97, 99, 99, 100, 100]
Regardless of space complexity, the code can be simplified as follows:
def quick_sort(l): if len(l) >= 2: # Recursive end condition k = l[0] # Select k value left, right = [], [] # Defines the list on the left and right sides of the reference value l.remove(k) # Remove base element for item in l: if item < k: left.append(item) else: right.append(item) return quick_sort(left) + [k] +quick_sort(right) else: return l
One line of code can realize:
f = lambda l:l if len(l)<1 else f([x for x in l[1:] if x >= l[0]]) + [l[0]] + f([x for x in l[1:] if x < l[0]])
Finally, the following is a knowledge architecture diagram of the development direction of software test engineers.
I hope you can benefit a lot from this growth process. It can be said that this process will make you miserable, but as long as you get through it. Life will be much easier in the future. As the saying goes, everything is difficult at the beginning. As long as you take the first step, you will have achieved half of your success. The ancients said that "no small step, no even a thousand miles." When you look back on this journey after completion, you will certainly feel a lot.
Due to the limited size of CSDN uploaded pictures, friends in need can pay attention to my official account: programmers two black, reply 1, you can get the original picture.
The following is a supporting software testing resource package:
The above are some supporting resources, which should be the most comprehensive and complete war preparation warehouse for friends of software testing. In order to better sort out each module, I also refer to many high-quality online blogs and projects, and strive not to miss every knowledge point. Many friends reviewed these contents and got offer s from BATJ and other major manufacturers, This warehouse has also helped many learners of software testing. I hope it can also help you.
Pay attention to my WeChat official account: programmers two black, free access!
The most difficult time is when we are not far from success! If you don't want to experience the feeling of giving up after a few days when you can't find materials and no one answers questions, you can join our group: 785128166. Let's discuss and exchange learning together.
Recommended reading
Byte jump software test post, the first two sides passed, and the third HR sinkhole! Told me