合并排序

   合并排序是一个O(nlogn)的算法,其基本思想就是一个分治的策略,先进行划分,然后再进行合并,下面举个例子。

   有这样一组数据,{5,4,1,22,12,32,45,21},如果对它进行合并排序的话,首先将它从中间分开,这样,它就被分成了两个数组{5,4,1,22} {12,32,45,21}.

对这两个数组,也分别进行这样的操作,逐步的划分,直到不能再划分为止(每个子数组只剩下一个元素),这样,划分的过程就结束了。

划分的过程如下图所示:

 

 

  接下来,我们进行合并操作,依照上图,划分过程是从上到下进行的,而合并的过程是从下往上进行的,例如上图中,最下层{5},{4}这两个数组,如果按升序排列,将他们合并后的数组就是{4,5}。{1},{22}这两个子数组合并后是{1,22}。而{4,5}与{1,22},这两个数组同属一个分支,他们也需要进行合并,由于这两个子数组本身就是有序的,所以合并的过程就是,每次从待合并的两个子数组中选取一个最小的元素,然后把这个元素放到合并后的数组中,前面两个数组合并后就是{1,4,5,22}。依次类推,直到合并到最上层结束,这是数据的排序已经完成了。

合并的过程如下图所示。这个过程是从下往上的。

 

C语言实现代码如下:

复制代码
 1#include <stdlib.h>
 2
 3//合并过程
 4void merge(int data[],int start,int mid,int end){
 5
 6
 7    int *tmpLeft,*tmpRight;
 8    int leftSize,rightSize;
 9    int l,r,j;
10
11    printArray(data,8);
12    printf("\n");
13    l = 0;
14    r = 0;
15    j = 0;
16    leftSize = mid - start + 1;
17    rightSize = end - mid;
18
19    tmpLeft = (int *)malloc(leftSize * sizeof(int));
20    tmpRight = (int *)malloc(rightSize * sizeof(int));
21
22    while(j < leftSize){
23        tmpLeft[j] = data[start + j];
24        j++;
25    }

26
27    j = 0;
28
29    while(j < rightSize){
30        tmpRight[j] = data[mid + 1 + j];
31        j++;
32    }

33
34    j = 0;
35
36    while(l < leftSize && r < rightSize){
37        if(tmpLeft[l] < tmpRight[r]){
38
39            data[start + j++= tmpLeft[l++];
40
41        }
else{
42        
43            data[start + j++= tmpRight[r++];
44        }
        
45    }

46
47    while(l < leftSize){
48        data[start + j++= tmpLeft[l++];
49    }

50
51    while(r < rightSize){
52        data[start + j++= tmpRight[r++];
53    }

54
55    free(tmpLeft);
56    free(tmpRight);
57}

58
59
60void merge_sort(int data[],int start,int end){
61
62    int mid;
63    if(start < end){
64        //将数组划分
65        mid = (start + end) / 2;
66        merge_sort(data,start,mid);
67        merge_sort(data,mid + 1,end);
68        //合并划分后的两个数组
69        merge(data,start,mid,end);
70    }

71
72}
复制代码

 

 

posted @   Springfield  阅读(3233)  评论(14编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
点击右上角即可分享
微信分享提示