[C语言] 归并排序的特性及实现

[C语言] 归并排序的特性及实现

1、算法特性

  归并排序是一种高效且稳定的排序方法,其速度仅次于快速排序,但比较占用内存。

  其时间复杂度最好、最差、平均情况均为O(nlog(2)n),空间复杂度为O(n)。

2、算法思路

  采用分治法的思路将问题分解、细化、逐个解决,即通过递归将无序序列不断分解,直到分解成序列有序(当序列长度为1时一定有序)。再将分解的有序序列不断合并成新的有序序列,最后合并成一个有序序列。

3、实现代码

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3
 4 // 归并排序:arr  [left,mid]区间升序  [mid+1,rigth]升序   合并这个数组的数据使之升序
 5 void merge(int arr[],int left,int mid,int rigth)
 6 {
 7     int len = mid-left+1;
 8     int* p = malloc(sizeof(int)*len);
 9     // 把[left,mid-1]区间的数据移动到p指向的内存
10     // memcpy(prr,arr+left,l1*sizeof(int));
11     for(int i=0; i<len; i++)
12     {
13         p[i] = arr[left+i];
14     }
15     // 把p[0,len-1]  arr[mid,rigth]两部分数据合并到 arr[left,rigth]数组里
16     int i = 0;
17     int j = mid+1;
18     int k = left; // 从left开始放
19     while(i<len && j<=rigth)
20     {
21         if(p[i] < arr[j])
22         {
23             arr[k++] = p[i++];
24         }
25         else
26         {
27             arr[k++] = arr[j++];
28         }
29     }
30     while(i < len)
31     {
32         arr[k++] = p[i++];
33     }
34 }
35
36 // 通铺使arr left-rigth区间有序
37 void _merge_sort(int arr[],int left,int rigth)
38 {
39     if(left >= rigth) // 只有一个数据  那本来就有序
40     {
41         return;
42     }
43     int mid = (left+rigth)/2;
44     // left mid   mid+1 rigth
45     if(mid > left)
46     {
47         _merge_sort(arr,left,mid); // 让数组 [left,mid]有序
48     }
49     if(rigth > mid+1)
50     {
51         _merge_sort(arr,mid+1,rigth); // 让数组  [mid+1,rigth]有序
52     }
53     merge(arr,left,mid,rigth); // 合并
54 }
55
56 void merge_sort(int arr[],int len)
57 {
58     _merge_sort(arr,0,len-1);
59 }
60
61 void travel(int arr[],int len)
62 {
63     for(int i=0; i<len; i++)
64     {
65         printf("%d ",arr[i]);
66     }
67     printf("\n");
68 }
69
70 int main()
71 {
72     int arr[] = {53,82,9,233,43,14,55,9,4,67};
73     int len = sizeof(arr)/sizeof(arr[0]);
74
75     travel(arr,len);
76     merge_sort(arr,len);
77     travel(arr,len);
78
79     return 0;
80 }

4、测试结果

原文地址:https://www.cnblogs.com/usingnamespace-caoliu/p/9433826.html

时间: 2024-08-03 05:45:47

[C语言] 归并排序的特性及实现的相关文章

Object-C中一些不同于C系列语言表现的特性

这段时间体验和学习OC,虽然这么多年基本都在使用C系列语言(C,C++,C#),但是仍然有很多的不习惯. 当然,这些不习惯不代表讨厌或者不好,也许这些就是OC作为Apple开发首选语言而显得特殊的一些原因吧.下面列举一下主要的不习惯: 1. 称调用对象的方法为向对象发送消息.这两者的仔细理解是一致的概念,都是对象1委托对象2做某件事情,至于对象2怎么做,对象1不管. 2. 方括号表达方式,替代了这些年相濡以沫的点和箭头语法.当然APPLE提供了类似的语法来让C系列开发者习惯旧的方式,但是我认为既

Java语言类的特性

一.内容的概述(主要内容) *类的私有成员和公共成员 *方法的重载 *构造方法 *类的静态方法 *对象的应用 二.类的私有成员和公有成员 私有成员:加private访问控制修饰符 公有成员:加public访问控制修饰符 如果没有一个机制来限制对类中成员的访问,则很有可能会造成错误的输入.为了防止这样的情况发生,Java语言提供了私有成员访问控制修饰符private..也就是说,如果在类的成员声明前加上修饰符private,则就无法从该类的外部访问到该类内部的成员,而只能通过该类自身访问和修改,而

Java学习的随笔(2)Java语言的三大特性

1.面向对象的三大特性 面向对象的三大特性主要包括:继承.封装.多态 (1)继承:就是指子类(导出类)获得了基类的全部功能(所有的域和方法).  注:在子类中,想要调用基类的方法可以使用“super.方法名”来调用. 术语:继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法.对象的一个新类可以从现有的类中派生,这个过程称为类继承.新类继 承了原始类的       特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类).派生类可以从它的基类那里继承方法

C# 语言历史版本特性(C# 1.0到C# 7.1汇总更新)

历史版本 C#作为微软2000年以后.NET平台开发的当家语言,发展至今具有17年的历史,语言本身具有丰富的特性,微软对其更新支持也十分支持.微软将C#提交给标准组织ECMA,C# 5.0目前是ECMA发布的最新规范,C# 6.0还是草案阶段,C# 7.1是微软当前提供的最新规范. 这里仅仅列个提纲,由于C# 5.0是具有ECMA标准规范的版本,所以选择C# 5.0作为主要版本学习,并专题学习C# 6.0,7.0版本新特性. C#语言规范GitHub库参见:https://github.com/

C# 语言历史版本特性(C# 1.0到C# 8.0汇总)

历史版本 C#作为微软2000年以后.NET平台开发的当家语言,发展至今具有17年的历史,语言本身具有丰富的特性,微软对其更新支持也十分支持.微软将C#提交给标准组织ECMA,C# 5.0目前是ECMA发布的最新规范,C# 6.0还是草案阶段,C# 7.1是微软当前提供的最新规范. 这里仅仅列个提纲,由于C# 5.0是具有ECMA标准规范的版本,所以选择C# 5.0作为主要版本学习,并专题学习C# 6.0,7.0版本新特性. C#语言规范GitHub库参见:https://github.com/

Rust语言的一些特性(基于表达式的系统编程语言?)

1.let mut x = 10i; 用学术的话来说,let代表文法级别的名字绑定(到value对象) println!是宏,第一眼看到它时还以为是学习Ruby,!代表函数有副作用呢 destructuring let:解构绑定这个概念来自于LISP/Erlang? 2.表达式语言:if是表达式:加上分号就变成语句:return x;等同于直接的一个x 还有,它的if/for/while的条件判断不用加()圆括号,这跟Swift是一致的(就是感觉有点别扭) 3.函数原型:fn f(x: int,

C语言归并排序

这篇文章是学习了小甲鱼-数据结构与算法结合自考教材编写出的代码,希望自己逐渐在算法造诣上能更上一层楼. 归并排序(递归实现) “归并”一词在中文含义中就是合并的意思,而在数据结构中的定义是将两个或者两个以上的有序表组合成一个新的有序表,就叫归并. 归并排序(Merge Sort)就是利用归并的思想实现的排序方法.它的原理是假设初始序列有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到⌈n/2⌉个长度为2或1的有序子序列:再两两归并,……,如此重复,直至得到一个长度

C语言归并排序(合并排序)算法及代码

归并排序也称合并排序,其算法思想是将待排序序列分为两部分,依次对分得的两个部分再次使用归并排序,之后再对其进行合并.仅从算法思想上了解归并排序会觉得很抽象,接下来就以对序列A[0], A[l]-, A[n-1]进行升序排列来进行讲解,在此采用自顶向下的实现方法,操作步骤如下. (1)将所要进行的排序序列分为左右两个部分,如果要进行排序的序列的起始元素下标为first,最后一个元素的下标为last,那么左右两部分之间的临界点下标mid=(first+last)/2,这两部分分别是A[first -

lua语言三则特性

pack和unpack 对于一个函数, 要将其入参转换为一个表, 则pack函数合适. 对于一个表要将其转换为 一个函数的入参, 则 lua原生提供的 unpack函数可以实现. do arrayData = {"a", "b", "c", "d", "e"}; function pack(...) return {...}; end print( pack("aa", "bb