归并排序(MergeSort)
2014-01-03 12:50 江湖么名 阅读(244) 评论(0) 编辑 收藏 举报原帖:http://blog.csdn.net/magicharvey/article/details/10192933
算法描述
归并排序(MergeSort)是采用分治法的一个非常典型的应用。通过先递归的分解数组,再合并数组就完成了归并排序。
基本思想
归并排序是将整个集合问题分解成最小单元,将该单元内的元素全部排序,然后将相邻的单元重新排序。如果将n1,n2看做一个整体n的话,则针对n,先对其一半进行排序,另一半排序,然后整体再次排序。
实现步骤
- 递归的将数组分为两个子数组,每个子数组重新分为两个子数组,直到数组个数为1为止;
- 将相邻的两个有序数组合并为一个有序数组;
- 最终直到剩下两个有序子数组,将其合并为一个总的有序大数组。
算法实现
代码在xcode中验证,可以直接使用
//新建一个临时数组,用来存放排序好的元素 int temp[100] = {0}; //交换两个值的函数 void swap(int a, int b) { int index = a; a = b; b = index; } //将两个有序的序列a[begin ... mid]和a[mid+1...end]合并 void M_Sort(int a[], int begin, int mid, int end) { int i = begin; //左边数组的开始节点 int j = mid+1; //右边数组的开始节点 int k = 0; //合并后的数组的下标 //左边或者右边数组是否有一个读取完毕 while(i <= mid && j <= end) { if( a[i] <= a[j]) { temp[k++] = a[i++]; } else { temp[k++] = a[j++]; } } //将左边或者右边节点剩余的节点复制给临时数组 while(i <= mid) { temp[k++] = a[i++]; } while(j <= end) { temp[k++] = a[j++]; } //k代表合并后的数组的大小 for(int m = 0; m < k; m++) { a[begin+m] = temp[m]; //begin+m代表在a数组中的位置 } } //将序列a[begin ... end]不断地分为相同的两个子序列,直到序列中的元素个数为1为止,不断递归 void MergeSort(int a[], int begin, int end) { if(begin<end) { int mid = (begin + end )/2 ; MergeSort(a, begin, mid); //递归左边的序列 MergeSort(a, mid+1, end); //递归右边的序列 M_Sort(a, begin, mid ,end); //合并左右的序列 } }
性能分析
归并算法是又分割和归并两部分组成的。对于分割部分,如果我们使用二分查找的话,时间是O(logn),在最后归并的时候,时间是O(n),所以总的时间O(nlogn)。
归并排序是稳定的,它的最差,平均,最好时间都是O(nlogn)。但是它需要额外的存储空间,这在某些内存紧张的机器上会受到限制。