将两个或两个以上的有序序列合并成一个新的有序序列
有序序列: 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),是一种不稳定的排序法
以上内容整理于狄泰软件学院系列课程,请你们保护原创!