一、步骤
快速排序的基本思想:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。
1.首先,先确定一个元素作为关键值赋值到变量keyi中(keyi保存的是该元素的坐标,即数组的下标)
2.其次,用变量left保存数组的左边左边,right保存数组的右边坐标
3.然后right先向左边开始走,直到找到小于keyi的元素停止
4.right停止后,left开始向右侧找,找到大于keyi的元素停止
5.将left和right位置的元素互换,然后重复3、4步
6.直到left和right相遇后,将left赋值给keyi。到此keyi左侧的元素全部小于keyi处的元素,右侧的元素全部大于keyi处的元素,整个数组便成为[left,keyi-1]keyi[keyi+1,right],这样就确定了一个元素的位置
快速排序有三种方法:hoare版本、挖坑法和前后指针版本
初始数组:
1.hoare版本
图片详解:
2.挖坑法
3.前后指针版本
图片详解:
这里的keyi保存的是关键值的坐标
二、代码
1.hoare版本
int PartSort1(int* arr, int left, int right)
{
int keyi = left; //keyi不可以赋值为0,因为传过来的数组left不一定是0
while (left < right)
{
while (left < right && arr[right] >= arr[keyi]) //右边找小,找到小于keyi的停止
{
right--;
}
while (left < right && arr[left] <= arr[keyi]) //左边找大,找到大于keyi的停止
{
left++;
}
Swap(&arr[left], &arr[right]);
}
Swap(&arr[left], &arr[keyi]);//此时left == right
keyi = left;
return keyi;
}
//[begin,end]
void QuickSort(int* arr, int left, int right)
{
if (left >= right) // 1.当数组中只剩一个元素时返回,不需要排序
{ // 2.当数组不存在时返回,即left > right
return;
}
int keyi = PartSort1(arr, left, right);//[left,keyi,right]
QuickSort(arr, left, keyi - 1); //[left,kryi-1]keyi[keyi+1,right]
QuickSort(arr, keyi + 1, right);
}
2.挖坑法
int PartSort2(int* arr, int left, int right)
{
int key = arr[left];
while (left < right)
{
while (left < right && arr[right] >= key)
{
right--;
}
arr[left] = arr[right];
while (left < right && arr[left] <= key)
{
left++;
}
arr[right] = arr[left];
}
arr[left] = key;
return left;
}
//[begin,end]
void QuickSort(int* arr, int left, int right)
{
if (left >= right) // 1.当数组中只剩一个元素时返回,不需要排序
{ // 2.当数组不存在时返回,即left > right
return;
}
int keyi = PartSort2(arr, left, right);//[left,keyi,right]
QuickSort(arr, left, keyi - 1); //[left,kryi-1]keyi[keyi+1,right]
QuickSort(arr, keyi + 1, right);
}
3.前后指针版本
int PartSort3(int* arr, int left, int right)
{
int keyi = left;
int prev = left;
int cur = left + 1;
while (cur <= right)
{
if (arr[cur] < arr[keyi] && prev != cur)
{
++prev;
Swap(&arr[cur], &arr[prev]);
}
cur++;
}
Swap(&arr[prev], &arr[keyi]);
keyi = prev;
return keyi;
}
//[begin,end]
void QuickSort(int* arr, int left, int right)
{
if (left >= right) // 1.当数组中只剩一个元素时返回,不需要排序
{ // 2.当数组不存在时返回,即left > right
return;
}
int keyi = PartSort3(arr, left, right);//[left,keyi,right]
QuickSort(arr, left, keyi - 1); //[left,kryi-1]keyi[keyi+1,right]
QuickSort(arr, keyi + 1, right);
}