C++快速排序、归并排序

归并排序


void Merge(int *a, int p, int q, int r)  
{  
    int n1 = q-p+1;  
    int n2 = r-q;  
    int *L = new int[n1+1];  
    int *R = new int[n2+1];  
    int i, j, k;  
      
    for (i=0; i<n1; i++){  
        L[i] = a[p+i];  
    }  
    for (j=0; j<n2; j++){  
        R[j] = a[q+j+1];  
    }  
    L[n1] = 10000000;  
    R[n2] = 10000000;  
  
    for (i=0, j=0, k=p; k<=r; k++)  
    {  
        if (L[i]<=R[j])  //如果第一个数组的第一个值小于第二个数组的第一个值,那么把a的第一个位置给第一个数组的第一个位置,然后再拿第一个数组的第二个位置和第二个数组的第一个位置进行比较
        {  
            a[k] = L[i];  
            i++;  
        }else{  
            a[k] = R[j];  
            j++;  
        }  
    }  
  
    delete []L;  
    delete []R;  
}  
  
void MergeSort1(int *a, int p, int r)  
{  
    if (p<r)  
    {  
        int q = (p+r)/2;  
        MergeSort1(a, p, q);  
        MergeSort1(a, q+1, r);  
        Merge(a, p, q, r);  
    }  
}  

转载至:http://blog.csdn.net/left_la/article/details/8656953#comments

------------------------------------------------------------------------------------------------------

快速排序

假设用户输入了如下数组:
下标
0
1
2
3
4
5
数据
6
2
7
3
8
9
创建变量i=0(指向第一个数据), j=5(指向最后一个数据), k=6( 赋值为第一个数据的值)。
我们要把所有比k小的数移动到k的左面,所以我们可以开始寻找比6小的数,从j开始,从右往左找,不断递减变量j的值,我们找到第一个下标3的数据比6小,于是把数据3移到下标0的位置,把下标0的数据6移到下标3,完成第一次比较:
下标
0
1
2
3
4
5
数据
3
2
7
6
8
9
i=0 j=3 k=6
接着,开始第二次比较,这次要变成找比k大的了,而且要从前往后找了。递加变量i,发现下标2的数据是第一个比k大的,于是用下标2的数据7和j指向的下标3的数据的6做交换,数据状态变成下表:
下标
0
1
2
3
4
5
数据
3
2
6
7
8
9
i=2 j=3 k=6
称上面两次比较为一个循环。
接着,再递减变量j,不断重复进行上面的循环比较。
在本例中,我们进行一次循环,就发现i和j“碰头”了:他们都指向了下标2。于是,第一遍比较结束。得到结果如下,凡是k(=6)左边的数都比它小,凡是k右边的数都比它大:
下标
0
1
2
3
4
5
数据
3
2
6
7
8
9
如果i和j没有碰头的话,就递加i找大的,还没有,就再递减j找小的,如此反复,不断循环。注意判断和寻找是同时进行的。
然后,对k两边的数据,再分组分别进行上述的过程,直到不能再分组为止。
注意:第一遍快速排序不会直接得到最终结果,只会把比k大和比k小的数分到k的两边。为了得到最后结果,需要再次对下标2两边的数组分别执行此步骤,然后再分解数组,直到数组不能再分解为止(只有一个数据),才能得到正确结果。
#include <iostream>
 
using  namespace  std;
 
void  Qsort( int  a[],  int  low,  int  high)
{
     if (low >= high)
     {
         return ;
     }
     int  first = low;
     int  last = high;
     int  key = a[first]; /*用字表的第一个记录作为枢轴*/
 
     while (first < last)
     {
         while (first < last && a[last] >= key)
         {
             --last;
         }
 
         a[first] = a[last]; /*将比第一个小的移到低端*/
 
         while (first < last && a[first] <= key)
         {
             ++first;
         }
         
         a[last] = a[first];    
/*将比第一个大的移到高端*/
     }
     a[first] = key; /*枢轴记录到位*/
     Qsort(a, low, first-1);
     Qsort(a, first+1, high);
}
int  main()
{
     int  a[] = {57, 68, 59, 52, 72, 28, 96, 33, 24};
 
     Qsort(a, 0,  sizeof (a) /  sizeof (a[0]) - 1); /*这里原文第三个参数要减1否则内存越界*/
 
     for ( int  i = 0; i <  sizeof (a) /  sizeof (a[0]); i++)
     {
         cout << a[i] <<  "" ;
     }
     
     return  0;
} /*参考数据结构p274(清华大学出版社,严蔚敏)*/

转载至:http://baike.baidu.com/link?url=judPREQW8zENwIms3v_pZD_uw43PFBS8HtqdUDskwrNfPS3hku5ABGRBtsvl4LyidI9K9e7CzWPWBmpLOtV9iBKX8qw2WoUjp7WYiku1rXzryLYvtPD3mhIWIM1IQQ-N67r6ULy9dBMlOJBpakey08ZaF2mvvONc9FelZqbVeBkWgmNtxtQnFV48jf2QDd4tncV7Mx5BmnxgeUsT8t05btR0FlL0W1FwQr3jQeNue_S

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值