算法基础:归并排序算法原理与实现
2017-02-24 17:07
155 查看
归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,归并排序将两个已排序的表合并成一个表。
归并排序基本原理
通过对若干个有序结点序列的归并来实现排序。所谓归并是指将若干个已排好序的部分合并成一个有序的部分。
归并排序基本思想
将待排序序列R[0...n-1]看成是n个长度为1的有序序列,将相邻的有序表成对归并得到n/2个长度为2的有序表
将这些有序序列再次归并,得到n/4个长度为4的有序序列
如此反复进行下去,最后得到一个长度为n的有序序列。
在具体的合并过程中,设置 i,j 和 p 三个指针,其初值分别指向这三个记录区的起始位置。合并时依次比较 array[i] 和 array[j] 的关键字,取关键字较小(或较大)的记录复制到 temp[p] 中,然后将被复制记录的指针 i 或 j 加 1,以及指向复制位置的指针 p加 1。重复这一过程直至两个输入的子序列有一个已全部复制完毕(不妨称其为空),此时将另一非空的子序列中剩余记录依次复制到 array 中即可。
若将两个有序表合并成一个有序表,称为2-路归并
举例说明"归并排序的排序过程"
待排序列(14,12,15,13,11,16)
假设我们有一个没有排好序的序列,那么首先我们使用分割的办法将这个序列分割成一个个已经排好序的子序列。然后再利用归并的方法将一个个的子序列合并成排序好的序列。分割和归并的过程可以看下面的图例。
先"分割"再"合并"
从上图可以看出,我们首先把一个未排序的序列从中间分割成2部分,再把2部分分成4部分,依次分割下去,直到分割成一个一个的数据,再把这些数据两两归并到一起,使之有序,不停的归并,最后成为一个排好序的序列。
实现代码:
归并排序基本原理
通过对若干个有序结点序列的归并来实现排序。所谓归并是指将若干个已排好序的部分合并成一个有序的部分。
归并排序基本思想
将待排序序列R[0...n-1]看成是n个长度为1的有序序列,将相邻的有序表成对归并得到n/2个长度为2的有序表
将这些有序序列再次归并,得到n/4个长度为4的有序序列
如此反复进行下去,最后得到一个长度为n的有序序列。
在具体的合并过程中,设置 i,j 和 p 三个指针,其初值分别指向这三个记录区的起始位置。合并时依次比较 array[i] 和 array[j] 的关键字,取关键字较小(或较大)的记录复制到 temp[p] 中,然后将被复制记录的指针 i 或 j 加 1,以及指向复制位置的指针 p加 1。重复这一过程直至两个输入的子序列有一个已全部复制完毕(不妨称其为空),此时将另一非空的子序列中剩余记录依次复制到 array 中即可。
若将两个有序表合并成一个有序表,称为2-路归并
举例说明"归并排序的排序过程"
待排序列(14,12,15,13,11,16)
假设我们有一个没有排好序的序列,那么首先我们使用分割的办法将这个序列分割成一个个已经排好序的子序列。然后再利用归并的方法将一个个的子序列合并成排序好的序列。分割和归并的过程可以看下面的图例。
先"分割"再"合并"
从上图可以看出,我们首先把一个未排序的序列从中间分割成2部分,再把2部分分成4部分,依次分割下去,直到分割成一个一个的数据,再把这些数据两两归并到一起,使之有序,不停的归并,最后成为一个排好序的序列。
实现代码:
#include<stdio.h> #include<stdlib.h> typedef int Item; #define key(A) (A) #define less(A,B) (key(A)<key(B)) #define exch(A,B) {Item t=A;A=B;B=t;} #define compexch(A,B) if(less(B,A)) exch(A,B) int aux[10000]; void merge(Item a[],int l,int m,int r) { int i,j,k; for(i=l;i<=m;i++) aux[i]=a[i]; for(j=r;j>m;j--) aux[m+r-j+1]=a[j]; for(i=l,j=r,k=l;k<=r;k++) { if(less(aux[i],aux[j])) a[k]=aux[i++]; else a[k]=aux[j--]; } } void mergeSort(Item a[],int l,int r) { if(r<=l) return; int m=(l+r)/2; mergeSort(a,l,m); mergeSort(a,m+1,r); merge(a,l,m,r); } int main(int argc,char *argv[]) { int N=atoi(argv[1]); Item *a=(Item*)malloc(N*sizeof(Item)); for(int i=0;i<N;i++) a[i]=1000*(1.0*rand()/RAND_MAX); for(int i=0;i<N;i++) printf("%3d ",a[i]); printf("\n"); mergeSort(a,0,N-1); for(int i=0;i<N;i++) printf("%3d ",a[i]); printf("\n"); return 0; }
相关文章推荐
- 深度学习基础模型算法原理及编程实现--01.感知机
- 深度学习基础模型算法原理及编程实现--02.线性单元
- java基础解析系列(四)---LinkedHashMap的原理及LRU算法的实现
- java基础解析系列(四)---LinkedHashMap的原理及LRU算法的实现
- 深度学习基础模型算法原理及编程实现--04.改进神经网络的方法
- 算法基础:快速排序算法原理与实现
- java基础解析系列(四)---LinkedHashMap的原理及LRU算法的实现
- 深度学习基础模型算法原理及编程实现--06.循环神经网络
- 深度学习基础模型算法原理及编程实现--09.自编码网络
- 深度学习基础模型算法原理及编程实现--05.卷积神经网络
- 深度学习基础模型算法原理及编程实现--03.全链接
- <基础原理进阶>机器学习算法python实现【1】--分类简谈&KNN算法
- 算法基础:堆排序原理及其实现
- 算法基础:基本排序算法原理、实现与总结
- 整数划分算法原理与实现
- java实现的18位身份证格式验证算法-Java基础-Java-编程开发
- 整数划分算法原理与实现
- Yale CAS实现原理及其基础协议
- Linux集群之负载平衡原理和实现算法
- Yale CAS实现原理及其基础协议