分治算法:ios
用分治策略實現n個元素進行排序的方法。算法
基本思想:數組
將待排序元素分紅大小大體相同的兩個子集合,分別對兩個子集合進行排序,最終排好序的子集合合併成所要求的排好序的集合。ide
源碼:函數
/* * mergeSort.cpp * 合併排序算法,算法導論P.17 * Created on: 2011-12-21 * Author: LiChanghai */ //#include <iostream> #include <vector> #include <iostream> #include <iterator> using namespace std; #define FLT_MAX 1.0E38 //定義一個很大的值做爲哨兵 //對於待排序的數組 A[p...r], 其子數組A[p...q],A[q+1...r]已排好序 //函數 subMerge(A, p, q, r), 將兩個已排好序的子數組A[p...q],A[q+1...r] //合併成一個有序的數組代替當前的數組A[p...r] template<typename T> void subMerge(vector<T> &array, typename vector<T>::iterator iterBegin, typename vector<T>::iterator iterBarrier, typename vector<T>::iterator iterEnd) { //建立兩個數組,分別存放以iterBarrier爲界線的array的左邊部分和右邊部分 vector<T> arrayLeft(iterBegin, iterBarrier+1); vector<T> arrayRight(iterBarrier+1, iterEnd); //在兩個數組尾部分別放一個「哨兵」 T temp = T(FLT_MAX); arrayLeft.push_back(temp); arrayRight.push_back(temp); //定義分別指向兩個數組的迭代器 typename vector<T>::iterator iterLeft = arrayLeft.begin(); typename vector<T>::iterator iterRight = arrayRight.begin(); //定義指向原數組array的迭代器 typename vector<T>::iterator iterArray = iterBegin; for(; iterArray != iterEnd; ++iterArray) if(*iterLeft < *iterRight) //若是左邊小,將左邊的值放入原數組 { *iterArray = *iterLeft; ++iterLeft; } else //若是右邊小,將右邊的值放入原數組 { *iterArray = *iterRight; ++iterRight; } return; } //函數 mergeSort(A, p, r) 調用subMerge對任意數組排序,p, r爲下標 //mergeSort(A, p, r)首先將數組A分爲兩部分 //而後遞歸調用其自己對這兩部分 分別排序 //依次遞歸下去,直到只剩2個數的時候完成這兩個數的排序 //而後再層層返回調用處,將已排好序的子序列合併成更大的有序序列 //最後一次調用subMerge時完成數組的排序 template<typename T> void mergeSort(vector<T> &vec, typename vector<T>::iterator iterHead, typename vector<T>::iterator iterTail) { //測試 mergeSort 調用了多少次 //static int times_mergeSort=0; //cout<<"the "<<++times_mergeSort<<" call mergeSort()"<<endl; //測試 subMerge 調用了多少次 //static int times_subMerge=0; if(iterHead < iterTail-1) { //數組長度的一半(錯誤的方法) //typename vector<T>::size_type halfLength = (vec.size()-1)/2; //數組長度的一半(正確方法) typename vector<T>::difference_type halfLength=( (iterTail-iterHead)-1)/2; //定義一個迭代器指向數組 vec 中間位置 typename vector<T>::iterator iterDivide = iterHead + halfLength; mergeSort(vec, iterHead, iterDivide+1); //遞歸調用自身對前半段排序 mergeSort(vec, iterDivide+1, iterTail); //遞歸調用自身對後半段排序 //cout<<"the "<<++times_subMerge<<" call subMerge()"<<endl; subMerge(vec, iterHead, iterDivide, iterTail); //將上面排好序的兩段合併 } return; } int main() { vector<int> vec; vec.push_back(0); vec.push_back(9); vec.push_back(8); vec.push_back(7); vec.push_back(6); vec.push_back(5); vec.push_back(4); vec.push_back(3); vec.push_back(2); vec.push_back(1); int size = vec.size(); int *phead = &vec[0]; int *ptail = &vec[size]; mergeSort(vec,phead,ptail); for(int i=0;i<10;i++) cout<<vec[i]<<" "; cout<<endl; return 0; }
運行結果:測試