排序算法(六)---- 归并排序
2017-09-04 22:31
274 查看
对于归并排序,与快速排序一样,巧妙的应用了分治算法的核心思想,它将整个序列分成若干组子序列,对这些子序列进行排序后,在一步一步进行合并有序子序列,从而使得整个序列达到有序。
但针对于归并排序,有着两种不同的排序方式,一是通过整个序列进行着手,将这个序列进行一步一步的划分,自顶向下进行处理,主要步骤包括序列划分,子序列排序,以及合并,而这一方法可以通过递归来实现;与之相对的就是另外一种方式,自底向上,从最小子序列着手,将其进行两两合并,一步一步得到整个有序序列,而这也是我们归并排序的非递归实现方式
①自顶向下(递归)
方法如下:
②自底向上(非递归)
方法如下:
值得注意的是,归并排序不管是非递归方法,还是递归方法,都需要辅助空间的参与,但是对于递归而言,一次递归就申请一次空间会降低效率,而且需要注意释放空间,所以这里在外部直接申请出一块足够的空间,然后将其指针作为参数进行传递,而在外部进行释放,也是相当方便。
对于归并排序的时间复杂度为O(NlogN),空间复杂度为O(N),而且归并排序是稳定的
与前面所有的排序算法不一样,归并排序属于外部排序,而对于外部排序而言,与内部排序最大的区别在于外部排序在进行排序时,并不需要得到所有数据,可以将大量的数据分成若干组,分别对其进行排序,最后再综合起来排序,适合与大量数据的排序
但针对于归并排序,有着两种不同的排序方式,一是通过整个序列进行着手,将这个序列进行一步一步的划分,自顶向下进行处理,主要步骤包括序列划分,子序列排序,以及合并,而这一方法可以通过递归来实现;与之相对的就是另外一种方式,自底向上,从最小子序列着手,将其进行两两合并,一步一步得到整个有序序列,而这也是我们归并排序的非递归实现方式
①自顶向下(递归)
方法如下:
void Merge(int arr[],int left,int right,int mid,int* tmp) { int i=left; int j=mid+1; int idx=0; while(i<=mid&&j<=right) { if(arr[i]<arr[j]) tmp[idx++]=arr[i++]; else tmp[idx++]=arr[j++]; } while(i<=mid) { tmp[idx++]=arr[i++]; } while(j<=right) { tmp[idx++]=arr[j++]; } } void MergeSort_Nor(int arr[],int left,int right,int* tmp) { if(left<right) { int mid=(left&right)+((left^right)>>1); MergeSort_Nor(arr,left,mid,tmp); MergeSort_Nor(arr,mid+1,right,tmp); Merge(arr,left,right,mid,tmp); memcpy(arr+left,tmp,(right-left+1)*sizeof(arr[0])); } } void MergeSort(int arr[],int size) { int* tmp=new int[size]; int left=0; int right=size-1; MergeSort_Nor(arr,left,right,tmp); delete[] tmp; }
②自底向上(非递归)
方法如下:
void Merge(int arr[],int left,int right,int mid,int* tmp) { int i=left; int j=mid+1; int idx=0; while(i<=mid&&j<=right) { if(arr[i]<arr[j]) tmp[idx++]=arr[i++]; else tmp[ 4000 idx++]=arr[j++]; } while(i<=mid) { tmp[idx++]=arr[i++]; } while(j<=right) { tmp[idx++]=arr[j++]; } } void MergeSort(int arr[],int size) { int* tmp=new int[size]; int gap=1; while(gap<size) { for(int i=0;i<size;i+=2*gap) { int left=i; int right=i+2*gap-1; int mid=i+gap-1; if(right>=size)//注意越界 right=size-1; if(mid>=size)//注意越界 mid=size-1; Merge(arr,left,right,mid,tmp); memcpy(arr+left,tmp,(right-left+1)*sizeof(arr[0])); } gap*=2; } delete[] tmp; }
值得注意的是,归并排序不管是非递归方法,还是递归方法,都需要辅助空间的参与,但是对于递归而言,一次递归就申请一次空间会降低效率,而且需要注意释放空间,所以这里在外部直接申请出一块足够的空间,然后将其指针作为参数进行传递,而在外部进行释放,也是相当方便。
对于归并排序的时间复杂度为O(NlogN),空间复杂度为O(N),而且归并排序是稳定的
与前面所有的排序算法不一样,归并排序属于外部排序,而对于外部排序而言,与内部排序最大的区别在于外部排序在进行排序时,并不需要得到所有数据,可以将大量的数据分成若干组,分别对其进行排序,最后再综合起来排序,适合与大量数据的排序
相关文章推荐
- 排序算法-归并排序
- 排序算法之归并排序
- 排序算法之归并排序的C++实现
- 排序算法之归并排序
- 排序算法(四)——归并排序与递归
- 《排序算法》——归并排序,插入排序(Java)
- 排序算法详解【归并排序-Merge_Sort】
- 排序算法之插入排序、归并排序、快速排序
- 排序算法——归并排序
- 排序算法(归并排序)
- 排序算法--归并排序
- 排序算法——归并排序
- 排序算法之归并排序
- 排序算法之(5)——归并排序(递归实现)
- 排序算法2-快速排序、归并排序
- 排序算法之归并排序
- 排序算法(3):归并排序
- 【算法】排序算法(三)——归并排序
- 排序算法java版,速度排行:冒泡排序、简单选择排序、直接插入排序、折半插入排序、希尔排序、堆排序、归并排序、快速排序
- 经典排序算法——归并排序