將兩個或兩個以上的有序序列合併成一個新的有序序列
有序序列: V[0]...V[m] 和 V[m+1] ... V[m]
==>
合併: V[0]...[Vn-1]ios
這種合併方法稱爲 2 路歸併。編程
- 將 3 個有序序列歸併爲一個新的有序序列,稱爲 3 路歸併
- 將 N 個有序序列歸併爲一個新的有序序列,稱爲 N 路歸併
- 將多個有序序列歸併爲一個新的有序序列,稱爲多路歸併
動圖
文件:Sort.hui
#ifndef SORT_H #define SORT_H #include "Object.h" namespace DTLib { class Sort : public Object { public: template <typename T> static void Select(T array[], int len, bool min2max = true) // O(n*n) { for (int i=0; i<len; ++i) { int min = i; for (int j=i+1; j<len; ++j) { if ((min2max ? (array[min] > array[j]) : (array[min] < array[j]))) { min = j; } } if (min != i) { Swap(array[i], array[min]); } } } template <typename T> static void Insert(T array[], int len, bool min2max = true) // O(n*n) { for (int i=1; i<len; ++i) { T e = array[i]; int k = i; for (int j=i-1; (j>=0) && (min2max ? (e < array[j]) : (e > array[j])); --j) { array[j+1] = array[j]; k = j; } if (i != k) { array[k] = e; } } } template <typename T> static void Bubble(T arrar[], int len, bool min2max = true) { bool exchange = true; for (int i=0; (i<len) && exchange; ++i) { exchange = false; for (int j=len-1; j>i; --j) { if (min2max ? (arrar[j] < arrar[j-1]) : (arrar[j] > arrar[j-1])) { Swap(arrar[j], arrar[j-1]); exchange = true; } } } } template <typename T> static void Shell(T array[], int len, bool min2max = true) { int d = len; do { d = d / 3 +1; for (int i=d; i<len; i+=d) { T e = array[i]; int k = i; for (int j=i-d; (j>=0) && (min2max ? (e < array[j]) : (e > array[j])); j-=d) { array[j+d] = array[j]; k = j; } if (i != k) { array[k] = e; } } }while (d > 1); } template <typename T> static void Merge(T arrar[], int len, bool min2max = true) { T *helper = new T[len]; if (helper != nullptr) { Merge(arrar, helper, 0, len-1, min2max); } delete [] helper; } private: Sort(); Sort(const Sort&); Sort &operator= (const Sort&); template <typename T> static void Swap(T &a, T &b) { T c(a); a = b; b = c; } template <typename T> static void Merge(T src[], T helper[], int begin, int end, bool min2max) { if (begin < end) { int mid = (begin + end) / 2; Merge(src, helper, begin, mid, min2max); Merge(src, helper, mid + 1, end, min2max); Merge(src, helper, begin, mid, end, min2max); } } template <typename T> static void Merge(T src[], T helper[], int begin, int mid, int end, bool min2max) { int i = begin; int j = mid + 1; int k = begin; while ((i <= mid) && (j <= end)) { if (min2max ? (src[i] < src[j]) : (src[i] > src[j])) { helper[k++] = src[i++]; } else { helper[k++] = src[j++]; } } while (i <= mid) { helper[k++] = src[i++]; } while (j <= end) { helper[k++] = src[j++]; } for (int i = begin; i <= end; ++i) { src[i] = helper[i]; } } }; } #endif // SORT_H
文件:main.cppspa
#include <iostream> #include "Sort.h" using namespace std; using namespace DTLib; int main() { int a[5] = {3, 4, 1, 0, 2}; Sort::Merge(a, 5); for (int i=0; i<5; ++i) { cout << a[i] << " "; } cout << endl; Sort::Merge(a, 5, false); for (int i=0; i<5; ++i) { cout << a[i] << " "; } return 0; }
輸出:code
0 1 2 3 4 4 3 2 1 0
任取序列中的某個元素做爲基準將整個序列劃分爲左右兩個子序列blog
左側子序列中全部元素都小於或等於基準元素 右側子序列中全部元素都大於基準元素 基準元素排在兩個子序列中間
分別對這兩個子序列重複進行劃分,直到全部的數據元素都排在相應位置上爲止排序
分解
動圖
文件:Sort.h遞歸
#ifndef SORT_H #define SORT_H #include "Object.h" namespace DTLib { class Sort : public Object { public: template <typename T> static void Select(T array[], int len, bool min2max = true) // O(n*n) { for (int i=0; i<len; ++i) { int min = i; for (int j=i+1; j<len; ++j) { if ((min2max ? (array[min] > array[j]) : (array[min] < array[j]))) { min = j; } } if (min != i) { Swap(array[i], array[min]); } } } template <typename T> static void Insert(T array[], int len, bool min2max = true) // O(n*n) { for (int i=1; i<len; ++i) { T e = array[i]; int k = i; for (int j=i-1; (j>=0) && (min2max ? (e < array[j]) : (e > array[j])); --j) { array[j+1] = array[j]; k = j; } if (i != k) { array[k] = e; } } } template <typename T> static void Bubble(T arrar[], int len, bool min2max = true) { bool exchange = true; for (int i=0; (i<len) && exchange; ++i) { exchange = false; for (int j=len-1; j>i; --j) { if (min2max ? (arrar[j] < arrar[j-1]) : (arrar[j] > arrar[j-1])) { Swap(arrar[j], arrar[j-1]); exchange = true; } } } } template <typename T> static void Shell(T array[], int len, bool min2max = true) { int d = len; do { d = d / 3 +1; for (int i=d; i<len; i+=d) { T e = array[i]; int k = i; for (int j=i-d; (j>=0) && (min2max ? (e < array[j]) : (e > array[j])); j-=d) { array[j+d] = array[j]; k = j; } if (i != k) { array[k] = e; } } }while (d > 1); } template <typename T> static void Merge(T arrar[], int len, bool min2max = true) { T *helper = new T[len]; if (helper != nullptr) { Merge(arrar, helper, 0, len-1, min2max); } delete [] helper; } template <typename T> static void Quick(T array[], int len, bool min2max = true) { Quick(array, 0, len-1, min2max); } private: Sort(); Sort(const Sort&); Sort &operator= (const Sort&); template <typename T> static void Swap(T &a, T &b) { T c(a); a = b; b = c; } template <typename T> static void Merge(T src[], T helper[], int begin, int end, bool min2max) { if (begin < end) { int mid = (begin + end) / 2; Merge(src, helper, begin, mid, min2max); Merge(src, helper, mid + 1, end, min2max); Merge(src, helper, begin, mid, end, min2max); } } template <typename T> static void Merge(T src[], T helper[], int begin, int mid, int end, bool min2max) { int i = begin; int j = mid + 1; int k = begin; while ((i <= mid) && (j <= end)) { if (min2max ? (src[i] < src[j]) : (src[i] > src[j])) { helper[k++] = src[i++]; } else { helper[k++] = src[j++]; } } while (i <= mid) { helper[k++] = src[i++]; } while (j <= end) { helper[k++] = src[j++]; } for (int i = begin; i <= end; ++i) { src[i] = helper[i]; } } template <typename T> static void Quick(T array[], int begin, int end, bool min2max) { if (begin < end) { int pivot = Partition(array, begin, end, min2max); Quick(array, begin, pivot-1, min2max); Quick(array, pivot + 1, end, min2max); } } template <typename T> static int Partition(T array[], int begin, int end, bool min2max) { T pv = array[begin]; while (begin < end) { while ((begin < end) && (min2max ? (array[end] > pv) : (array[end] < pv))) { --end; } Swap(array[begin], array[end]); while ((begin < end) && (min2max ? (array[begin] <= pv) : (array[begin] >= pv))) { ++begin; } // Swap(array[begin], array[end]); // 功能上不須要! } array[begin] = pv; return begin; } }; } #endif // SORT_H
文件:main.cppip
#include <iostream> #include "Sort.h" using namespace std; using namespace DTLib; int main() { int a[5] = {3, 4, 1, 0, 2}; Sort::Quick(a, 5); for (int i=0; i<5; ++i) { cout << a[i] << " "; } cout << endl; Sort::Quick(a, 5, false); for (int i=0; i<5; ++i) { cout << a[i] << " "; } return 0; }
輸出:it
0 1 2 3 4 4 3 2 1 0
- 歸併排序須要額外的輔助空間才能完成,空間複雜度爲 O(n)
- 歸併排序的時間複雜度爲O(n*logn),是一種穩定的排序法
- 快速排序經過遞歸的方式對排序問題進行劃分
- 快速排序的時間複雜度爲 O(n*logn),是一種不穩定的排序法
以上內容整理於狄泰軟件學院系列課程,請你們保護原創!