- 一、快速排序
- 1.1 快排概念
- 1.2 快排算法基本思想
- 1.3 快排算法具体说明
- 1.4 通过快排举例进行详解
- 二、代码实现
- 三、结果展示
快速排序是冒泡排序的优化,是一种基于交换的排序方式。
时间复杂度 O(nlogn)。
分而治之思想
通过一趟排序,将待排序列分成两部分,
其中一部分中的数据都比另一部分中的数据小(每一部分中的数据无需保证有序)。
然后将分成的这两部分数据,每一个部分分别在各自执行排序,每一部分再分成独立的两部分。
将上面的方式通过递归执行,直到整个序列有序。
在一串待排序序列的数列中,通过找一个关键字(待排序序列中的一个数据元素),从而将待排序序列分为两部分(一部分都大于这个关键字,一部分都小于这个关键字),但这两部分序列无需是有序的。
以上操作本质就是找到关键字在这个序列中(升序或降序)该存在的位置。
然后被这个关键字分割的两部分序列继续按照上述描述进行分割(递归思想)。
综合来说将算法思路分成三个部分:
1.挑元素
2.划分组
3.分组重复前两步
以无序序列 8,4,13,67,99,23,15为例:
1.挑元素:
一般是以序列首元素为作为参考元素(关键字),首元素是8。
2.划分组:
本质是确定参考元素(关键字) 8 该存在的位置,并将序列分为两个部分。
将大于 8 的数据放到 8 应该存在位置的右侧,
将小于 8 的数据放到 8 应该存在位置的左侧,
且被 8 分成两部分的序列无需是有序的。
首先,找出 8 应该存放至序列本应存在的位置
定义一个temp,将数据 8 赋给temp
定义i,j变量分别记录序列的第一个元素,和最后一个元素的位置
以上述无序序列为例i=0,j=6
从j位置上开始和temp进行循环比较,如果是s[j]>temp且i
j位置上的元素要赋值到i位置的元素上
i位置上的数据被覆盖
但是我们以及提前将i位置上的数据保存在temp中了
接下来要从i位置上开始和temp进行循环比较,如果是s[i]<=temp且i
j位置上的数据在查找s[j]>temp时就已经将j位置上的数据赋值到i上去了
当i与j重合的时就是temp所该存在的位置
s[i]=temp或者s[j]=temp
3.分组重复前两步
通过递归进行左部分排序
通过递归进行右部分排序
#include三、结果展示void quick(int *s, int i, int j); //声明快排函数 int main(int argc, const char *argv[]) { int s[7] = {8, 4, 13, 67, 99, 23, 15}; int i = 0; for (; i < 7; i++) //排序前进行遍历 { printf("%d ", s[i]); } puts(""); quick(s, 0, 6); for (i = 0; i < 7; i++) //排序后进行遍历 { printf("%d ", s[i]); } puts(""); return 0; } void quick(int *s, int i, int j) { if (i < j) //递归入口 { int temp = s[i]; //挑元素 int begin = i; int end = j; while (i < j) { //划分组 while (i < j && temp < s[j]) { j--; } s[i] = s[j]; //小于temp的值进行左移 while (i < j && temp >= s[i]) { i++; } s[j] = s[i]; //大于等于temp的值进行右移 } s[i] = temp; //确定temp应在的位置 quick(s, begin, i - 1); //左组重复前两部 quick(s, j + 1, end); //右组重复前两部 } else //递归出口 { return ; } }
成功实现



