快速排序,冒泡

 

本文转载自网络: http://virus.blog.51cto.com/51437/17961
查看系统那个调用 qsort sort
快速排序C语言源程序分析!

 void  Swap( int   * a,  int   * b)
  {
     int  temp;

    temp  =   * a;
     * a    =   * b;
     * b    =  temp;
}
 
 //  冒泡排序
 void  BubbleSort( int  array[],  int  length)
  {
     //  记录一次遍历中是否有元素的交换
      bool  exchange;
     for  ( int  i  =   0 ; i  <  length;  ++ i)
      {
        exchange  =   false ;
         for  ( int  j  =  i  +   1 ; j  <  length;  ++ j)
          {
             if  (array[j]  <=   array[i])//=号解决了相等的数问题
              {
                exchange  =   true ;
                Swap( & array[j],  & array[i]);
            }
        }
         //  如果这次遍历没有元素的交换,那么排序结束
          if  ( false   ==  exchange)
             break ;
    }
}

2007-02-16 23:44:32
标签: C语言
提示:
看此文之前请将快速排序的思想和过程基本搞清楚,否则光看程序理解起来是比较困难的,因为违反了循序渐进 的学习法则。
 

快速排序是对冒泡排序的一种改进。它的基本思想是:通过一躺排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一不部分的所有数据都要小,然后再按次方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

   假设要排序的数组是A[1]……A[N],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一躺快速排序。一躺快速排序的算法是:

  1)、设置两个变量I、J,排序开始的时候I:=1,J:=N;

  2)以第一个数组元素作为关键数据,赋值给X,即X:=A[1];

  3)、从J开始向前搜索,即由后开始向前搜索(J:=J-1),找到第一个小于X的值,两者交换;

  4)、从I开始向后搜索,即由前开始向后搜索(I:=I+1),找到第一个大于X的值,两者交换;

  5)、重复第3、4步,直到I=J;

  例如:待排序的数组A的值分别是:(初始关键数据X:=49)

                  A[1]    A[2]    A[3]    A[4]    A[5]     A[6]    A[7]: 

                    49       38      65      97      76      13       27

进行第一次交换后:  27       38      65      97      76      13       49

                  ( 按照算法的第三步从后面开始找

进行第二次交换后:  27       38      49      97      76      13       65

                 ( 按照算法的第四步从前面开始找>X的值,65>49,两者交换,此时I:=3 )

进行第三次交换后:  27       38      13      97      76      49       65

( 按照算法的第五步将又一次执行算法的第三步从后开始找

进行第四次交换后:  27       38      13      49      76      97       65

( 按照算法的第四步从前面开始找大于X的值,97>49,两者交换,此时J:=4 )

     此时再执行第三不的时候就发现I=J,从而结束一躺快速排序,那么经过一躺快速排序之后的结果是:27       38      13      49      76      97       65,即所以大于49的数全部在49的后面,所以小于49的数全部在49的前面。

     快速排序就是递归调用此过程——在以49为中点分割这个数据序列,分别对前面一部分和后面一部分进行类似的快速排序,从而完成全部数据序列的快速排序,最后把此数据序列变成一个有序的序列,根据这种思想对于上述数组A的快速排序的全过程如图6所示:

 

 初始状态                       {49    38    65    97    76    13    27}   

进行一次快速排序之后划分为     {27    38    13}    49  {76    97    65}

分别对前后两部分进行快速排序 {13}   27   {38} 

                                                          结束        结束   49   {65}   76   {97}

                                                                   图6   快速排序全过程

#i nclude <iostream.h>
int   data[9] = {54,38,96,23,15,72,60,45,83};
void quick_sort(int data[], int low, int high)//  程序中这样调用quick_sort(data,0,sizeof(data)/sizeof(int) - 1);
{
       int i, j, pivot;
       if (low < high)
       {
              pivot=data[low];
              i=low;
              j=high;
             
              while(i<j)
              {
                     while (i<j && data[j]>=pivot)
                            j--;
                     if(i<j)
                            data[i++]=data[j];   // 将比枢轴记录小的记录移到低端
                    
                     while (i<j && data[i]<=pivot)
                            i++;
                     if(i<j)
                            data[j--]=data[i];       // 将比枢轴记录大的记录移到高端
              }
             
              data[i]=pivot;         // 枢轴记录移到最终位置
             
              quick_sort(data,low,i-1);
              quick_sort(data,i+1,high);
       }
}
 
void main()
{
       quick_sort(data, 0, 8);
}
 
        下面是对这段程序的分析:
    “ pivot=data[low]; ”表示将最低端即第一个元素作为枢轴记录,暂存到 pivot 中去,“ while(i<j) ”表示当高低指针相遇时循环终止,否则继续。“ while (i<j && data[j]>=pivot)          j--; ”表示从高端(即数组后面)开始搜索,直到搜索到一个比枢轴值小的某个元素,条件“ data[j]>=pivot ”用的是大于或等于号,可见,在搜索过程中若遇到相等的则跳过并继续搜索,条件“ i<j ”不可少,因为在搜索过程中, low high 可能相遇,此“ i<j ”跟外层 while 的条件“ i<j ”无关,作用各不相同,外层 while 的条件“ i<j ”是判断在进行从高端向低端搜索一趟、从低端向高端搜索一趟之后高低指针是否相遇,而前者却是在单向的搜索过程中为防止高低指针相遇。
        当经过“ while (i<j && data[j]>=pivot)       j--; ”的搜索之后,搜索到一个比枢轴小的元素,因为在搜索完之后 i j 可能相等,若相等,就没有交换的必要,因此紧接下面设置了一个判断“ if(i<j) ”,若成立,那么就要将比枢轴记录小的记录移到低端“ data[i++]=data[j]; ”,这里的“ data[i++] ”表示先使用了 data[i] 之后才加 1 ,相当于“ data[i]=data[j]; i++; ”两句的效果。为什么要 i++ ?是因为刚交换的记录肯定比枢轴小,那么紧接下面的语句“ while (i<j && data[i]<=pivot) ”就少了一次不必要的比较(因为: data[i]<=pivot 必定成立,而 i<j 在前面的 if 语句中已成立,则“ i<j && data[i]<=pivot ”必成立,若没有 i++ while 中的““ i<j && data[i]<=pivot ””在肯定成立的情况下执行了一次),提高了效率。执行“ data[i++]=data[j]; ”之后,高端的 data[j] 覆盖了 data[i] 的值,第一次覆盖时,覆盖的是 data[low] 的值,因为最开始时,“ pivot=data[low]; ”将最低端即第一个元素作为枢轴记录暂存到 pivot 中去了,所以不必担心,会丢失信息,由于 data[j] 的值赋给了 data[i] ,那么 data[j] 原来的位置 j 就可以看做一个空白,下一次覆盖时,就将低端的 data[i] 复制到这个位置。
        紧接下来的“ while (i<j && data[i]<=pivot)   i++; ”是从低端向高端搜索,直到找到一个比枢轴大的元素,先进行判断“ if(i<j) ”,若成立,如前所述,执行“ data[j--]=data[i]; ”就将低端的 data[i] 复制到上次赋值后空出的 j 位置。
        如此反复,直到外层 while 的条件不成立,即 i==j ,即高低指针相遇,表示已经找到了枢轴记录 pivot 的最终位置 i ,执行“ data[i]=pivot; ”于是,枢轴记录移到最终位置。接下来的“ quick_sort(data,low,i-1);  quick_sort(data,i+1,high); ”表示,对被 pivot 分开的左右子序列进行递归的快速排序。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值