快速排序的基本思想
快速排序是对冒泡排序的一种改进,其基本思想是基于分治法的:在待排序表L[1…n]中任取一个元素 pivot 作为基准(或者叫枢轴),通过一趟排序将待排序表划分为独立的两部分L[1…k-1]和L[k+1…n],使得L[1…k-1]中的所有元素都小于 pivot ,L[k+1…n]中的所有元素都大于等于 pivot ,而 pivot 则放在了其最终位置L(k)上,这个过程称为一趟快速排序。而后分别递归地对两个子表L[1…k-1]和L[k+1…n]重复上述过程,直至每部分内只有一个元素或空为止,即所有元素放在了其最终位置上。
快速排序任务可以如下完成:
1)设k=a[0],将k挪到适当位置,使得比k小的元素都在k左边,比k大的元素都在k右边,和k相等的不用关心出现在k的左还是右,因为在k左右出现均可(O(n)时间完成)
2)把k左边的部分快速排序
3)把k右边的部分快速排序
快速排序代码实现
#include<iostream>
using namespace std;
int a[] = {7,1,3,8,12,11,2,9};
void swap(int & a,int & b)//交换变量a,b的值
{
int tmp = a;
a = b;
b = tmp;
}
void QuickSort(int a[],int s,int e)
{
if(s >= e)//递归结束条件
return;
int k = a[s];//取第一个位置的元素作为基准元素
int i = s, j = e;
while(i != j)//偶数次交换后看变量 j(右边),奇数次交换后看变量 i(左边)
{//0也算偶数,所以一开始看变量 j
while(j > i && a[j] >= k)
--j;
swap(a[i],a[j]);
while(i < j && a[i] <= k)
++i;
swap(a[i],a[j]);
}//处理完后,i=j,a[i] = k
QuickSort(a,s,i-1);
QuickSort(a,i+1,e);
}
int main()
{
int size = sizeof(a)/sizeof(int);
QuickSort(a,0,size-1);
for(int i = 0; i < size; i++)
cout << a[i] << " ";
cout << endl;
return 0;
}
这里强调一下:
当基准元素选择最左边的数字时,那么就应该先从右边开始搜索;当基准元素选择最右边的数字时,那么就应该先从左边开始搜索。
上述代码第一趟快速排序过程如下:
(因为基准元素选择最左边的数字7,所以先从右边开始搜索,先看指针j)
如图所示,7作为基准元素,小于它的在其左边,大于它的在其右边。接下来对[2,1,3]和[12,11,8,9]再递归地进行排序。
最后我们再来实现严蔚敏老师的《数据结构》书上快速排序的伪代码:
#include<iostream>
using namespace std;
int a[] = {7,1,3,8,12,11,2,9};
int Partition(int a[], int low, int high)//Partition()就是划分操作,将a[low...high]进行一分为二
{
int pivot = a[low];//选择当前表中第一个元素设为基准元素
while(low < high)//从表的两端交替地向中间扫描
{
while(high > low && a[high] >= pivot)
--high;
a[low] = a[high];//将比基准元素值小的元素移动到左端
while(low < high && a[low] <= pivot)
++low;
a[high] = a[low];//将比基准元素值大的元素移动到右端
}
a[low] = pivot;//基准元素存放到最终位置
return low;//返回存放基准元素的最终位置 pivotpos(pos:position 位置)
}
void QuickSort(int a[],int low,int high)
{
if(low < high)//递归跳出的条件
{
int pivotpos = Partition(a,low,high);//基准元素最终位置
QuickSort(a,low,pivotpos-1);//对低子表递归排序
QuickSort(a,pivotpos+1,high);//对高子表递归排序
}
}
int main()
{
int size = sizeof(a)/sizeof(int);
QuickSort(a,0,size-1);
for(int i = 0; i < size; i++)
cout << a[i] << " ";
cout << endl;
return 0;
}
运行截图如下:
感谢阅读,若有错误还请指出,如果有什么不懂的也可以留言!
最后推荐一篇对快速排序过程写得很好的文章:
漫画:什么是快速排序?(完整版)