非递归形式归并排序c语言,归并排序(非递归) ----- C语言

归并排序(Merge sort,台湾译做:合并排序)是创建在归并操做上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个很是典型的应用。算法

算法步骤:数组

1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列ide

2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置函数

3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置spa

4. 重复步骤3直到某一指针达到序列尾指针

5. 将另外一序列剩下的全部元素直接复制到合并序列尾code

9d6a69c65fef46152e2f53d3737e0018.png

以上理论归理论,代码要实现其实仍是有难度的,本身搞了好久才基本弄清楚非递归的归并排序的基本思想,查阅许久才看懂代码,本身简单地实现了一下:blog

#define A_LENGTH 10

#include

#include

int MergeSort(int *a)

{

int k = 1;/*k用来表示每次k个元素归并*/

int *temp = (int *)malloc(sizeof(int) * A_LENGTH);

while (k < A_LENGTH)

{

//k每次乘以2是遵循1->2->4->8->16的二路归并元素个数的原则

MergePass(a, temp, k, A_LENGTH);/*先借助辅助空间归并*/

k *= 2;

MergePass(temp, a, k, A_LENGTH);/*再从辅助空间将排过序的序列归并回原数组*/

k *= 2;

}

}

int MergePass(int *S, int *T, int times, int length)

{

int i = 0, s = times, l;

while ((i + 2*s - 1) < length)

{

Merge(S, T, i, i+s-1, i+2*s-1);

i += 2*s;

}/*此处的循环用于遍历数组所有元素并依照k(此处为赋值为s)来归并入辅助的数组空间中*/

/*if-else用于处理归并剩下的序列,由于已经不知足(i + 2*s - 1) < length的条件

* 因此须要修改Merge()函数的下标,而若是知足(i + s - 1) < length即表示

* i 到 i + s - 1 这段序列为归并的第一段,剩下一段为 i + s 到 length - 1,

* 而若是不知足if条件则说明剩下序列已经有序,直接循环赋值给目标数组便可

*/

if ((i + s - 1) < length)

{

Merge(S, T, i, i+s-1, length-1);

}

else

{

for (l = i; l < length; l++)

{

T[l] = S[l];

}

}

}

//归并排序最主要实现函数

int Merge(int *S, int *T, int low, int m, int high)

{//j在[m+1,high]区间递增,k用于目标T的下标递增, l是辅助变量

int j, k, l;

for (k = low, j = m+1;

low <= m && j <= high;

k++)

{

if (S[low] < S[j])

{

T[k] = S[low++];//此处先执行T[k] = S[low],而后low++;

}

else

{

T[k] = S[j++];//同理

}

}

//for循环事后,必然有low>m 或者 j>high,故分状况处理

if (low <= m)

{

for (l = 0; l <= m-low; l++)

{

T[k+l] = S[low+l];

}

}

if (j <= high)

{

for (l = 0; l <= high-j; l++)

{

T[k+l] = S[j+l];

}

}

}

int main()

{

int i;

int a[A_LENGTH] = {50, 90, 80, 40, 30,

120, 150, 200, 70, 60};

printf("Before sorting:");

for (i = 0; i < A_LENGTH; i++)

{

printf("%d -- ", a[i]);

}

MergeSort(a);

printf("\n\nAfter sorting: ");

for (i = 0; i < A_LENGTH; i++)

{

printf("%d -- ", a[i]);

}

return 0;

}

d377d51fb64ccffafc8a73cc089f76ad.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值