来源:
https://www.runoob.com/w3cnote/quick-sort-2.html
快速排序实现重点精华:
注意: 排序得到pivot位置之后,这个位置的值不再移动,所以在QuickSort中有
int pivot = Paritition1(A, low, high);
QuickSort(A, low, pivot - 1);
QuickSort(A, pivot + 1, high);
递归调用左区间为(low:pivot-1),右区间为(pivot+1:high)
并且,须知递归调用时使用if(low<high)
来控制的,意义为符合条件就递归,千万不能使用while,可能会无限递归调用。
还有就是在Paritition当中,应该使用while(low<high)
,表示有最少两个值的时候进行位置交换才有用。当只有一个值的时候,没有必要继续进行。
算法步骤
1.从数列中挑出一个元素,称为 “基准”(pivot);
2.重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
3.递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序; 代码:
#include <iostream>
//#include<time.h>
using namespace std;
int Paritition1(int A[], int low, int high) {
//***************1:上下对称结构,内外对称结构*************//
int pivot = A[low];
while (low < high) {
while (low < high && A[high] >= pivot) {
--high;
}
A[low] = A[high];//这里的A[high]的值一定是小于pivot,所以A[low]当中的值在赋值之后一定也是小于pivot
//因此,不用担心下面这行代码会不会运行,是一定运行,所以不会在同一个地址
//如果是同一个地址,那么就该返回了,返回中间值的地址
while (low < high && A[low] <= pivot) {
++low;
}
A[high]=A[low];
}
A[low] = pivot;
return low;
}
void QuickSort(int A[], int low, int high) //快排母函数
{
if (low < high) {
int pivot = Paritition1(A, low, high);
//***************2:左右对称结构******************//
QuickSort(A, low, pivot - 1);
QuickSort(A, pivot + 1, high);
}
}
int main()
{
int len = 8;
int aa[] = { 4,6,0,9,4,9,6,1};
//int* a = new int[len];
int* a = aa;
/*srand(time(NULL));
for (int i = 0; i < len; i++)
{
a[i] = 10 * rand() / RAND_MAX;
}*/
for (int i = 0; i < len; i++)
cout << ' ' << a[i];
cout << endl;
QuickSort(a, 0 ,len-1);
for (int i = 0; i < len; i++)
cout << ' ' << a[i];
return 0;
}
结果:
4 6 0 9 4 9 6 1
0 1 4 4 6 6 9 9
解释:
#include<vector>
#include<iostream>
using namespace std;
class Solution {
private:
int subSort(vector<int>& nums, int left, int right)
{
int pivot = nums[left];
while (left < right)
{
while (left<right && nums[right]>=pivot)
{
--right;
}
nums[left] = nums[right];//如果left==right,那么跳出上面的while循环,并且不影响排序;且,右边排序完成
//且,当left!=right的时候,直接将大于pivot的数值移动到右边nums[right]
while (left < right && nums[left] <= pivot)
{
++left;
}
nums[right] = nums[left];//如果left==right,那么跳出上面的while循环,并且不影响排序;且,左边排序完成
//且,当left!=righ的时候,直接将小于pivot的数值移动到左边nums[left]
}
nums[left] = pivot;
cout << "left=" << left << " right= " << right << endl;
return left;//这里传递回去left或者right都是一样的,由于排序结束left==right
}
public:
void quikSort(vector<int>& nums, int left, int right)
{
if (left < right)
{
int pivot = subSort(nums, left, right);
quikSort(nums, left, pivot - 1);
quikSort(nums, pivot + 1, right);
}
}
};
int main()
{
vector<int>nums{ 2,3,1,1,4,5,0,8,7,6 };
for (int n : nums)cout << n << " ";
cout << endl;
Solution kill;
kill.quikSort(nums, 0, nums.size() - 1);
for (int n : nums)cout << n << " ";
cout << endl;
return 0;
}
2 3 1 1 4 5 0 8 7 6
left=3 right= 3
left=0 right= 0
left=1 right= 1
left=5 right= 5
left=6 right= 6
left=9 right= 9
left=7 right= 7
0 1 1 2 3 4 5 6 7 8