归并排序
来源:互联网 发布:任子行 知乎 编辑:程序博客网 时间:2024/06/03 22:52
归并操作(merge),也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作。归并排序算法依赖归并操作。
算法描述
归并操作的过程如下:
- 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
- 设定两个指针,最初位置分别为两个已经排序序列的起始位置
- 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
- 重复步骤3直到某一指针到达序列尾
- 将另一序列剩下的所有元素直接复制到合并序列尾
自顶向下的归并排序(递归):
#include<iostream>using namespace std;class MergeSort{public: void merge(int a[],int l,int mid,int h) { int i=l; int j=mid+1; for(int k=l;k<=h;++k) aux[k]=a[k]; for(int k=l;k<=h;++k) { if(i>mid)a[k]=aux[j++];//左半边元素用尽 else if(j>h)a[k]=aux[i++];//右半边元素用尽 else if(aux[i]<aux[j])a[k]=aux[i++];//左半边元素小于右半边元素 else a[k]=aux[j++];//左半边元素大于右半边元素 } } void sort(int a[],int l,int h) { if(h<=l)return ; int mid=l+(h-l)/2; sort(a,l,mid); sort(a,mid+1,h); merge(a,l,mid,h); } void sort() { sort(a,0,n-1); } MergeSort(int *a,int n) { this->n=n; this->a=a; aux=new int(n); } ~MergeSort(){ free(aux); }private: int *aux; int n; int *a;};int main(int argc, char *argv[]){ int a[]={4,5,6,7,1,2,3,0}; MergeSort m(8); m.sort(a); for(int i=0;i<sizeof(a)/sizeof(int);++i) printf("%d\n",a[i]); return 0;}
经验:使用插入排序处理小规模的子数组(比如长度小于15),一般可以将归并排序的运行时间缩短10%~15%
自底向上的归并排序(迭代):
class MergeSort2{public : MergeSort2(int a[],int n){ this->n=n; this->a=a; aux=new int(n); } ~MergeSort2(){free(aux);} inline int min(int a,int b) {return a<b?a:b;} void sort() { for(int sz=1;sz<n;sz=sz+sz) for(int l=0;l<n-sz;l+=sz+sz) merge(a,l,l+sz-1,min(l+sz+sz-1,n-1)); } void merge(int a[],int l,int mid,int h) { int i=l; int j=mid+1; for(int k=l;k<=h;++k) aux[k]=a[k]; for(int k=l;k<=h;++k) { if(i>mid)a[k]=aux[j++]; else if(j>h)a[k]=aux[i++]; else if(aux[i]<aux[j])a[k]=aux[i++]; else a[k]=aux[j++]; } }private: int n; int *aux; int *a;};
自底向上的归并排序比较适合用链表组织的数据。想象一下将链表先按大小为1的子链表进行排序,然后是大小为2的子链表,然后是大小为4的子链表等。这种方法只需要重新组织链表链接就能将链表原地排序(不需要创建任何新的链表结点)。
0 0
- 归并排序-归并排序
- 归并和归并排序
- 归并与归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 排序::归并
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- Tachyon简介
- mongodb学习(-)安装及其简单的操作命令
- [leetcode]Longest Palindromic Substring
- 高性能Javascript--脚本的无阻塞加载策略
- HDU—— 2078 复习时间
- 归并排序
- union,union all,intersect,minus(转载)
- operator++()和operator++(int)的区别
- OpenCV目录简介&各模块的介绍
- canada goose arctic efSt niTq cMklv
- viewControll的生命周期[整理]
- Ubuntu下PHP错误提示的开启
- POJ 1503 Integer Inquiry
- 3.Jq效果函数