您的位置:首页 > 其它

快速排序算法

2016-03-28 23:40 696 查看
快速排序算法

本文参考清华大学出版社《数据结构与算法(C语言版)(第三版)》,详情请见书本。

快速排序是已知排序算法中速度最快的。

快速排序对序列S进行排序分成以下4步:

(1)如果S中只有1或者0个元素,则返回。

(2)在S中任意取一个元素v,称为枢纽元(pivot)。

(3)将S-{v}分成两个不相交的集合:S1={χ∈S-{v}|χ≤v}和S2={χ∈S-{v}|χ>v}。

(4)返回排序结果:{quicksort(S1),v,quicksort(S2)}。

下图以例子:{5,6,2,20,8,12,16,18,1}为例,讲解算法过程:



选取枢纽元的好坏,关系到算法性能的好坏。

常见的选取枢纽元的方法:

①选择待排序序列的第一个或最后一个记录。弊端:大段序列已经预排序,使得划分的子集严重失衡。

②使用随机数发生器来随机选取枢纽元。弊端:产生随机数本身要花费时间。

③实际中常见的三数中值分割法。用任意3个数值的中值作为整个序列中值的估量值。取待排序序列的第一个记录,位置位于中间的记录和最后一个记录的中值作为枢纽元。

待排序序列为{5,6,2,20,8,12,16,18,1},取record[0]=5, record[4]=8, record[8]=1的中值8为枢纽元。

三数中值分割法获取枢纽元的算法:获取枢纽元,并将其放在待排序记录的最后。

int getPivot(int *SList, int left, int right)
{
int center=(left+right)/2;
if(SList[left]>SList[center])
swap(&SList[left], &SList[center]);
if(SList[left]>SList[right])
swap(&SList[left], &SList[right]);
if(SList[center]>SList[right])
swap(&SList[center], &SList[right]);
swap(&SList[center], &SList[right]);
//将pivot放在倒数第一的位置,除了可以得到pivot的右值,还能得到其左值
return SList[right-1];
}
对集合的分割策略:

(1)将枢纽元与最后一个记录交换,让枢纽元pivot离开需要分割的数据集合。

(2)first指针指向第一个元素record[0],last指针指向倒数第二个元素record[n-1]。

(3)first向后移动到第一个比枢纽元pivot大的元素,last向前移动到第一个比枢纽元pivot小的元素。交换first和last指针所指记录。

(4)重复步骤(3),直到first和last相互错开,即first位于last的后面。将first所指记录与最后一个记录(枢纽元)交换。

待处理序列:{5,6,2,20,8,12,16,18,1},枢纽元为8。

集合分割策略演示:



快速排序算法:

int quicksort(int *SList, int left, int right)
{
if(right-left>=3)
{
int pivot,i,j;
pivot = getPivot(SList,left,right);
i=left;
j=right;
while(true)
{
while(SList[i]<pivot)
i++;
while(Slist[j]>pivot)
j--;
if(i<j)
swap(&SList[i],&SList[j]);
else
break;
}
swap(&SList[i],&SList[right]);
quicksort(SList, left, i-1);
quicksort(SList, i+1, right);
}
else     //当待排序序列长度小于3时使用直接插入排序
straightsort(SList, right-left);
}
快速排序实现程序:
在VS2010下新建Win32 控制台应用程序的项目:QuickSort

见下图:



源代码:QuickSort.cpp

// QuickSort.cpp : 定义控制台应用程序的入口点。

#include "stdafx.h"

#include<stdio.h>
#define MAXSIZE 20

int Partition(int *SList, int low, int high)
{
int pivotkey=SList[low];
while(low<high)
{
while(low<high && SList[high]>=pivotkey)
high--;
SList[low]=SList[high];
while(low<high && SList[low]<=pivotkey)
high++;
SList[high]=SList[low];
}
SList[low]=pivotkey;
return low;
}

void QSort(int *SList, int low, int high, int len)
{
int pivotloc;
if(low<high)
{
int i;
for(i=0; i<len; i++)
{
printf("%d ", SList[i]);
}
pivotloc=Partition(SList, low, high);
printf("(Current pivotkey is %d) ", SList[pivotloc]);
for(i=0; i<len; i++)
{
printf("%d ", SList[i]);
}
printf("\n ");
QSort(SList, low, pivotloc-1, len);
QSort(SList, pivotloc+1, high, len);
}
}

void QuickSort(int *SList, int len)
{
QSort(SList, 0, len-1, len);
}

int main()
{
int length;
//int pos;
int test[MAXSIZE];
int i;
printf("Please input the number of record:\n");
if(scanf("%d",&length)!=1)
return -1;
printf("Please input the record:\n");
for(i=0; i<length; i++)
{
scanf("%d",&(test[i]));
}
QuickSort(test,length);
for(i=0; i<length; i++)
{
printf("%d ", test[i]);
}
printf("\n ");

return 0;
}
Ctrl+F5执行QuickSort.cpp ,运行结果如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: