先把网上别人的转载
-
- // 快速排序示例.cpp : Defines the entry point for the console application.
- // Written By Lee 2005-11-24
- #include "stdafx.h"
- /*使用快速排序法设计一个排序程序*/
- /*此程序的关键是取要排序数组的第一个元素(list[0])做为pivot值.然后分别左边从list[1]开始往又找比
- pivot值大的数组元素如果找到此元素就停下,再此同时程序从右边第一个元素开始找比pivot小的元素
- 找到以后停下,这样在i<j的前提下把这些元素一一掉换.一旦i>=j了就说明以pivot为数组中间元素的此数组
- 已经交换了所有可以交换的元素了,这时就应该让list[left]也就是当前的pivot归于它应该归属的数组位置
- list[j]了.然后数组以list[j]为界一分为二,递归.
- */
- /*举例说明
- 例如数组为 4 6 2 9 5 1 7 3 当此数组赋值完毕以后index=8,然后调用
- QuickSort(list,0,index-1,index)函数 然后这个函数的left=i=0;right=index-1;j=index=8;
- 然后以list[0]=4为pivot值,开始两头寻找可以交换的值.
- 第一次寻找 i=1 也就是list[1]=6 >4 而 j=7 list[7]=3<4 而且i<j 这就说明list[1]和list[7]
- 可以交换了.交换完毕数组为 4 3 2 9 5 1 7 6
- 同样的步骤第二次交换是9 和1 此时i=3而j=5 list[3]=9 而list[5]=1 而且i<j所以list[i]与
- list[j]交换.交换完毕数组为 4 3 2 1 5 9 7 6 .
- 然后因为i<j所以继续循环1.此时i=4结束循环2 ,j=3结束循环3 .list[i]=5 list[j]=1;由于
- i=4>j=3所以结束循环1.而执行pivot的归位工作
- temp=list[left];
- list[left]=list[j];
- list[j]=temp;
- 即list[0]与list[3]交换值.交换完毕数组变为 1 3 2 4 5 9 7 6 此时4成了数组的分界线.
- 然后以4为界分为两半.左边为 1 3 2 右边为 5 9 7 6 .继续递归.
- 再以1 3 2为例说明一下排序过程 1 3 2 里最初pivot值为1 在经过循环2时i=1,而经过循环3时
- j=0 此时i>j了因此循环1结束.1的位置直接就很快找到了这就是快速排序的快的原因了.
- 然后就是list[left]和
- list[j]其实还是list[0]交换数据.等于没有交换.此时1的位置就还是它原来的位置,然后以
- 1为界再划分为两个部分进行递归.划分的结果就是1和2 3两个部分.下面的过程就很明了了.
- */
- void QuickSort(int *list ,int left,int right,int index)
- {
- int i,j,k;
- int pivot;/*分割指针*/
- int temp;//用于交换时的暂存变量*/
- i=left;j=right+1;
- pivot=list[left];
- /*取数组最左边的元素为pivot,下面的程序就是要为这个pivot找到它在当前数组里面
- 应该所属的位置*/
- if(i<j)
- {
- //循环1
- do
- {
- do
- { i++; } while(list[i]<=pivot&&i<=right); //循环2
- do
- { j--; } while(list[j]>=pivot&&j>left); //循环3
- if(i<j)
- {
- temp=list[i];
- list[i]=list[j];
- list[j]=temp;
- printf("/n *当前排序结果:");
- for(k=0;k<index;k++)
- {
- printf("%d ",list[k]);
- }
- }
- }while(i<j);
- //循环1结束
- /*如果此时i>=j则说明当前的这个pivot值已经是当前数组所有元素的中间位置应该等于的值了,而且这个值应该处在list[j]的
- 位置上.所以应该交换list[left]也就是当前pivot与list[j]单元格里面的值.然后就以list[j]为界
- 把此数组一分为二.
- */
- temp=list[left];
- list[left]=list[j];
- list[j]=temp;
- /*再打印一下当前的排序结果*/
- printf("/n #当前排序结果:");
- for(k=0;k<index;k++)
- {
- printf("%d ",list[k]);
- }
- /*此时list[j]里面的值就是中间值,此数组以list[j]为分界点左边的值小于list[j],
- 右边的值大于list[j],因此递归调用此函数排序左边与右边.
- */
- QuickSort(list,left,j-1,index);
- QuickSort(list,j+1,right,index);
- }
- }
- procedure QuickSort(var Data: array of Integer; Lo, Hi: Integer);
- procedure Swap(var A,B:Integer);
- var C:Integer;
- begin
- C:=A;
- A:=B;
- B:=C;
- end;
- var X,I,J:Integer;
- begin
- if Hi<=Lo then Exit;
- X:=Data[Lo];
- I:=Lo+1;
- J:=Hi;
- while True do begin
- while Data[I]<X do Inc(I);//从左向右找到第一个比X中间值大的,用来交换
- while Data[J]>X do Dec(J);//从右向左找到第一个比X中间值小的,用来交换
- if I<J then begin
- //分别有小于及大于中间值的数,交换
- Swap(Data[I],Data[J]);
- //如果再有2个都等于中间值时,会死循环在此,所以需要将I,J加一 正常情况下有可能没有考虑到这里,
- Inc(I);
- Dec(J);
- end;
- if I>=J then begin
- //将中间值交换为它的正确位置,初始为第一个
- Swap(Data[Lo],Data[J]);
- //此时已经将数据分开,在中间值左边为小于中间值的数据,在右边为大于的
- Break;
- end;
- end;
- DispData;
- //左边数据排序
- QuickSort(Data,Lo,J-1);
- //右边数据排序
- QuickSort(Data,J+1,Hi);
- end;