排序算法的c++实现——归并排序
Posted yinheyi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序算法的c++实现——归并排序相关的知识,希望对你有一定的参考价值。
归并排序是典型分治思想的代表——首先把原问题分解为两个或多个子问题,然后求解子问题的解,最后使用子问题的解来构造出原问题的解。
对于归并排序,给定一个待排序的数组,首先把该数组划分为两个子数组,然后对子数组进行排序(递归调用归并排序),最后对两个有序的子数组进行合并,使合并之后的数组为有序状态。
让我们想想,把一个数组不断地划分为子数组,不断地划分......,不断地划分......., 最后停止了划分不下去了。 此时子数组的元素有一个,它们本身就是有序的。接下来,我们就需要执行合并过程,不断地一层层向上合并,........, 直到原数组。通过这个过程就会发现, 归并排序的核心在于合并有序的子数组,而不是对子数组进行排序,因为最底层的子数组本身就是有序的,上一层子数组如果想要变成有序的,通过合并底层有序的子数组就可以得到, 最终我们使原数组变成了有序的,从而完成了排序操作。
说明几点:
1. 归并排序采用了分治思想,它的核心在于合并子问题的解而不是求解子问题(快速排序也采用了分治思想,但它的核心是在于求解子问题而不需要合并子问题的解)、
2. 归并排序不是原址排序,它有排序过程中需要借助额外的内存空间。
3. 归并排序为稳定排序(其实呢,具体还得看你怎么写代码,如果两个数的值相等时,你不保持原顺序都就会变成非稳定的了)
4. 归并排序的时间复杂度为O(NlogN).
具体代码如下:
1 /*********************************************************************** 2 * Copyright (C) 2019 Yinheyi. <[email protected]> 3 * 4 * This program is free software; you can redistribute it and/or modify it under the terms 5 * of the GNU General Public License as published by the Free Software Foundation; either 6 * version 2 of the License, or (at your option) any later version. 7 8 * Brief: 9 * Author: yinheyi 10 * Email: [email protected] 11 * Version: 1.0 12 * Created Time: 2019年05月06日 星期一 22时22分57秒 13 * Modifed Time: 2019年05月09日 星期四 21时10分59秒 14 * Blog: http://www.cnblogs.com/yinheyi 15 * Github: https://github.com/yinheyi 16 * 17 ***********************************************************************/ 18 19 20 // 归并排序,分治法的典型代表: 将原问题分解了几个子问题,解决子问题,再合并子问题的解, 21 // 这样就得到了原问题的解。 22 // 分治本质上就是把原问题分解为几个子问题来解决。 23 // 快速排序也是分治思想来解决。 24 // 25 // 26 // 归并排序(merge-sort): 27 // 1. 把一个待排序的数组分解为两个子数组; 28 // 2. 对两个子数组进行排序(通过递归地调用自己来实现); 29 // 3. 对两个已经排序的数组进行合并。 30 // 31 // 分析: 32 // 1. 一个数组一直分解下去,只到分解成只包含一个元素的子数组为止, 此时自然是有序的; 33 // 2. 归并排序的重点在于合并,而不是对子数组的排序。(快速排序与它恰恰相反,快速排序的 34 // 重点是对子数组进行排序,而不是合并,因为它不需要合并了) 35 // 36 // 37 #include <cstring> 38 #include <iostream> 39 typedef bool(*CompareFunc)(int, int); 40 41 // 下面函数实现合并功能,输入三个下标参数表示了两个子数组, :[nStart_, nMiddle)和[nMiddle, nEnd) 42 void Merge(int array[], int nStart_, int nMiddle_, int nEnd_, CompareFunc comp) 43 { 44 if (array == nullptr || nStart_ >= nMiddle_ || nMiddle_ >= nEnd_) 45 return; 46 47 // 建立一个临时数组存放中间数据 48 int _nIndex = 0; 49 int* _pTempArray = new int[nEnd_ - nStart_]; 50 51 // 对两个子数组进行合并 52 int _nStartChange = nStart_; 53 int _nMiddleChange = nMiddle_; 54 while (_nStartChange < nMiddle_ && _nMiddleChange < nEnd_) 55 { 56 // 此处的if中比较语句的安排可以保持稳定排序的特性。 57 if (comp(array[_nMiddleChange], array[_nStartChange])) 58 { 59 _pTempArray[_nIndex] = array[_nMiddleChange]; 60 ++_nMiddleChange; 61 } 62 else 63 { 64 _pTempArray[_nIndex] = array[_nStartChange]; 65 ++_nStartChange; 66 } 67 ++_nIndex; 68 } 69 70 // 把不为空的子数组的元素追加到临时数 71 if (_nStartChange < nMiddle_) 72 { 73 memcpy(_pTempArray + _nIndex, array + _nStartChange, sizeof(int) * (nMiddle_ - _nStartChange)); 74 } 75 else if (_nMiddleChange < nEnd_) 76 { 77 memcpy(_pTempArray + _nIndex, array + _nMiddleChange, sizeof(int) * (nEnd_ - _nMiddleChange)); 78 } 79 else 80 { 81 /* do noting */ 82 } 83 84 // 数据交换 85 memcpy(array + nStart_, _pTempArray, sizeof(int) * (nEnd_ - nStart_)); 86 87 delete [] _pTempArray; 88 _pTempArray = nullptr; 89 } 90 91 // 归并排序功能实现函数 92 void MergeSort(int array[], int nStart_, int nEnd_, CompareFunc comp) 93 { 94 // 数组指针为空,或者数组内的个数少于等于1个时,直接返回。 95 if (nullptr == array || (nEnd_ - nStart_) <= 1) 96 return; 97 98 // 划分为两个子数组并递归调用自身进行排序 99 int _nMiddle = (nStart_ + nEnd_) / 2; 100 MergeSort(array, nStart_, _nMiddle, comp); 101 MergeSort(array, _nMiddle, nEnd_, comp); 102 103 // 合并排序完成的子数组 104 Merge(array, nStart_, _nMiddle, nEnd_, comp); 105 } 106 107 // 比较函数 108 bool less(int lhs, int rhs) 109 { 110 return lhs < rhs; 111 } 112 113 // 打印数组函数 114 void PrintArray(int array[], int nLength_) 115 { 116 if (nullptr == array || nLength_ <= 0) 117 return; 118 119 for (int i = 0; i < nLength_; ++i) 120 { 121 std::cout << array[i] << " "; 122 } 123 124 std::cout << std::endl; 125 } 126 127 /*************** main.c *********************/ 128 >>int main(int argc, char* argv[]) 129 { 130 // 测试1 131 int array[10] = {1, -1, 1, 231321, -12321, -1, -1, 123, -213, -13}; 132 PrintArray(array, 10); 133 MergeSort(array, 0, 10, less); 134 PrintArray(array, 10); 135 136 // 测试2 137 int array2[1] = {1}; 138 PrintArray(array2, 1); 139 MergeSort(array2, 0, 1, less); 140 PrintArray(array2, 1); 141 142 // 测试3 143 int array3[2] = {1, -1}; 144 PrintArray(array3, 2); 145 MergeSort(array3, 0, 2, less); 146 PrintArray(array3, 2); 147 148 return 0; 149 }
以上是关于排序算法的c++实现——归并排序的主要内容,如果未能解决你的问题,请参考以下文章