思路图来自: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); } } }
时间: 2024-10-14 21:50:20