c语言合并排序算法

Merge Sort follows the rule of Divide and Conquer to sort a given set of numbers/elements, recursively, hence consuming less time.

合并排序遵循分而治之的规则,以递归方式对一组给定的数字/元素进行排序,从而减少了时间。

In the last two tutorials, we learned about Selection Sort and Insertion Sort, both of which have a worst-case running time of O(n2). As the size of input grows, insertion and selection sort can take a long time to run.

在最后的两个教程中,我们了解了选择排序和插入排序,这两个类的最坏运行时间均为O(n 2 ) 。 随着输入大小的增长,插入和选择排序可能需要很长时间才能运行。

Merge sort , on the other hand, runs in O(n*log n) time in all the cases.

另一方面,合并排序在所有情况下均以O(n*log n)时间运行。

Before jumping on to, how merge sort works and it's implementation, first lets understand what is the rule of Divide and Conquer?

在继续之前,合并排序如何工作及其实现,首先让我们了解分而治之的规则是什么?

分而治之 (Divide and Conquer)

If we can break a single big problem into smaller sub-problems, solve the smaller sub-problems and combine their solutions to find the solution for the original big problem, it becomes easier to solve the whole problem.

如果我们可以将一个大问题分解为较小的子问题,解决较小的子问题,然后将它们的解决方案结合起来以找到原始大问题的解决方案,那么解决整个问题就变得更加容易。

Let's take an example, Divide and Rule.

让我们以Divide and Rule为例。

When Britishers came to India, they saw a country with different religions living in harmony, hard working but naive citizens, unity in diversity, and found it difficult to establish their empire. So, they adopted the policy of Divide and Rule. Where the population of India was collectively a one big problem for them, they divided the problem into smaller problems, by instigating rivalries between local kings, making them stand against each other, and this worked very well for them.

当英国人来到印度时,他们看到一个宗教信仰不同的国家和睦相处,工作勤奋但天真的公民,多元而团结,发现很难建立自己的帝国。 因此,他们采取了分而治之的政策。 在印度人口集体对他们来说是一个大问题的地方,他们通过煽动地方国王之间的对抗,使他们相互对抗,将问题分为较小的问题,这对他们来说非常有效。

Well that was history, and a socio-political policy (Divide and Rule), but the idea here is, if we can somehow divide a problem into smaller sub-problems, it becomes easier to eventually solve the whole problem.

那是历史,是一项社会政治政策(“ 分而治之” ),但是这里的想法是,如果我们能够以某种方式将一个问题分解为较小的子问题,则最终解决整个问题变得更加容易。

In Merge Sort, the given unsorted array with n elements, is divided into n subarrays, each having one element, because a single element is always sorted in itself. Then, it repeatedly merges these subarrays, to produce new sorted subarrays, and in the end, one complete sorted array is produced.

Merge Sort中 ,给定的具有n元素的未排序数组被划分为n个子数组,每个子数组都有一个元素,因为单个元素始终在自身中进行排序。 然后,它反复合并这些子数组,以生成新的排序后的子数组,最后生成一个完整的排序后的数组。

The concept of Divide and Conquer involves three steps:

分而治之的概念涉及三个步骤:

  1. Divide the problem into multiple small problems.

    鸿沟的问题分成多个小的问题。

  2. Conquer the subproblems by solving them. The idea is to break down the problem into atomic subproblems, where they are actually solved.

    通过解决他们征服的子问题。 想法是将问题分解为原子子问题,并在其中实际解决。

  3. Combine the solutions of the subproblems to find the solution of the actual problem.

    结合子问题的解决方案以找到实际问题的解决方案。

合并排序如何工作? (How Merge Sort Works?)

As we have already discussed that merge sort utilizes divide-and-conquer rule to break the problem into sub-problems, the problem in this case being, sorting a given array.

正如我们已经讨论的那样,合并排序利用分而治之的规则将问题分解为子问题,在这种情况下,问题是对给定数组进行排序

In merge sort, we break the given array midway, for example if the original array had 6 elements, then merge sort will break it down into two subarrays with 3 elements each.

在归并排序中,我们将给定的数组中途中断,例如,如果原始数组有6元素,则归并排序会将其分解为两个每个具有3元素的子数组。

But breaking the orignal array into 2 smaller subarrays is not helping us in sorting the array.

但是将原始数组分成2个较小的子数组并不能帮助我们对数组进行排序。

So we will break these subarrays into even smaller subarrays, until we have multiple subarrays with single element in them. Now, the idea here is that an array with a single element is already sorted, so once we break the original array into subarrays which has only a single element, we have successfully broken down our problem into base problems.

因此,我们将把这些子数组分解为更小的子数组 ,直到我们拥有多个包含单个元素的数组 。 现在,这里的想法是已经对具有单个元素的数组进行了排序,因此一旦将原始数组分解为仅具有单个元素的子数组,我们就可以成功地将问题分解为基本问题。

And then we have to merge all these sorted subarrays, step by step to form one single sorted array.

然后,我们必须逐步合并所有这些排序后的子数组,以形成一个单独的排序后的数组。

Let's consider an array with values {14, 7, 3, 12, 9, 11, 6, 12}

让我们考虑一个值{14, 7, 3, 12, 9, 11, 6, 12} 14,7,3,12,9,9,11,6,12 {14, 7, 3, 12, 9, 11, 6, 12}的数组

Below, we have a pictorial representation of how merge sort will sort the given array.

下面,我们以图形方式表示合并排序将如何对给定数组进行排序。

In merge sort we follow the following steps:

在合并排序中,我们遵循以下步骤:

  1. We take a variable p and store the starting index of our array in this. And we take another variable r and store the last index of array in it.

    我们采用变量p并在其中存储数组的起始索引。 然后,我们使用另一个变量r并将数组的最后一个索引存储在其中。

  2. Then we find the middle of the array using the formula (p + r)/2 and mark the middle index as q, and break the array into two subarrays, from p to q and from q + 1 to r index.

    然后,我们使用公式(p + r)/2找到数组的中间,并将中间索引标记为q ,然后将该数组分为两个子数组,从pq和从q + 1r索引。

  3. Then we divide these 2 subarrays again, just like we divided our main array and this continues.

    然后,我们再次划分这2个子数组,就像划分主数组一样,这种情况将继续。

  4. Once we have divided the main array into subarrays with single elements, then we start merging the subarrays.

    一旦将主数组划分为具有单个元素的子数组,我们便开始合并子数组。

实现合并排序算法 (Implementing Merge Sort Algorithm)

Below we have a C program implementing merge sort algorithm.

下面我们有一个实现合并排序算法的C程序。

/*  a[] is the array, p is starting index, that is 0, and r is the last index of array.
*/#include <stdio.h>// lets take a[5] = {32, 45, 67, 2, 7} as the array to be sorted.// merge sort function
void mergeSort(int a[], int p, int r)
{int q;if(p < r){q = (p + r) / 2;mergeSort(a, p, q);mergeSort(a, q+1, r);merge(a, p, q, r);}
}// function to merge the subarrays
void merge(int a[], int p, int q, int r)
{int b[5];   //same size of a[]int i, j, k;k = 0;i = p;j = q + 1;while(i <= q && j <= r){if(a[i] < a[j]){b[k++] = a[i++];    // same as b[k]=a[i]; k++; i++;}else{b[k++] = a[j++];}}while(i <= q){b[k++] = a[i++];}while(j <= r){b[k++] = a[j++];}for(i=r; i >= p; i--){a[i] = b[--k];  // copying back the sorted list to a[]}
}// function to print the array
void printArray(int a[], int size)
{int i;for (i=0; i < size; i++){printf("%d ", a[i]);}printf("\n");
}int main()
{int arr[] = {32, 45, 67, 2, 7};int len = sizeof(arr)/sizeof(arr[0]);printf("Given array: \n");printArray(arr, len);// calling merge sortmergeSort(arr, 0, len - 1);printf("\nSorted array: \n");printArray(arr, len);return 0;
}

Given array: 32 45 67 2 7 Sorted array: 2 7 32 45 67

给定数组:32 45 67 2 7排序数组:2 7 32 45 67

合并排序的复杂度分析 (Complexity Analysis of Merge Sort)

Merge Sort is quite fast, and has a time complexity of O(n*log n). It is also a stable sort, which means the "equal" elements are ordered in the same order in the sorted list.

合并排序非常快,并且时间复杂度为O(n*log n) 。 这也是一种稳定的排序方式,这意味着“相等”元素在排序列表中的排序顺序相同。

In this section we will understand why the running time for merge sort is O(n*log n).

在本节中,我们将理解为什么合并排序的运行时间为O(n*log n)

As we have already learned in Binary Search that whenever we divide a number into half in every stpe, it can be represented using a logarithmic function, which is log n and the number of steps can be represented by log n + 1(at most)

正如我们在二元搜索中所学到的,每当我们在每个stpe中将数字分为一半时,就可以使用对数函数来表示,即log n ,步数可以由log n + 1表示(最多)

Also, we perform a single step operation to find out the middle of any subarray, i.e. O(1).

同样,我们执行一步操作来找出任何子数组的中间,即O(1)

And to merge the subarrays, made by dividing the original array of n elements, a running time of O(n) will be required.

为了合并通过划分n元素的原始数组而形成的子数组,将需要O(n)的运行时间。

Hence the total time for mergeSort function will become n(log n + 1), which gives us a time complexity of O(n*log n).

因此, mergeSort函数的总时间将变为n(log n + 1) ,这使我们的时间复杂度为O(n*log n)

Worst Case Time Complexity [ Big-O ]: O(n*log n)

最坏情况下的时间复杂度[Big-O]: O(n * log n)

Best Case Time Complexity [Big-omega]: O(n*log n)

最佳情况下的时间复杂度[Big-Omega]: O(n * log n)

Average Time Complexity [Big-theta]: O(n*log n)

平均时间复杂度[Big-theta]: O(n * log n)

Space Complexity: O(n)

空间复杂度: O(n)

  • Time complexity of Merge Sort is O(n*Log n) in all the 3 cases (worst, average and best) as merge sort always divides the array in two halves and takes linear time to merge two halves.

    在所有3种情况下(最差,平均和最佳),合并排序的时间复杂度均为O(n*Log n) ,因为合并排序始终数组分为两半,并花费线性时间来合并两半。

  • It requires equal amount of additional space as the unsorted array. Hence its not at all recommended for searching large unsorted arrays.

    它需要与未排序数组相等数量的额外空间 。 因此,完全不建议搜索大型未排序的数组。

  • It is the best Sorting technique used for sorting Linked Lists.

    这是用于对链表进行排序的最佳排序技术。

翻译自: https://www.studytonight.com/data-structures/merge-sort

c语言合并排序算法

c语言合并排序算法_合并排序算法相关推荐

  1. 【Matlab】智能优化算法_蜻蜓优化算法DA

    [Matlab]智能优化算法_蜻蜓优化算法DA 1.背景介绍 2.灵感 3.公式推导 3.1 勘探和开发操作 4.算法流程图 5.文件结构 6.伪代码 7.详细代码及注释 7.1 DA.m 7.2 d ...

  2. 【Matlab】智能优化算法_蚁狮优化算法ALO

    [Matlab]智能优化算法_蚁狮优化算法ALO 1.背景介绍 2.基本思想 3.公式推导 3.1 ALO算法的运算符 3.2 蚂蚁的随机游动 3.3 困在蚂蚁坑里 3.4 修建陷阱 3.5 蚂蚁划向 ...

  3. 【Matlab】智能优化算法_灰狼优化算法GWO

    [Matlab]智能优化算法_灰狼优化算法GWO 1.背景介绍 2.基本思想 2.1 等级制度 2.2 狩猎方式 3.公式推导 3.1 社会等级制度 3.2 包围猎物 3.3 包围猎物 3.4 攻击猎 ...

  4. 合并排序算法排序过程_合并排序| 用于大型输入的最佳排序算法之一

    合并排序算法排序过程 What is sorting? 什么是分类? Sorting allows us to process our data in a more organized and eff ...

  5. java常见的排序算法_常见排序算法及Java实现

    先上个总图↓: ①.直接插入排序 插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法.它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并 ...

  6. 解释什么是快速排序算法?_解释排序算法

    解释什么是快速排序算法? Sorting algorithms are a set of instructions that take an array or list as an input and ...

  7. 常见排序算法_解释的算法-它们是什么以及常见的排序算法

    常见排序算法 In its most basic form, an algorithm is a set of detailed step-by-step instructions to comple ...

  8. 会排序吗_洗牌算法详解:你会排序,但你会打乱吗?

    预计阅读时间: 8 分钟 我知道大家会各种花式排序,但是如果叫你打乱一个数组,你是否能做到胸有成竹?即便你拍脑袋想出一个算法,怎么证明你的算法就是正确的呢?乱序算法不像排序算法,结果唯一可以很容易检验 ...

  9. raptor五个数排序流程图_数据结构与算法(一):排序(上)

    做这个系列一是记录自己的学习过程,二是整合目前我所接触的比较好的资料,给出最直观,最通俗的算法解释 总体概况 十大排序算法:(比较排序):冒泡.选择.插入.归并.快速.希尔.堆排序 基数排序.桶排序. ...

最新文章

  1. 网络高可用性之流量镜像和端口流量控制
  2. 数据库笔记1:数据库基本语句
  3. (一) 自带刷新的列表-LtRecyclerView v2.x版本(LtAdapter)(基本使用)
  4. 中国碳酸氢钠干粉灭火剂市场产量规模与未来竞争走势研究报告2022年
  5. 2022-2028年中国医疗器械行业战略运营模式与典型案例分析报告
  6. php弱类型变量是什么,php弱类型变量如何实现?
  7. 重磅!阿里开源自研语音识别模型DFSMN,准确率高达96.04%
  8. 【Python7】csv/excel/matplotlib,排序/树遍历,线/进程,文件/xml操作,百度人脸API,aiohttp/hal/restful/curl
  9. web 后台返回json格式数据的方式(status 406)
  10. 送给微软中文.NET社区的一份礼物,.NET FM
  11. DDD领域模型自动生成?
  12. netapp存储常用命令
  13. 使用函数输出水仙花数
  14. java 基础知识面试题(持续更新),java基础面试笔试题
  15. JS对数据进行判空操作
  16. 实战分析PHP大马隐藏后门——案例二
  17. SogouLabDic搜狗词库
  18. grads 读取shp
  19. sublime php code sniffer,Sublime插件CodeSniffer配置
  20. easypoi.excel 导入不固定的合并单元格数据

热门文章

  1. 法国巴黎高等计算机学院世界排名,2018巴黎第十一大学世界排名
  2. 选择进口血糖仪的几个小建议,可收藏
  3. 保护公民个人信息,法不容缓
  4. idea的maven项目修改java代码重启后无效
  5. 不找IT男孩做老公的理由
  6. 求最大子数组和(数据结构和算法C++)
  7. 北斗定位背后的数学秘密
  8. CH340/CH341安卓应用开发指南
  9. 2015微信文案策划全集 热门微信文案策划分享 微信策划
  10. 做真实的自己:不要试图让太多人喜欢你