经典算法学习:各种排序算法的模板类实现
2017-05-21 15:40
531 查看
参考:《大话数据结构》
对各种排序算法进行了模板类实现,备忘。
冒泡排序:
两两比较相邻记录的关键字,如果反序就交换,直到没有反序的记录为止。
简单选择排序:
通过n-i次关键字间的比较,从n-i+1个记录中选出关键字最小的记录,并和第i(1<=i<=n)个记录进行交换。
直接插入排序:
将一个记录插入到已经排好序的有序序列中,从而得到一个新的,记录数增加1的有序序列。
希尔排序:
将相距某个“增量”的记录组成一个子序列,保证子序列内分别进行直接插入排序后得到的结果是基本有序的。最后一次的增量必须为1。
堆排序:
将待排序列构造成一个最大堆,此时整个序列的最大值就是根结点。将根节点与末尾元素进行交换,则末尾元素是最大值。然后将n-1个元素重新构造最大堆,得到次大值,如此反复进行。
归并排序:
假设初始序列含有n个记录,可以看成n个有序的子序列,每个子序列长度为1,然后两两归并,得到长度为2或1的有序子序列;再两两归并,……,如此重复,直到得到一个长度为n的有序序列。
快速排序:
通过一趟排序将待排序列分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,然后分别再对这两部分进行排序,以达到整体有序。
各种排序算法的时间复杂度、辅助空间、稳定性:
下面是各种排序算法的模板类实现:
如果不足,欢迎指正!
对各种排序算法进行了模板类实现,备忘。
冒泡排序:
两两比较相邻记录的关键字,如果反序就交换,直到没有反序的记录为止。
简单选择排序:
通过n-i次关键字间的比较,从n-i+1个记录中选出关键字最小的记录,并和第i(1<=i<=n)个记录进行交换。
直接插入排序:
将一个记录插入到已经排好序的有序序列中,从而得到一个新的,记录数增加1的有序序列。
希尔排序:
将相距某个“增量”的记录组成一个子序列,保证子序列内分别进行直接插入排序后得到的结果是基本有序的。最后一次的增量必须为1。
堆排序:
将待排序列构造成一个最大堆,此时整个序列的最大值就是根结点。将根节点与末尾元素进行交换,则末尾元素是最大值。然后将n-1个元素重新构造最大堆,得到次大值,如此反复进行。
归并排序:
假设初始序列含有n个记录,可以看成n个有序的子序列,每个子序列长度为1,然后两两归并,得到长度为2或1的有序子序列;再两两归并,……,如此重复,直到得到一个长度为n的有序序列。
快速排序:
通过一趟排序将待排序列分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,然后分别再对这两部分进行排序,以达到整体有序。
各种排序算法的时间复杂度、辅助空间、稳定性:
下面是各种排序算法的模板类实现:
#pragma once #ifndef SORT_H #define SORT_H template<typename T> class Sort { private: void Max_Heapify(T *array, int i, int heapSize); void Merge(T *array,int left, int mid, int right); void SubMerge(T *array, int left, int right); void QuickSort(T *array, int left, int right); public: Sort(); ~Sort(); void Bubble_Sort(T *array, const int length); void Select_Sort(T *array, const int length); void Insert_Sort(T *array, const int length); void Shell_Sort(T *array, const int length); void Heap_Sort(T *array, const int length); void Merge_Sort(T *array, const int length); void Quik_Sort(T *array, const int length); }; #endif // !SORT_H /*堆排序-构造最大堆*/ template<typename T> inline void Sort<T>::Max_Heapify(T * array, int i, int heapSize) { int left = 2 * i + 1; int right = 2 * i + 2; int max = i; if (left <= heapSize&&array[left] > array[i]) max = left; if (right <= heapSize&&array[right] > array[max]) max = right; if (max != i) { T temp = array[i]; array[i] = array[max]; array[max] = temp; if (2 * max + 1 <= heapSize) Max_Heapify(array, max, heapSize); } } /*归并排序-两路排序合并*/ template<typename T> inline void Sort<T>::Merge(T *array,int left,int mid,int right) { T *temp = new T[right - left + 1];//额外空间进行排序 int i = left; int j = mid + 1; int k = 0; while (i <= mid&&j <= right) { if (array[i] < array[j]) { temp[k++] = array[i++]; } else { temp[k++] = array[j++]; } } while (i <= mid) { temp[k++] = array[i++]; } while (j <= right) { temp[k++] = array[j++]; } for (i = left, k = 0; i <= right;) { array[i++] = temp[k++];//将排序结果复制到原数组 } delete []temp; } /*归并排序-分治*/ template<typename T> inline void Sort<T>::SubMerge(T * array, int left, int right) { if (left < right) { int mid = (left + right) / 2; subSort(array, left, mid);//左边有序 subSort(array, mid + 1, right);//后边有序 Merge(array, left, mid, right);//左右合并 } } /*快速排序-递归*/ template<typename T> inline void Sort<T>::QuickSort(T * array, int left, int right) { while (left < right) { int i = left; int j = right; T pivot = array[i];//用区间的第一个记录作为基准,基准数在位置i上 while (i < j)//从区间的两端向中间扫描,直到i=j { while (i < j&&array[j] >= pivot)//从右向左找到小于基准的数 j--; if(i<j) array[i++] = array[j]; while (i < j&&array[i] <= pivot)//从左向右扫描找到大于基准的数 i++; if(i<j) array[j--] = array[i]; } array[i] = pivot;//基准数的最终位置 QuickSort(array, left, i - 1); left = i + 1; } } template<typename T> inline Sort<T>::Sort() { } template<typename T> inline Sort<T>::~Sort() { } /*冒泡排序*/ template<typename T> inline void Sort<T>::Bubble_Sort(T * array, const int length) { if (array == NULL) { throw invalid_argument("Array must not be empty."); } if (length <= 0) return; bool flag = true;//设置一个标记,如果flag=false,说明这一趟没有经过交换,已经排好序了 for (int i = 0; i < length - 1 && flag; i++) { flag = false; for (int j = length - 2; j >= i; j--) { if (array[j] > array[j+1]) { T temp = array[j + 1]; array[j + 1] = array[j]; array[j] = temp; flag = true; } } } } /*简单选择排序*/ template<typename T> inline void Sort<T>::Select_Sort(T * array, const int length) { if (array == NULL) { throw invalid_argument("Array must not be empty."); } if (length <= 0) return; for (int i = 0; i < length-1; i++) { int min = i;//设置第i位为最小值,后面所有的数和它进行比较 for (int j = i + 1; j < length; j++) { if (array[j] < array[min])//如果后面有小于当前最小值的数,将这个数的下标赋给min min = j; } if (min != i)//找到这一趟的实际最小值 { T temp = array[i]; array[i] = array[min]; array[min] = temp; } } } /*直接插入排序*/ template<typename T> inline void Sort<T>::Insert_Sort(T * array, const int length) { if (array == NULL) throw invalid_argument("Array must not be empty."); if (length <= 0) return; for (int i = 1; i < length; i++) { T temp = array[i]; int j = i - 1; while (j >= 0 && array[j] > temp) { array[j + 1] = array[j]; j--; } array[j + 1] = temp; } } /*希尔排序*/ template<typename T> inline void Sort<T>::Shell_Sort(T * array, const int length) { if (array == NULL) throw invalid_argument("Array must not be empty."); if (length <= 0) return; int increment = length / 2;//设置增量 while (increment) { T temp; for (int i = increment; i < length; i++) { temp = array[i]; int j = i; while (j >= increment&&temp < array[j - increment]) { array[j] = array[j - increment]; j -= increment; } array[j] = temp; } increment /= 2; } } /*堆排序*/ template<typename T> inline void Sort<T>::Heap_Sort(T * array, const int length) { if (array == NULL) { throw invalid_argument("Array must not be empty."); } if (length <= 0) return; for (int i = length / 2-1; i >= 0; i--) { Max_Heapify(array, i, length - 1);//构造一个最大堆 } for (int i = length -1; i >= 0; i--)//将堆顶元素和末尾元素交换,剩下的元素再构造最大堆 { T temp = array[0]; array[0] = array[i]; array[i] = temp; Max_Heapify(array, 0, i - 1); } } /*归并排序*/ template<typename T> inline void Sort<T>::Merge_Sort(T * array, const int length) { /*T* sorted = (T*)malloc(length * sizeof(T)); int k = 0; while (k < length - 1) { Merge_Pass(array, sorted, k, length); k = 2 * k; Merge_Pass(sorted, array, k, length); k = 2 * k; }*/ if (array == NULL) { throw invalid_argument("Array must not be empty."); } if (length <= 0) return; subSort(array, 0, length - 1); } /*快速排序*/ template<typename T> inline void Sort<T>::Quik_Sort(T * array, const int length) { if (array == NULL) throw invalid_argument("Array must not be empty."); if (length <= 0) return; QuickSort(array, 0, length - 1); }
如果不足,欢迎指正!
相关文章推荐
- 算法学习----各种排序算法的实现和对比1
- 算法学习----各种排序算法的实现和对比2
- Java基础学习总结(28)——Java对各种排序算法的实现
- 各种基本算法实现小结(五)—— 排序算法
- 经典算法学习——非循环双向链表实现冒泡排序(不带头结点)
- 机器学习经典算法详解及Python实现–决策树(Decision Tree)
- 各种排序算法学习整理 C++实现
- 算法学习一:排序算法实现与算法性能分析
- 【数据结构--经典算法】PHP实现各种经典算法
- 算法基础_8大经典排序算法实现回顾
- [算法学习]常用排序算法实现
- 各种基本算法实现小结(五)—— 排序算法
- 【算法学习】B-Tree编程实现(C++模板类封装)
- 算法学习(1):排序算法-插入排序及python实现
- 用HTML5实现的各种排序算法的动画比较 及算法小结
- C/C++:各种基本算法实现小结(五)—— 排序算法
- 经典算法学习——求次方函数实现
- 各种基本算法实现小结(五)—— 排序算法
- 经典内部排序算法学习总结(算法思想、可视化、Java代码实现、改进、复杂度分析、稳定性分析)
- PHP实现各种经典算法