归并排序的实现
来源:互联网 发布:windows 10 蓝牙丢失 编辑:程序博客网 时间:2024/06/04 19:27
归并排序的时间复杂度和快排还有堆排序是一样的,归并排序利用了分治的思想,它的核心就是将两个有序的数组合并,那么我们怎么得到这两个有序的数组呢,就是将这两个数组再分为小的数组,由小的数组合并而成,是不是有种递归的赶脚?对了,归并就是,递归+合并
算法的框架像这样的:
void merge_sort(int a[], int l, int r, int temp[]){ if(l < r) { int mid = (l + r)/2; merge_sort(a, l, mid, temp);//递归 merge_sort(a, mid+1, r, temp);//递归 merge_array(a, l, mid, r, temp);//合并 }}就像这样的一个数组:(图片摘自唐苏:http://hi.baidu.com/tangsu2009/item/b74e66a7b07a19228919d3f6)
自己实现的代码如下:
/****************merge_sort.c made by cfmlovers************/#include <stdio.h>#define ARRAYSIZE 4merge_array(int a[], int l, int mid, int r, int temp[]){ int i = l, j = mid+1, k = 0; while(i <= mid && j <= r) { if(a[i] < a[j]) temp[k++] = a[i++]; else temp[k++] = a[j++]; } while(i <= mid) temp[k++] = a[i++]; while( j <= r) temp[k++] = a[j++]; for(i = 0; i < k; i++) a[i+l] = temp[i];}void merge_sort(int a[], int l, int r, int temp[]){ if(l < r) { int mid = (l + r)/2; merge_sort(a, l, mid, temp); merge_sort(a, mid+1, r, temp); merge_array(a, l, mid, r, temp); }}void main(){ int a[ARRAYSIZE], i; printf("please input 4 numbers\n"); for(i = 0; i < 4; i++) scanf("%d",&a[i]); int temparray[ARRAYSIZE]; /*merge sort*/ merge_sort(a, 0, ARRAYSIZE-1, temparray); for(i = 0; i < 4; i++) printf("%d\n", a[i]);}
刚才说递归利用了分治的思想,我们的递归框架中先把整个数组分为两个部分,然后在各个部分继续分为两个部分,就像上面的那张图片,分到最后只剩一个数的数组的时候就是有序的了,然后向上合并,每一次都是合并有序的数组,这是一个自上而下分治,然后合并的过程
那么非递归如何实现呢?其实是一个逆过程,我们可以自下而上分治,然后合并
代码实现如下:
void merge_sort(int a[], int length, int *temp){ int i, left_min, left_max, right_min, right_max, next; for(i = 1; i < length; i*=2)//自下向上分治,步长为1、2、4、8 { for(left_min = 0; left_min < length - i; left_min = right_max) { right_min = left_max = left_min + i;//需要注意的是left_max = right_min right_max = left_max + i; if(right_max > length) right_max = length; next = 0; while(left_min < left_max && right_min < right_max)//此处是<,所以上面for里面是left_min = right_max temp[next++] = a[left_min] > a[right_min] ?a[right_min++]: a[left_min++]; while(left_min < left_max) a[--right_min] = a[--left_max]; while(next > 0) a[--right_min] = temp[--next]; } }}
贵并排序的时间分为两个部分,分治,类似一个二分法查找,时间复杂度O(logn),合并的时候时间是O(n),总的时间就是O(nlogn),是一个稳定的排序算法,
最差,平均,最好时间都是O(nlogn)
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- empty和isset误点分析
- create_proc_read_entry中函数的说名
- Android网络通信的六种方式示例代码
- 某APK中使用了动态注册BroadcastReceiver,Launcher中动态加载此APK出现java.lang.SecurityException异常的解决方法
- Hibernate查询的各种方式效率比较
- 归并排序的实现
- 吝啬的国度
- 在Myeclipse buildpath 加server lib (server runtime)
- 改变UIImage 的大小 强制改变服务器请求下来的的图片的大小
- python脚本放到linux的cgi-bin下出现Premature end of script headers问题
- Struts1.x中的令牌(Token)使用
- LeakDiag
- 使用lock_sga和pre_page_sga参数保证SGA常驻物理内存 .
- POJ 1895 Bring Them There 分层构图 求最大流 并输出路径