一、什么是快速排序?
快速排序是对冒泡排序的改进,本质上都是通过交换两个元素来消除逆序。
在冒泡排序中,由于扫描过程中只对相邻的两个元素进行比较,因此在互换两个相邻元素时只能消除一个逆序。
而在快速排序中,能通过两个不相邻的元素的交换,消除待排序记录中的多个逆序,则速度较冒泡排序有极大的提高。
二、快速排序实现算法思路:
(1)、快速排序算法是一个递归过程:
一个问题能通过递归来解决,则说明其能够将一个大问题分解为无数个小问题;而且这些小问题的解决算
法与大问题的解决算法是一毛一样的,只是问题规模的差别。
所以快速排序可以分解为无数的小问题,每一个小问题的解决方法都一样。
(2)、那么这个解决方法是什么呢?
首先在待排序记录中找一个支柱元素结点(一般都是找序列的第一个元素,因为简单),使用这个支柱结
点将序列划分为两个子序列。
怎么划分呢? 将大于等于支柱结点值的元素放到支柱结点的右边(子序列1);将小于支柱结点值得元
素放到支柱结点的左边(子序列2);然后理所应当这个支柱结点就在两个子序列的交接点上。在此时,我们
如果把整个序列看成三个元素:子序列2 < 支柱结点 < 子序列1,是不是有序的呢?
(3)、理解了这一点,就好办了!
我们把一个最开始的大序列通过支柱结点划分为两个子序列,再将每个子序列划分为两个子子序列。。。
当所有的子序列的长度为0 或 1 时,而且经过(2)步骤的元素交换后。那么当前整个序列就已经是一个有序
序列了。
下图为一次划分实例:
<1>. 将序列的第一个元素用变量x保存(则下标为0的元素位置空下来了),用low 和 high两个下标变量来存
储序列两端的下标。其中low是序列左端下标(下标为 0),high为序列的右端下标(下标为序列长度- 1)
, low < high ;
<2>. 因为low位置是空的,所以可以放一个元素;因为是左端空了,所以从右端由 high 从右端向左端递减寻
找比支柱结点 x 值小的元素放入 low 的位置,low下标向后挪一个位置(low++)。然后是 high位置空了。
<3>. 因为high位置是空的,所以可以放一个元素;因为是右端空了,所以从左端由 low 从左端向右端递增寻
找比支柱结点 x 值大的元素放入 high的位置,high下标向前挪一个位置 (high--)。然后又是 low 位置空
了。 由此转去循环执行<2>、<3>过程。直到 low < high 条件不在被满足,退出循环。
<4>. 将支柱结点的值保存在low = high 的下标位置。
<5>. 一趟排序完成。
源代码:
#include <stdio.h>
/*
**功能: 进行一趟快速排序
**参数说明:
**@record : 子序列数组; @low : 序列左端下标; @high : 序列右端下标
**返回值 : 支柱结点下标
*/
int QKPass(int record[], int low, int high)
{
int x = record[low]; //保存支柱结点值
while (low < high)
{
/*
* 因为low位置是空的,所以可以放一个元素;因为是左端空了,所以从右端由
* high 从右端向左端递减寻找比支柱结点 x 值小的元素放入 low 的位置,low下
* 标向后挪一个位置(low++)
*/
while (low < high && record[high] >= x)
{
high--;
}
if (low < high)
{
record[low] = record[high];
low++;
}
/*
* 经过上面操作后,high位置是空的,所以可以放一个元素;因为是右端空了,
* 所以从左端由low 从左端向右端递增寻找比支柱结点 x 值大的元素放入 high的
* 位置,high下标向前挪一个位置 (high--)。
*/
while (low < high && record[low] < x)
{
low++;
}
if (low < high)
{
record[high] = record[low];
high--;
}
}
record[low] = x; //将支柱结点的值保存在low = high的位置
}
/*
**功能: 快速排序入口点
**参数说明:
**@record : 记录序列数组; @low : 序列左端下标; @high : 序列右端下标
**返回值 : 无
*/
void QKSort(int record[], int low, int high)
{
if (low < high)
{
int position; //保存支柱结点下标
position = QKPass(record, low, high); //进行一趟快速排序,找到支柱结点的下标
QKSort(record, low, position - 1); //对序列2进行快速排序
QKSort(record, position + 1, high); //对序列1进行快速排序
}
}
int main(void)
{
int record[] = { 48,62,35,77,55,14,35,98 };
int len = sizeof(record) / sizeof(record[0]);
int i = 0;
printf("排序前: \n");
for (i = 0;i < len;i++)
{
printf("%d ", record[i]);
}
puts("");
QKSort(record, 0, len - 1);
printf("排序后: \n");
for (i = 0;i < len;i++)
{
printf("%d ", record[i]);
}
puts("");
return 0;
}
运行截图: