算法分析:归并排序
归并排序:
最坏情形是O(NlogN)
使用的比较次数几乎是最优的。
这个算法中基本操作是合并两个已排序的表。
归并排序通过递归,将数组自身分拆成2个数组,然后进入子数组的排序。
分拆的数组左右两个,必须是紧跟着的。
虽然归并排序的运行时间是O(NlogN),但是很难用于主存排序,主要问题在于合并两个排序表需要额外的内存,在整个算法中还要复制数据。
归并排序的运行时间很大程度上依赖于在数组中进行元素的比较和移动所消耗的时间。
例如java中,元素比较耗时很多,移动元素就快很多,所以归并排序是一般目的的排序的最佳选择。
在C++中,对象很大的时候,复制对象代价很大,而对象比较消耗小。
//-------------归并排序---------------------- template<typename Comparable> void mergeSort(Vector<Comparable>& a) { //构建一个临时数组,用来放数据 Vector<Comparable> temArry(a.size()); //调用核心函数 mergeSort(a, temArry, 0, a.size() - 1); } template<typename Comparable> void mergeSort(Vector<Comparable>& a, Vector<Comparable>& tmpArray, int left, int right) { if (left >= right) { return;//只有一个元素的时候,就返回了 } int center = (left + right) / 2;//定义一个中心,一分为二 mergeSort(a, tmpArray, left, center);//对左边进行归并排序 mergeSort(a, tmpArray, center + 1, right);//对右边进行归并排序 merge(a, tmpArray, left, center + 1, right);//合并左右两边 } //合并两个已排序的队列 template<typename Comparable> void merge(Vector<Comparable>& a, Vector<Comparable>& tmpArray, int leftPos, int rightPos, int rightEnd) { int leftEnd = rightPos - 1;//左边最后一位 int tmpPos = leftPos;//临时数组中的第一个位置 int numElements = rightEnd - leftPos + 1;//总的元素数量 //两边都有元素的时候 while (leftPos <= leftEnd && rightPos <= rightEnd) { //将小的放进临时数组 if (a[leftPos] <= a[rightPos]) { tmpArray[tmpPos++] = a[leftPos++]; } else { tmpArray[tmpPos++] = a[rightPos++]; } } //有一个数组是完结的了,放另一个数组的全部数据进去 while (leftPos <= leftEnd) { tmpArray[tmpPos++] = a[leftPos++]; } while (rightPos <= rightEnd) { tmpArray[tmpPos++] = a[rightPos++]; } //将临时数组的数据放到原来的数组 for (int i = 0; i < numElements; i++, rightEnd--) { a[rightEnd] = tmpArray[rightEnd]; } }
人生如戏,还是戏如人生?微信公众号:传说之路
csdn博客 http://blog.csdn.net/u012175089/article/list/2