快速排序算法(数据结构)

快速排序的基本思想:任取待排序序列的一个元素作为中心元素(可以用第一个,最后一个,也可以是中间任何一个),习惯将其称为pivotkey,即枢轴元素。将所有比枢轴元素小的放在其左边,将所有比它大的放在其右边,形成左右两个子表,然后对左右两个子表再按照前面的算法进行排序(递归),直到每个子表的元素只剩下一个。

举例说明一下:

arr 为 [39 , 28 , 55 , 87 , 66 , 3 ,17 ,39*]为了区别两个相同元素,将最后一个加上 * 。
初始状态如下图:

快速排序算法(数据结构)

定义一枢轴元素pivotkey,初始化为第一个元素的值,即39;
查询左边的元素的变量为leftlow,初始值为第一个元素的索引,0;
查询右边的元素的变量为righthight,初始值为第一个元素的索引,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随笔 - 博客园

 希望可以帮到你哦!^_^

上一篇:72_Go基础_1_39 结构体匿名字段


下一篇:[解题报告]《算法零基础100讲》(第39讲) 非比较排序 - 计数排序