码迷,mamicode.com
首页 > 编程语言 > 详细

归并排序的递归实现

时间:2017-11-22 14:26:02      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:pre   遍历   区间   length   define   排序   子序列   generate   void   

思路图来自:https://www.cnblogs.com/fanwencong/p/5910503.html

这里我们依然用顺序表来实现这个排序算法。

顺序表一样是0号位不用。

这里我们的归并排序是二路归并,思路就是把序列一直分解成两份,直至分到子序列的长度为1,那么显然子序列已经有序,然后再不停地将有序序列归并起来,最后实现排序。

技术分享图片

 

下面上代码:

先是顺序表的接口与声明:

#define OVERFLOW 0
#define ERROR 0
#define FALSE 0
#define OK 1
#define TRUE 1

typedef struct {
    int * elem;//基址空间
    int length;//当前长度
    int size;//储存容量
    int increment;//扩容的增量
}SqList;
/*顺序表的接口*/
int InitSqList(SqList &L, int size, int inc);//初始化顺序表
int DestroySqList(SqList &L);//销毁顺序表L
int ClearSqList(SqList &L);//将顺序表清空
int SqListIsEmpty(SqList L);//判空函数
int GetElemSqList(SqList L, int i, int &e);//用e返回顺序表L中第i号元素
int SearchSqList(SqList L, int e);//在顺序表中查找元素e,若成功时返回该元素第一次出现的位置,否则返回-1
int PutElemSqList(SqList &L, int i, int e);//将L中第i个元素改为e
int AppendSqList(SqList &L, int e);//在L表添加元素e
int DeleteLastSqList(SqList &L, int &e);//删除L表的尾元素,并用参数e作为返回值
void TraverseSqList(SqList L);//遍历元素,并打印
                              /*随机数生成函数*/
int * RandomGenerate(int n);//生成个n个随机数的数组
                            /*测试函数*/

 

看算法:

void Merge(SqList & L1,SqList L2 , int i, int m, int n);//2路归并的归并操作,将L1的相邻有序区间i->m和m+1->n归并成i->n的有序序列储存到L2中。
void MSort(SqList L1, SqList L2, int i, int s, int t);//递归归并排序的递归排序操作,如果i为奇数,排序后的记录储存在L2否则存进L1里

int main() 
{
      srand((unsigned)time(NULL));//加一句srand((unsigned)time(NULL));  打开随机触发器 与时钟频率同步 
    SqList l;
    InitSqList(l,6,5);//默认加多一个内存
    int * testArray = RandomGenerate(6);
    int i;
    for (i = 0 ; i < 6; i++) {
        AppendSqList(l, testArray[i]);//默认从1号位开始加数字
    }
    printf("the original list:\n");
    TraverseSqList(l);

      //排序模块:
         SqList l2;
    InitSqList(l2, 6, 5);//辅助顺序表
    MSort(l, l2, 0, 1, l.length);//因为是排顺序表l,所以传入的i是偶数0
    DestroySqList(l2);               
}    



void Merge(SqList & L1, SqList L2, int i, int m, int n) {//2路归并的归并操作,将L1的相邻有序区间i->m和m+1->n归并成i->n的有序序列储存到L2中。
    int j = i, k = m + 1, h = i;
    for (; j <= m, k <= n; h++) {
        if (L1.elem[j] <= L1.elem[k]) {//这个如果不加=就是不稳定的排序喔
            L2.elem[h] = L1.elem[j++];//哪个小就把哪个放过来
        }
        else {
            L2.elem[h] = L1.elem[k++];
        }
    }
    while (j <= m) {
        L2.elem[h++] = L1.elem[j++];
    }
    while (k <= n) { 
        L2.elem[h++] = L1.elem[k++];
    }
    
}


void MSort(SqList L1, SqList L2, int i, int s, int t) { //递归归并排序的递归排序操作。这里是对L1进行排序如果i为奇数,排序后的记录储存在L2否则存进L1里
    int m;
    if (s == t) {  //终结条件
        if (i%2 == 1) {//奇数的话
            L2.elem[s] = L1.elem[s];
        }
    }
    else {
        m = (s + t) / 2;
        MSort(L1, L2, i + 1, s, m);//对前半部分递归排序
        MSort(L1, L2, i + 1, m+1, t);//对后半部分递归排序
        if (i % 2 == 1) {
            Merge(L1, L2, s, m, t);
        }
        else {
            Merge(L2, L1, s, m, t);
        }
    }
}

 

归并排序的递归实现

标签:pre   遍历   区间   length   define   排序   子序列   generate   void   

原文地址:http://www.cnblogs.com/wangshen31/p/7878674.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!