C语言合并排序及实例代码_C 语言

归并排序也称合并排序,其算法思想是将待排序序列分为两部分,依次对分得的两个部分再次使用归并排序,之后再对其进行合并。仅从算法思想上了解归并排序会觉得很抽象,接下来就以对序列A[0], A[l]…, A[n-1]进行升序排列来进行讲解,在此采用自顶向下的实现方法。

操作步骤如下:

(1)将所要进行的排序序列分为左右两个部分,如果要进行排序的序列的起始元素下标为first,最后一个元素的下标为last,那么左右两部分之间的临界点下标mid=(first+last)/2,这两部分分别是A[first … mid]和A[mid+1 … last]。

(2)将上面所分得的两部分序列继续按照步骤(1)继续进行划分,直到划分的区间长度为1。

(3)将划分结束后的序列进行归并排序,排序方法为对所分的n个子序列进行两两合并,得到n/2或n/2+l个含有两个元素的子序列,再对得到的子序列进行合并,直至得到一个长度为n的有序序列为止。

下面通过一段代码来看如何实现归并排序。

#include <stdio.h>
#include <stdlib.h>
#define N 7
void merge(int arr[], int low, int mid, int high){
 int i, k;
 int *tmp = (int *)malloc((high-low+1)*sizeof(int));
 //申请空间,使其大小为两个
 int left_low = low;
 int left_high = mid;
 int right_low = mid + 1;
 int right_high = high;
 for(k=0; left_low<=left_high && right_low<=right_high; k++){ // 比较两个指针所指向的元素
  if(arr[left_low]<=arr[right_low]){
   tmp[k] = arr[left_low++];
  }else{
   tmp[k] = arr[right_low++];
  }
 }
 if(left_low <= left_high){ //若第一个序列有剩余,直接复制出来粘到合并序列尾
 //memcpy(tmp+k, arr+left_low, (left_high-left_low+l)*sizeof(int));
 for(i=left_low;i<=left_high;i++)
  tmp[k++] = arr[i];
 }
 if(right_low <= right_high){
 //若第二个序列有剩余,直接复制出来粘到合并序列尾
 //memcpy(tmp+k, arr+right_low, (right_high-right_low+1)*sizeof(int));
  for(i=right_low; i<=right_high; i++)
   tmp[k++] = arr[i];
 }
 for(i=0; i<high-low+1; i++)
  arr[low+i] = tmp[i];
 free(tmp);
 return;
}
void merge_sort(int arr[], unsigned int first, unsigned int last){
 int mid = 0;
 if(first<last){
  mid = (first+last)/2; /* 注意防止溢出 */
  /*mid = first/2 + last/2;*/
  //mid = (first & last) + ((first ^ last) >> 1);
  merge_sort(arr, first, mid);
  merge_sort(arr, mid+1,last);
  merge(arr,first,mid,last);
 }
 return;
}
int main(){
 int i;
 int a[N]={32,12,56,78,76,45,36};
 printf ("排序前 \n");
 for(i=0;i<N;i++)
  printf("%d\t",a[i]);
 merge_sort(a,0,N-1); // 排序
 printf ("\n 排序后 \n");
 for(i=0;i<N;i++)
  printf("%d\t",a[i]); printf("\n");
 system("pause");
 return 0;
}

运行结果:

排序前

32    12    56    78    76    45    36

排序后

12    32    36    45    56    76    78

分析上面的运行结果,通过归并排序成功地实现了对给定序列的排序操作。接下来通过图来了解归并排序的具体操作流程。

在下图先对所要进行排序的序列进行分解,直到分为单个元素为止,然后将其进行两两合并。由于最终分解成单个元素,因此在合并的时候.将小数放在前面,大数放在后面,得到一个有序序列。接下来对两个相连的有序序列进行排序,先比较有序序列中的第一个元素,将较小的元素放入临时数组中,接着将较小元素所在数组的下一个元素与另一个数组中的较小元素比较,同样将较小元素放入临时数组中,依次进行,直到两个数组的所有元素都放入临时数组中,最后再将临时数组的元素放入原始数组中的对应位置。

以上就是对合并排序的详细讲解,希望对你有帮助。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索C语言合并排序
合并排序详解
合并排序c语言、合并排序算法c语言、c语言冒泡排序、c语言排序、冒泡法排序 c语言,以便于您获取更多的相关知识。

时间: 2024-11-03 03:17:00

C语言合并排序及实例代码_C 语言的相关文章

C 语言插入排序算法及实例代码_C 语言

插入排序是排序算法的一种,它不改变原有的序列(数组),而是创建一个新的序列,在新序列上进行操作. 这里以从小到大排序为例进行讲解. 基本思想及举例说明 插入排序的基本思想是,将元素逐个添加到已经排序好的数组中去,同时要求,插入的元素必须在正确的位置,这样原来排序好的数组是仍然有序的. 在实际使用中,通常是排序整个无序数组,所以把这个无序数组分为两部分排序好的子数组和待插入的元素.第一轮时,将第一个元素作为排序好的子数组,插入第二个元素:第二轮,将前两个元素作为排序好的数组,插入第三个元素.以此类

C语言 奇偶排序算法详解及实例代码_C 语言

C语言奇偶排序算法 奇偶排序,或奇偶换位排序,或砖排序,是一种相对简单的排序算法,最初发明用于有本地互连的并行计算.这是与冒泡排序特点类似的一种比较排序.该算法中,通过比较数组中相邻的(奇-偶)位置数字对,如果该奇偶对是错误的顺序(第一个大于第二个),则交换.下一步重复该操作,但针对所有的(偶-奇)位置数字对.如此交替进行下去. 使用奇偶排序法对一列随机数字进行排序的过程 处理器数组的排序 在并行计算排序中,每个处理器对应处理一个值,并仅有与左右邻居的本地互连.所有处理器可同时与邻居进行比较.交

C语言选择排序算法及实例代码_C 语言

选择排序是排序算法的一种,这里以从小到大排序为例进行讲解. 基本思想及举例说明 选择排序(从小到大)的基本思想是,首先,选出最小的数,放在第一个位置:然后,选出第二小的数,放在第二个位置:以此类推,直到所有的数从小到大排序. 在实现上,我们通常是先确定第i小的数所在的位置,然后,将其与第i个数进行交换. 下面,以对 3  2  4  1 进行选择排序说明排序过程,使用min_index 记录当前最小的数所在的位置. 第1轮 排序过程 (寻找第1小的数所在的位置) 3  2  4  1(最初, m

C语言之单向链表详解及实例代码_C 语言

1,单向链简洁. 单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始:链表是使用指针进行构造的列表:又称为结点列表,因为链表是由一个个结点组装起来的:其中每个结点都有指针成员变量指列表中的下一个结点:列表是由结点构成,由head指针指向第一个成为表头的结点而终止于最后一个指向nuLL的指针: 2,例子要求: 根据示例代码中的例子,完成单向链表(single linked list)中的以字符串为数据的链表的插入.删除以及查找,并支持单向链表的反转

C 语言快速排序实例代码_C 语言

快速排序是对冒泡法排序的一种改进. 快速排序算法 的基本思想是:将所要进行排序的数分为左右两个部分,其中一部分的所有数据都比另外一 部分的数据小,然后将所分得的两部分数据进行同样的划分,重复执行以上的划分操作,直 到所有要进行排序的数据变为有序为止. 可能仅根据基本思想对快速排序的认识并不深,接下来以对n个无序数列A[0], A[1]-, A[n-1]采用快速排序方法进行升序排列为例进行讲解. (1)定义两个变量low和high,将low.high分别设置为要进行排序的序列的起始元素和最后一个元

c语言实现输入一组数自动从大到小排列的实例代码_C 语言

如下所示: #include <stdio.h> main() { int x; printf("请输入要排序数字个数:"); scanf("%d",&x); int i,j,k,a,b,num[x]; printf("输入数据:"); for(i=0;i<x;i++) scanf("%d",&num[i]); for(j=0;j<x;j++) { for(k=j+1;k<x;k+

C语言之实现控制台光标随意移动的实例代码_C 语言

原理引入windows.h,首先是要获得输入的东西,然后通过判断: 1.方向键:执行上下左右的移动功能 2 .回车键:执行换行的功能. 3.普通键:输入功能. 终点就是要获取到屏幕上的坐标,当按下了方向键以后,坐标值+1,或者减一,从而实现了光标的自由移动. //C语言实现控制台中光标随意移动 #include <stdio.h> #include <windows.h> #include <conio.h> HANDLE hout; //获得输入 char getIn

C语言之双向链表详解及实例代码_C 语言

1,双向链表简介. 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱.所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点.一般我们都构造双向循环链表. 2,例子要求: 完成双向链表的插入.删除以及查找,将学生管理系统使用的数组,以双向链表的方式实现,能够支持无限制的学生人数的增删改查以及保存. 3,代码实现. #include <stdio.h> #include <string.h> #include <

使用C++的string实现高精度加法运算的实例代码_C 语言

对于超大数字的运算,用long long int仍然不能解决,这时候就需要考虑通过模拟运算和数组存储来实现高精度运算. 本文讨论借助C++的string来实现高精度的运算. 首先输入的量直接存储为string,设为s1和s2. 接下来设计一个反转函数,用于把整个字符串反转(为了方便后续计算). string reverseStr(string input){ string output = ""; for(int i = 0; i < input.length(); i++){