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

来源:互联网 发布:妖精帝国知乎 编辑:程序博客网 时间:2024/06/06 01:12

归并排序


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

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 入户门对着厕所怎么办 一开门对厕所门怎么办 房子窗户对着路怎么办 电梯门对入户门怎么办 鞋柜对着入户门怎么办 入户门对着窗户怎么办 院子门对着窗户怎么办 电梯入户同梯人怎么办 房门对着电梯门怎么办 房门对着电梯口怎么办 大门对着电梯门怎么办 房门和电梯对着怎么办 搬家与生肖相冲怎么办 颈椎生理曲度变直怎么办 整个背部长痘痘怎么办 卧室门对着厨房怎么办 卧室门正对厕所怎么办 进门正对厕所门怎么办 门口对着厕所门怎么办 厨房门比大门高怎么办 鼻子上山根横纹怎么办 墙与床的缝隙怎么办 床边与墙有间隙怎么办 抽了烟头晕恶心怎么办 9个月宝宝口臭怎么办 狗舔了人的伤口怎么办 狗舔了结痂伤口怎么办 狗狗指甲变黑了怎么办 狗狗不肯剪指甲怎么办 厕所门对厨房门怎么办 房间门对着镜子怎么办 门直对着楼梯口怎么办 厨房门对着客厅怎么办 卧室正对着马路怎么办 主卧厕所对着床怎么办 卧室门对着床头怎么办 主卧厕所门对床怎么办 老人晕车怎么办最有效方法 货车油刹不好用怎么办 7岁儿童喉咙有痰怎么办 3岁宝宝喉咙有痰怎么办