排序算法之七:归并排序(非递归)

简介: 排序算法之七:归并排序(非递归)

1.非递归实现思路

我们之前学习了递归实现的归并排序,是分治的思想,即先分解,再归并

这篇文章我们讲一下非递归的实现

非递归实现的思路是模拟递归的过程,在递归过程中,我们找key将数组分成左右数组,然后递归子数组,知道该数组剩一个元素,然后归并:两个两元素数组归并为四元素数组,两个四元素数字归并为八元素数组

而非递归的实现不需要递归子数组进行分解,我们可以将n个元素的数组看作n个数组,直接进行下面的合并

我们先设gap为1,表示先控制一个元素的数组进行归并,malloc一个临时数组tmp,归并到tmp数组;一整趟归并结束后gap*=2,同时将归并完成的数组拷贝到原数组,继续控制两元素的数组进行归并,直到gap>=n则停止归并,此时原数组已经有序了

2.图示归并

归并的过程和递归方式的归并排序一样

每次归并的时候,两个数组中找小的排到前面,排空一个数组之后将另外一个数组尾插到后面即可

3.代码展示

函数代码和测试代码如下

1. #define _CRT_SECURE_NO_WARNINGS 1
2. #include<stdio.h>
3. #include<stdlib.h>
4. #include<string.h>
5. void MergeSortNonR(int* a, int n)
6. {
7.  int* tmp = (int*)malloc(sizeof(int) * n);
8.  if (tmp == NULL)
9.  {
10.     perror("malloc fail!");
11.     return;
12.   }
13.   int gap = 1;//先控制一个一个归并
14.   while (gap < n)
15.   {
16.     for (int i = 0; i < n; i += 2 * gap)
17.     {
18.       int begin1 = i, end1 = i + gap - 1;
19.       int begin2 = i + gap, end2 = i + 2 * gap - 1;
20.       if (end1 >= n || begin2 >= n)
21.       {
22.         break;
23.       }
24.       if (end2 >= n)
25.       {
26.         end2 = n - 1;
27.       }
28.       int j = begin1;
29.       while (begin1 <= end1 && begin2 <= end2)
30.       {
31.         if (a[begin1] < a[begin2])
32.           tmp[j++] = a[begin1++];
33.         else
34.           tmp[j++] = a[begin2++];
35.       } //[begin1,end1][begin2,end2]归并->tmp[]
36.       while (begin1 <= end1)
37.         tmp[j++] = a[begin1++];
38.       while (begin2 <= end2)
39.         tmp[j++] = a[begin2++];
40.       memcpy(a + i, tmp + i, sizeof(int) * (end2 - i + 1));
41.     }
42.     gap *= 2;
43.   }
44.   free(tmp);
45. }
46. int main()
47. {
48.   int i = 0;
49.   int a[] = { 10,10,2,5,7,9,3,4,5,4,1,0 };
50.   int n = sizeof(a) / sizeof(a[0]);
51.   for (i = 0; i < n; i++)
52.   {
53.     printf("%d ", a[i]);
54.   }
55.   printf("\n");
56.   MergeSortNonR(a, n);
57.   for (i = 0; i < n; i++)
58.   {
59.     printf("%d ", a[i]);
60.   }
61.   return 0;
62. }


相关文章
|
算法 搜索推荐 Shell
数据结构与算法学习十二:希尔排序、快速排序(递归、好理解)、归并排序(递归、难理解)
这篇文章介绍了希尔排序、快速排序和归并排序三种排序算法的基本概念、实现思路、代码实现及其测试结果。
421 1
|
存储 搜索推荐 算法
【排序算法(二)】——冒泡排序、快速排序和归并排序—>深层解析
【排序算法(二)】——冒泡排序、快速排序和归并排序—>深层解析
|
存储 算法 搜索推荐
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
212 0
|
算法 搜索推荐 Java
算法实战:手写归并排序,让复杂排序变简单!
归并排序是一种基于“分治法”的经典算法,通过递归分割和合并数组,实现O(n log n)的高效排序。本文将通过Java手写代码,详细讲解归并排序的原理及实现,帮助你快速掌握这一实用算法。
113 0
|
搜索推荐 Java Go
深入了解归并排序算法
深入了解归并排序算法
263 0
|
存储 算法 搜索推荐
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
【7月更文挑战第12天】归并排序是高效稳定的排序算法,采用分治策略。Python 实现包括递归地分割数组及合并已排序部分。示例代码展示了如何将 `[12, 11, 13, 5, 6]` 分割并归并成有序数组 `[5, 6, 11, 12, 13]`。虽然 $O(n log n)$ 时间复杂度优秀,但需额外空间,适合大规模数据排序。对于小规模数据,可考虑其他算法。**
148 4
|
数据采集 搜索推荐 算法
【高手进阶】Java排序算法:从零到精通——揭秘冒泡、快速、归并排序的原理与实战应用,让你的代码效率飙升!
【8月更文挑战第21天】Java排序算法是编程基础的重要部分,在算法设计与分析及实际开发中不可或缺。本文介绍内部排序算法,包括简单的冒泡排序及其逐步优化至高效的快速排序和稳定的归并排序,并提供了每种算法的Java实现示例。此外,还探讨了排序算法在电子商务、搜索引擎和数据分析等领域的广泛应用,帮助读者更好地理解和应用这些算法。
176 0
|
搜索推荐 C语言
【C/排序算法】:快速排序和归并排序的非递归实现
【C/排序算法】:快速排序和归并排序的非递归实现
191 0
|
搜索推荐 算法
【C/排序算法】:归并排序和计数排序
【C/排序算法】:归并排序和计数排序
125 0

热门文章

最新文章

下一篇
oss云网关配置