快速排序的基本思想:任取待排序序列的一个元素作为中心元素(可以用第一个,最后一个,也可以是中间任何一个),习惯将其称为pivotkey,即枢轴元素。将所有比枢轴元素小的放在其左边,将所有比它大的放在其右边,形成左右两个子表,然后对左右两个子表再按照前面的算法进行排序(递归),直到每个子表的元素只剩下一个。
举例说明一下:
arr 为 [39 , 28 , 55 , 87 , 66 , 3 ,17 ,39*]为了区别两个相同元素,将最后一个加上 * 。
初始状态如下图:
定义一枢轴元素pivotkey,初始化为第一个元素的值,即39;
查询左边的元素的变量为left即low,初始值为第一个元素的索引,0;
查询右边的元素的变量为right即hight,初始值为第一个元素的索引,7。
如下图:
演示第一轮排序过程
从右边开始,从右边找到一个比枢轴元素小的,如果没找到right即high一直自减1;
然后把当前left即low所在元素赋值为该值;
这里right即hight所指元素并没有空,只是为了好演示,设置为空(下同);
然后从左边开始找一个比枢轴元素pivotkey大的元素;如果没找到left一直自增1;
将当前right所指元素设为该值;
然后从右边找到一个比枢轴元素小的,如果没找到right一直自减1;
将当前left所指元素设为该值;
然后从左边开始找一个比枢轴元素pivotkey大的元素;如果没找到left一直自增1;
将当前right所指元素设为该值;
然后从右边找到一个比枢轴元素小的,如果没找到right一直自减1;
这时left和right相遇了,将枢轴元素赋值给当前位置。
第一轮排序动态过程:
然后将数组分成了[17,28,3] 与 [66, 87, 55, 39*]两部分,再对这两部分进行上述环节即可,反反复复,直到只剩下一个元素。
排序全过程
完整代码如下:
#include<bits/stdc++.h> //万能头
using namespace std;
const int Max=100;
//顺序表的定义
typedef struct
{
int key;
}ordNode;
typedef struct
{
ordNode a[Max];
int len;
}Sqlist;
//对顺序表L中的子表r[low..high]进行一趟排序,返回枢轴位置
int Partition(Sqlist &L,int low,int high)
{
L.a[0]=L.a[low]; //用子表的第一个记录做枢轴记录
int pivotkey=L.a[low].key; //枢轴记录关键字记录到pivotkey中
while(low<high)
{
while(low<high&&L.a[high].key>=pivotkey)
high--;
L.a[low]=L.a[high]; //将比枢轴记录小的记录移到低端
while(low<high&&L.a[low].key<=pivotkey)
low++;
L.a[high]=L.a[low]; //将比枢轴记录大的记录移到高端
}
L.a[low]=L.a[0];//枢轴记录到位
return low; //返回枢轴位置
}
//调用前置初值:low=1, high=L.length
void QSort(Sqlist &L,int low,int high)
{
int pivotloc;
if(low<high)
{
pivotloc=Partition(L,low,high);
QSort(L,low,pivotloc-1); //递归调用
QSort(L,pivotloc+1,high);
}
}
//对顺序表L做快速排序
void QuickSort(Sqlist &L)
{
QSort(L,1,L.len);
}
int main(){
Sqlist L;
printf("请输入待排序数的个数:");
scanf("%d",&L.len);
printf("请输入待排序的数:");
for(int i=1;i<=L.len;i++)
scanf("%d",&L.a[i]);
int pivotkey=L.a[1].key;
QSort(L , L.a[1].key , L.a[L.len].key);
QuickSort(L);
printf("请输出排好序的数列:");
for(int i=1;i<=L.len;i++)
printf("%d ",L.a[i]);
return 0;
}
测试用例如下:
请输入待排序数的个数:8
请输入待排序的数:39 28 55 87 66 3 17 39
请输出排好序的数列:3 17 28 39 39 55 66 87
稳定性分析:
如下面的数组,相同元素用 * 标出[ 3 , 4 , 2, 2* ]
第一次排序为[2* , 2, 3, 4]
第二次为[2* , 2 , 3 , 4]
相对顺序发生了变化,所以是不稳定的。
图片讲解参考详解快速排序算法 - code随笔 - 博客园
希望可以帮到你哦!^_^