归并排序

来源:互联网 发布:搞笑相机软件大全 编辑:程序博客网 时间:2024/06/06 14:13

归并排序运用分治法,先将无序序列不断分解,再将有序子序列逐层合并,得到完全有序序列。

归并排序的算法我们通常用递归实现,终止条件为分解到子区间只有一个元素。先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,默认单个元素不用排序。最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。

归并细节:比较已排好序的左区间a[i]和右区间b[j]的大小,若a[i]≤b[j],则将左区间中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将右区间中的元素b[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。


归并排序时间复杂度为O(nlog₂n),空间复杂度为 O(n)比较占用内存,但却是一种效率高且稳定的算法。

C++实现代码如下:

//将data[]每层每个子序列已经排好序的左右区间的数据归并到result[]相应的下标中void merge(int *data, int start, int end, int *result){int mid = (start+end)/2;int left_index = start;//左区间下标int right_index = mid+1;//右区间下标int result_index = start;while (left_index <= mid && right_index <= end ){if (data[left_index] <= data[right_index])result[result_index++] = data[left_index++];elseresult[result_index++] = data[right_index++];}while (left_index <= mid )result[result_index++] = data[left_index++];while (right_index <= end )result[result_index++] = data[right_index++];}//注意每层每个子序列的start和end是不一样的void merge_sort(int *data, int start, int end, int *result){int mid = (start + end) / 2;if (start == end)//划分到每个子序列只有一个元素结束return;else{merge_sort(data, start, mid, result);//划分每层每个子序列的左区间merge_sort(data, mid + 1, end, result);//划分每层每个子序列右区间merge(data, start, end, result);//开始归并每层每个子序列已经排好序的左区间和右区间,即该层start到end之间的数据,单个元素不用排序for (int i = start; i <= end; ++i)//把排序后的区间数据复制到原始数据中去data[i] = result[i];}}int main(){int data[] = { 23,21,34,45,35,56,89,12 };const int length = 8;int result[length];cout << "Before sorted:" << endl;for (int i = 0; i < length; ++i)cout << data[i] << "  ";cout << endl;merge_sort(data, 0, length - 1, result);cout << "After sorted:" << endl;for (int i = 0; i < length; ++i)cout << data[i] << "  ";cout << endl;return 0;}

原创粉丝点击