快速排序原理

先把网上别人的转载
    1. // 快速排序示例.cpp : Defines the entry point for the console application.
    2. // Written By Lee  2005-11-24
    3. #include "stdafx.h"
    4. /*使用快速排序法设计一个排序程序*/
    5. /*此程序的关键是取要排序数组的第一个元素(list[0])做为pivot值.然后分别左边从list[1]开始往又找比
    6. pivot值大的数组元素如果找到此元素就停下,再此同时程序从右边第一个元素开始找比pivot小的元素
    7. 找到以后停下,这样在i<j的前提下把这些元素一一掉换.一旦i>=j了就说明以pivot为数组中间元素的此数组
    8. 已经交换了所有可以交换的元素了,这时就应该让list[left]也就是当前的pivot归于它应该归属的数组位置
    9. list[j]了.然后数组以list[j]为界一分为二,递归.
    10. */
    11. /*举例说明
    12. 例如数组为 4 6 2 9 5 1 7 3 当此数组赋值完毕以后index=8,然后调用
    13. QuickSort(list,0,index-1,index)函数 然后这个函数的left=i=0;right=index-1;j=index=8;
    14. 然后以list[0]=4为pivot值,开始两头寻找可以交换的值.
    15. 第一次寻找 i=1 也就是list[1]=6 >4 而 j=7 list[7]=3<4 而且i<j 这就说明list[1]和list[7]
    16. 可以交换了.交换完毕数组为 4 3 2 9 5 1 7 6 
    17. 同样的步骤第二次交换是9 和1 此时i=3而j=5 list[3]=9 而list[5]=1 而且i<j所以list[i]与
    18. list[j]交换.交换完毕数组为 4 3 2 1 5 9 7 6 .
    19. 然后因为i<j所以继续循环1.此时i=4结束循环2 ,j=3结束循环3 .list[i]=5 list[j]=1;由于
    20. i=4>j=3所以结束循环1.而执行pivot的归位工作
    21. temp=list[left];
    22. list[left]=list[j];
    23. list[j]=temp;
    24. 即list[0]与list[3]交换值.交换完毕数组变为 1 3 2 4 5 9 7 6 此时4成了数组的分界线.
    25. 然后以4为界分为两半.左边为 1 3 2 右边为 5 9 7 6 .继续递归.
    26. 再以1 3 2为例说明一下排序过程 1 3 2 里最初pivot值为1 在经过循环2时i=1,而经过循环3时
    27. j=0  此时i>j了因此循环1结束.1的位置直接就很快找到了这就是快速排序的快的原因了.
    28. 然后就是list[left]和
    29. list[j]其实还是list[0]交换数据.等于没有交换.此时1的位置就还是它原来的位置,然后以
    30. 1为界再划分为两个部分进行递归.划分的结果就是1和2 3两个部分.下面的过程就很明了了.
    31. */
    32. void QuickSort(int *list ,int left,int right,int index)
    33. {
    34.  int i,j,k;
    35.  int pivot;/*分割指针*/
    36.  int temp;//用于交换时的暂存变量*/
    37.  i=left;j=right+1;
    38.  pivot=list[left];
    39.  /*取数组最左边的元素为pivot,下面的程序就是要为这个pivot找到它在当前数组里面
    40.  应该所属的位置*/
    41.   
    42.  if(i<j)
    43.  {
    44.   //循环1
    45.   do
    46.   {
    47.    do
    48.    { i++; } while(list[i]<=pivot&&i<=right); //循环2
    49.    
    50.    do
    51.    { j--; } while(list[j]>=pivot&&j>left);   //循环3
    52.   
    53.    if(i<j)
    54.    {
    55.     temp=list[i];
    56.     list[i]=list[j];
    57.     list[j]=temp;
    58.     printf("/n *当前排序结果:");
    59.     for(k=0;k<index;k++)
    60.     {
    61.      printf("%d ",list[k]);
    62.     }
    63.    }
    64.   }while(i<j);
    65.   //循环1结束
    66.   /*如果此时i>=j则说明当前的这个pivot值已经是当前数组所有元素的中间位置应该等于的值了,而且这个值应该处在list[j]的
    67.   位置上.所以应该交换list[left]也就是当前pivot与list[j]单元格里面的值.然后就以list[j]为界
    68.   把此数组一分为二.
    69.   */
    70.   temp=list[left];
    71.   list[left]=list[j];
    72.   list[j]=temp;
    73.   /*再打印一下当前的排序结果*/
    74.   printf("/n #当前排序结果:");
    75.           for(k=0;k<index;k++)
    76.     {
    77.      printf("%d ",list[k]);
    78.     }
    79.   /*此时list[j]里面的值就是中间值,此数组以list[j]为分界点左边的值小于list[j],
    80.     右边的值大于list[j],因此递归调用此函数排序左边与右边.
    81.    */
    82.   QuickSort(list,left,j-1,index);
    83.   QuickSort(list,j+1,right,index);
    84.   
    85.  }
    86. }
  • 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;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值