目录
一、选择排序
二、冒泡排序
三、插入排序
四、希尔排序
五、快速排序
六、归并排序
七、堆排序
八、代码和调用
一、选择排序
在线性表中,分为排好序的前一部分V和还未排好序U的后一部分,刚开始整个线性表都是未排好序的。选择排序就是在未排好序U集合的部分每次选择最小值换到最前面。然后纳入集合V。
二、冒泡排序
冒泡排序,每次排序比较连续两个相邻的元素,小的交换到前面,大的交换交换到后面,达到每次排序小元素“浮"数组前面或大元素"沉"到数组后面的过程。
三、插入排序
插入排序,分为排好序的前一部分V和还未排好序U的后一部分。从 i=1 开始和 第0个元素比较,如果已经排号序的集合中要比 被比较元素 大,那么往后挪一个位置,最后把被比较元素放在率先比自己小的元素之后。
四、希尔排序
即带有步长的插入排序。最后一次排序的步长必然是1.加入设 步长集合分别为{4,3,1}.代码 原始线性表中每相互间隔为4的元素进行插入排序一次.之后,原始线性表中每相互间隔为3的元素进行插入排序一次,最后原始线性表中每相互间隔为1的元素进行插入排序一次。一般插入排序实际上也就是步长为1的希尔排序。由于插入排序在顺序集合中的时间复杂度能达到 O(n).所以希尔排序就是尽可能的让子集合进行顺序排好序。如果步长集合设置的合适步长 希尔排序的时间复杂度可以降低为O(n(log n)^2)。
五、快速排序
快速排序,每次排序把待排序元素放入到它的最终位置,并且,它的右侧有比它大,左侧都比它小的目的。
具体操作步骤就是 确定好待比较元素后,如果遍历从后往前开始,那么当遍历到元素比待比较元素小时进行交换,接着从交换位置开始从前往后遍历。如果此时遍历到元素比待比较元素大时,进行交换.反复遍历,最后确认好自身位置。
第二次排序时,只要对上一次确定好位置的元素,左边集合和右边集合分别进行快排就行。
六、归并排序
把刚开始元素各自立为一个集合,每个集合都可以已经排好序的集合。接着集合两两合并,通过比较两个集合中的"头"元素,把小的元素移值新合并到新的空间中成为一个新的集合。不断合并最后合并成一个大集合。
七、堆排序
构建从小到大排序的线性表,需要构建一个"大顶堆",实际上就是每个父节点都要比子节点大的完全二叉树。对于线性表[0...length] ,按层次映射到完全二叉树中,第n个元素的左孩子2n+1个元素,右孩子第2n+2个元素。
调整成”大顶"步骤如下,两个孩子选出大的孩子,然后和父节点比较如果子节点和父节点大,那么交换。接着和孩子比较,直到比较到叶子节点。在完全二叉树[0....length]中,最后一个非叶子节点的位置是,floor(heaplen/2)-1 。
操作步骤如下。
首先把乱序数组调成大顶堆。从floor(heaplen/2)-1 到 0 进行调整。
当调整成大顶堆时,堆顶元素和最后一个元素进行交换,把推顶大元素弄到数组后边去。然后调整推顶节点即可。
八、代码和调用
hpp
//// Created by Administrator on /11/2.//#ifndef SMARTDONGLIB_SORT_H#define SMARTDONGLIB_SORT_H#include "const.h"#include <vector>//#include<cstring>#include <iostream>namespace SmartDongLib{class Sort{public:enum sortMethod {SelectionSort =1,BubbleSort ,InsertionSort,ShellSort,QuickSort,MergingSort=6,HeapSort};template<class _tp,class _RandomAccessIterator , class _Compare>static void sort(_RandomAccessIterator _first, _RandomAccessIterator _last,_Compare _comp ,sortMethod method=QuickSort){switch (method) {case SelectionSort:selectionSort(_first,_last,_comp);break;case BubbleSort:bubbleSort(_first,_last,_comp);break;case InsertionSort:insertionSort(_first,_last,_comp);break;case ShellSort:shellSort(_first,_last,_comp);break;case QuickSort:quickSort(_first,_last-1,_comp);break;case MergingSort:mergingSort<_tp>(_first,_last,_comp);case HeapSort:heapSort(_first,_last,_comp);default:quickSort(_first,_last-1,_comp);break;}}template<class _tp,class _RandomAccessIterator>static void sort(_RandomAccessIterator _first, _RandomAccessIterator _last,sortMethod method=QuickSort){switch (method) {case SelectionSort:selectionSort(_first,_last);break;case BubbleSort:bubbleSort(_first,_last);break;case InsertionSort:insertionSort(_first,_last);break;case ShellSort:shellSort(_first,_last);break;case QuickSort:quickSort(_first,_last-1);break;case MergingSort:mergingSort<_tp>(_first,_last);case HeapSort:heapSort(_first,_last);default:quickSort(_first,_last-1);break;}}protected:/*** <p>堆排序.每次选择最值放到子节点前* @tparam _RandomAccessIterator 线性表地址类型* @tparam _Compare 比较函数类型* @param _first线性表起始地址* @param _last 线性表结束地址* @param _comp 比较函数*/template< class _RandomAccessIterator, class _Compare>static void heapSort(_RandomAccessIterator _first, _RandomAccessIterator _last,_Compare _comp ){int heaplen =_last - _first;//把无序堆建立成有序堆,从最后一个节点的父节点 heaplen -1,堆的一半开始调整for (int i = heaplen/2 -1 ; i >= 0 ; --i) {HeapAdjust(_first,i,heaplen-1,_comp);}//有序堆,每次调整后堆顶和最后一元素交换。for (int j = heaplen-1; j >0 ; --j) {iteratorSwap(_first,_first+j);HeapAdjust(_first,0,j-1,_comp);}}template< class _RandomAccessIterator >static void heapSort(_RandomAccessIterator _first, _RandomAccessIterator _last ){int heaplen =_last - _first;//把无序堆建立成有序堆,从最后一个节点的父节点 heaplen -1,堆的一半开始调整for (int i = heaplen/2 -1 ; i >= 0 ; --i) {HeapAdjust(_first,i,heaplen-1);}//有序堆,每次调整后堆顶和最后一元素交换。for (int j = heaplen-1; j >0 ; --j) {iteratorSwap(_first,_first+j);HeapAdjust(_first,0,j-1);}}/*** <p>归并排序.每次选择最值放到最前面* @tparam _RandomAccessIterator 线性表地址类型* @tparam _Compare 比较函数类型* @param _first线性表起始地址* @param _last 线性表结束地址* @param _comp 比较函数*/template<class _tp,class _RandomAccessIterator, class _Compare>static void mergingSort(_RandomAccessIterator _first, _RandomAccessIterator _last,_Compare _comp ){Size len = _last -_first;_tp temp[len];Sort::mergeSort(_first,temp,0,len-1,_comp);}template<class _tp,class _RandomAccessIterator>static void mergingSort(_RandomAccessIterator _first, _RandomAccessIterator _last){Size len = _last -_first;_tp temp[len];Sort::mergeSort(_first,temp,0,len-1);}/*** <p>选择排序.每次选择最值放到最前面* @tparam _RandomAccessIterator 线性表地址类型* @tparam _Compare 比较函数类型* @param _first线性表起始地址* @param _last 线性表结束地址* @param _comp 比较函数*/template<class _RandomAccessIterator, class _Compare>static void selectionSort(_RandomAccessIterator _first, _RandomAccessIterator _last,_Compare _comp ){for (_RandomAccessIterator iter = _first ; iter < _last ;iter++){_RandomAccessIterator maxValue = iter;for (_RandomAccessIterator index= iter; index < _last; ++index) {if ( _comp (*index,*maxValue) ){maxValue=index;}}iteratorSwap(maxValue,iter);}}template<class _RandomAccessIterator>static void selectionSort(_RandomAccessIterator _first, _RandomAccessIterator _last){for (_RandomAccessIterator iter = _first ; iter < _last ;iter++){_RandomAccessIterator maxValue = iter;for (_RandomAccessIterator index= iter; index < _last; ++index) {if (*index<*maxValue ){maxValue=index;}}iteratorSwap(maxValue,iter);}}/*** <p> 冒泡排序。每次双循环把最值交换到最前面* @tparam _RandomAccessIterator 线性表地址类型* @tparam _Compare 比较函数类型* @param _first线性表起始地址* @param _last 线性表结束地址* @param _comp 比较函数*/template<class _RandomAccessIterator, class _Compare>static void bubbleSort(_RandomAccessIterator _first, _RandomAccessIterator _last,_Compare _comp ){for (_RandomAccessIterator iter = _last ; iter > _first+1 ;iter--){for (_RandomAccessIterator index= _first; index < iter -1; ++index) {if ( _comp (*(index +1),*index) ){iteratorSwap(index,index +1);}}}}template<class _RandomAccessIterator>static void bubbleSort(_RandomAccessIterator _first, _RandomAccessIterator _last){for (_RandomAccessIterator iter = _last ; iter > _first+1 ;iter--){for (_RandomAccessIterator index= _first; index < iter -1; ++index) {if ( *(index +1)<*index ){iteratorSwap(index,index +1);}}}}/*** <p> 直接插入排序。每次双循环i次表示前 i-1 个数都已经排好序。* @tparam _RandomAccessIterator 线性表地址类型* @tparam _Compare 比较函数类型* @param _first线性表起始地址* @param _last 线性表结束地址* @param _comp 比较函数*/template<class _RandomAccessIterator, class _Compare>static void insertionSort(_RandomAccessIterator _first, _RandomAccessIterator _last,_Compare _comp ){singleShellInsert(_first,_last,_comp,1);}template<class _RandomAccessIterator>static void insertionSort(_RandomAccessIterator _first, _RandomAccessIterator _last){singleShellInsert(_first,_last,1);}/*** <p> 希尔排序,有步长的插入排序* @tparam _RandomAccessIterator* @tparam _Compare* @param _first* @param _last* @param _comp*/template<class _RandomAccessIterator, class _Compare>static void shellSort(_RandomAccessIterator _first, _RandomAccessIterator _last,_Compare _comp){Size len =_last-_first;std::vector<Size> dlta;// int loopnum =(int)(log10(2*len+1) / log10(3) );for (int i = (len>>1); i >1; i=(i>>1) ){dlta.push_back(i);}dlta.push_back(1);for (int j = 0; j < dlta.size(); ++j) {singleShellInsert(_first,_last,_comp,dlta[j]);}}template<class _RandomAccessIterator>static void shellSort(_RandomAccessIterator _first, _RandomAccessIterator _last){Size len =_last-_first;std::vector<Size> dlta;// int loopnum =(int)(log10(2*len+1) / log10(3) );for (int i = (len>>1); i >1; i=(i>>1) ){dlta.push_back(i);}dlta.push_back(1);for (int j = 0; j < dlta.size(); ++j) {singleShellInsert(_first,_last,dlta[j]);}}/*** <p> 快速排序,每一次partitio确定一个元素对应的位置,左右两边序列递归* @tparam _RandomAccessIterator 线性表地址类型* @tparam _Compare 比较函数类型* @param _first线性表起始地址* @param _last 线性表结束地址* @param _comp 比较函数*/template<class _RandomAccessIterator, class _Compare>static void quickSort(_RandomAccessIterator _first, _RandomAccessIterator _last,_Compare _comp){if (_first<_last){_RandomAccessIterator pivotloc = singlePartition(_first,_last,_comp);quickSort(_first,pivotloc-1,_comp);quickSort(pivotloc+1,_last,_comp);}}template<class _RandomAccessIterator>static void quickSort(_RandomAccessIterator _first, _RandomAccessIterator _last){if (_first<_last){_RandomAccessIterator pivotloc = singlePartition(_first,_last);//for (_RandomAccessIterator i = _first; i < _last; ++i) {//std::cout<< *i <<" ";//}//std::cout<<"\n";quickSort(_first,pivotloc-1 );quickSort(pivotloc+1,_last );}}template<class _RandomAccessIterator, class _Compare>static voidmergeSort(_RandomAccessIterator _arr1first, _RandomAccessIterator _arr2first,int s, int t,_Compare _comp) {//把arr1[s...t] 并入到 arr2[s...t];if (s == t) {*(_arr2first + s) = *(_arr1first + s);} else{int m =(s + t )/2;mergeSort(_arr1first,_arr2first,s,m,_comp);mergeSort(_arr1first,_arr2first,m+1,t,_comp);merging(_arr2first,_arr1first,s,m,t,_comp);//memcpy(_arr2first+s,_arr1first+s,(t-s+1)*sizeof(*_arr2first));}}template<class _RandomAccessIterator>static voidmergeSort(_RandomAccessIterator _arr1first, _RandomAccessIterator _arr2first,int s, int t) {//把arr1[s...t] 并入到 arr2[s...t];if (s == t) {*(_arr2first + s) = *(_arr1first + s);} else{int m =(s + t )/2;mergeSort(_arr1first,_arr2first,s,m);mergeSort(_arr1first,_arr2first,m+1,t);merging(_arr2first,_arr1first,s,m,t);//memcpy(_arr2first+s,_arr1first+s,(t-s+1)*sizeof(*_arr2first));}}template<class _RandomAccessIterator, class _Compare>static void singleShellInsert(_RandomAccessIterator _first, _RandomAccessIterator _last,_Compare _comp,Size dk){for (_RandomAccessIterator iter = _first+ dk ; iter < _last ;iter++){auto temp = *iter;_RandomAccessIterator index = iter -dk;//假如前面 iter -1 个都已经排好序 ,现在插第 iter 个// 先把iter的值保存起来 到temp// 然后从 iter -1 开始 和 temp 开始比较,如果小则 index的值往后移// 当比较结果为大时结束循环,把 temp 放入到 当前比较位置的后一个for ( ;index >= _first && _comp(temp , *index); index-=dk) {*(index +dk) = *(index);}*(index +dk) = (temp);}}template<class _RandomAccessIterator >static void singleShellInsert(_RandomAccessIterator _first, _RandomAccessIterator _last,Size dk){for (_RandomAccessIterator iter = _first+ dk ; iter < _last ;iter++){auto temp = *iter;_RandomAccessIterator index = iter -dk;//假如前面 iter -1 个都已经排好序 ,现在插第 iter 个// 先把iter的值保存起来 到temp// 然后从 iter -1 开始 和 temp 开始比较,如果小则 index的值往后移// 当比较结果为大时结束循环,把 temp 放入到 当前比较位置的后一个for ( ;index >= _first && temp < *index; index-=dk) {*(index +dk) = *(index);}*(index +dk) = (temp);}}private:template<class _RandomAccessIterator>static void iteratorSwap(_RandomAccessIterator _elem1, _RandomAccessIterator _elem2){auto temp = *_elem1;*_elem1 = *_elem2;*_elem2 = temp;}template<class _RandomAccessIterator, class _Compare>static _RandomAccessIterator singlePartition(_RandomAccessIterator _first, _RandomAccessIterator _last,_Compare _comp ){auto temp = *_first;while(_first -_last <0){while (_first<_last && _comp(temp,*_last)){--_last;}*_first=*_last;while (_first<_last && _comp(*_first,temp)){++_first;}*_last=*_first;}*_first=temp;return _first;}/*** <p> 找到指定位置* @tparam _RandomAccessIterator* @param _first 包含起始位置* @param _last 包含结束位置* @return*/template<class _RandomAccessIterator >static _RandomAccessIterator singlePartition(_RandomAccessIterator _first, _RandomAccessIterator _last){auto temp = *_first;while(_first -_last <0){while (_first<_last && temp<=*_last){--_last;}*_first=*_last;while (_first<_last && *_first<=temp){++_first;}*_last=*_first;}*_first=temp;return _first;}template<class _RandomAccessIterator, class _Compare>static voidmerging(_RandomAccessIterator _arr1first, _RandomAccessIterator _arr2first, int i, int m, int n,_Compare _comp) {//把arr1[i...mid]和arr1[mid+1...n] 并入到 arr2[i .... n];int j,k; //j属于mid+1...lasti属于i...mid k属于 i...lastfor (j = m+1 ,k=i; i <=m && j <= n ; ++k) {if (_comp(*(_arr1first + i) , *(_arr1first + j))){*(_arr2first + k) = *(_arr1first+ (i++));} else{*(_arr2first + k) = *(_arr1first+ (j++));}}if ( i <=m){//memcpy(_arr2first+k,_arr1first+i,(m-i+1)*sizeof(*_arr2first));for (;k<=n && i<=m ; k++,i++) {*(_arr2first + k) = *(_arr1first+ i);}}if ( j <=n){//memcpy(_arr2first+k,_arr1first+j,(n-j+1)*sizeof(*_arr2first));for (;k<=n && i<=n ; k++,i++) {*(_arr2first + k) = *(_arr1first+ i);}}}template<class _RandomAccessIterator>static voidmerging(_RandomAccessIterator _arr1first, _RandomAccessIterator _arr2first, int i, int m, int n) {//把arr1[i...mid]和arr1[mid+1...n] 并入到 arr2[i .... n];int j,k; //j属于mid+1...lasti属于i...mid k属于 i...lastfor (j = m+1 ,k=i; i <=m && j <= n ; ++k) {if (*(_arr1first + i) < *(_arr1first + j)){*(_arr2first + k) = *(_arr1first+ (i++));} else{*(_arr2first + k) = *(_arr1first+ (j++));}}if ( i <=m){//memcpy(_arr2first+k,_arr1first+i,(m-i+1)*sizeof(*_arr2first));for (;k<=n && i<=m ; k++,i++) {*(_arr2first + k) = *(_arr1first+ i);}}if ( j <=n){//memcpy(_arr2first+k,_arr1first+j,(n-j+1)*sizeof(*_arr2first));for (;k<=n && i<=n ; k++,i++) {*(_arr2first + k) = *(_arr1first+ i);}}}/*** 堆节点"筛选"函数,堆顶自堆底的调整方式* @tparam _RandomAccessIterator* @tparam _Compare* @param _first* @param _last* @param _comp*/template<class _RandomAccessIterator, class _Compare>static void HeapAdjust(_RandomAccessIterator _first, int nodeIndex,int heapLenth,_Compare _comp ){//从小到大排序用大顶堆,父节点比自身节点大,假如按层(从0开始)排列,那么 第n个节点的左孩子是 2n+1 2n+2//和自己的孩子进行比较然后交换,接着继续和孩子比较到叶子节点auto temp = *(_first + nodeIndex);for (int i = 2*nodeIndex +1; i <=heapLenth ; i =2 *i+1 ) {if (i < heapLenth && _comp( *(_first+i) , *(_first+i+1)))++i;if (!_comp(temp,*(_first + i)))break;*(_first + nodeIndex) = *(_first+i);nodeIndex = i;}*(_first+nodeIndex) = temp;}/*** 堆节点"筛选"函数,堆顶自堆底的调整方式* @tparam _RandomAccessIterator* @tparam _Compare* @param _first* @param _last* @param _comp*/template<class _RandomAccessIterator >static void HeapAdjust(_RandomAccessIterator _first, int nodeIndex,int heapLenth){//从小到大排序用大顶堆,父节点比自身节点大,假如按层(从0开始)排列,那么 第n个节点的左孩子是 2n+1 2n+2//和自己的孩子进行比较然后交换,接着继续和孩子比较到叶子节点auto temp = *(_first + nodeIndex);for (int i = 2*nodeIndex +1; i <=heapLenth ; i =2 *i+1 ) {if (i < heapLenth && *(_first+i)< *(_first+i+1) )++i;if (! temp<*(_first + i) )break;*(_first + nodeIndex) = *(_first+i);nodeIndex = i;}*(_first+nodeIndex) = temp;}};}#endif //SMARTDONGLIB_SORT_H
cpp
//// Created by Administrator on /11/2.//#include<iostream>#include "sdalgorithm/util/sort.h"#include <ctime>#include <malloc.h>#include<algorithm>using namespace std;using namespace SmartDongLib;void print(int a[],int size){for (int i = 0; i < size; ++i) {cout<< a[i]<<" ";}cout<<endl;};class C1{public:C1(int a){a_=a;}int a_;};int main(){const int veclen =100000 ;int a[veclen] ;// a.resize(veclen);// int a[10] ={9,34,24,56,31,24,66,3,45,20};// Sort::sort(a.begin(),a+veclen,[](int x,int y){return abs(x-30)<=abs(y-30);},SmartDongLib::Sort::QuickSort);// print(a,10);unsigned seed = time(0);srand(seed);for (int i = 0; i < veclen; ++i) {a[i]=rand();}clock_t startSelectionSort,endSelectionSort;startSelectionSort = clock();Sort::sort<int>(a,a+veclen,SmartDongLib::Sort::SelectionSort);endSelectionSort = clock();cout<<"1.SelectionSort:"<< (double)(endSelectionSort - startSelectionSort)<<"\t isSort:"<<std::is_sorted(a,a+veclen)<<endl;for (int i = 0; i < veclen; ++i) {a[i]=rand();}clock_t startBubbleSort,endBubbleSort;startBubbleSort = clock();Sort::sort<int>(a,a+veclen,SmartDongLib::Sort::BubbleSort);endBubbleSort = clock();cout<<"2.BubbleSort:"<< (double)(endBubbleSort - startBubbleSort)<<"\t isSort:"<<std::is_sorted(a,a+veclen)<<endl;;for (int i = 0; i < veclen; ++i) {a[i]=rand();}clock_t startInsertionSort,endInsertionSort;startInsertionSort = clock();Sort::sort<int>(a,a+veclen,SmartDongLib::Sort::InsertionSort);endInsertionSort = clock();cout<<"3.InsertionSort:"<< (double)(endInsertionSort - startInsertionSort)<<"\t isSort:"<<std::is_sorted(a,a+veclen)<<endl;;for (int i = 0; i < veclen; ++i) {a[i]=rand();}clock_t startShellSort,endShellSort;startShellSort = clock();Sort::sort<int>(a,a+veclen,SmartDongLib::Sort::ShellSort);endShellSort = clock();cout<<"4.ShellSort:"<< (double)(endShellSort - startShellSort)<<"\t isSort:"<<std::is_sorted(a,a+veclen)<<endl;;for (int i = 0; i < veclen; ++i) {a[i]=rand();}clock_t startQuickSort,endQuickSort;startQuickSort = clock();// print(a, veclen);Sort::sort<int>(a,a+veclen,SmartDongLib::Sort::QuickSort);// print(a, veclen);endQuickSort = clock();cout<<"5.QuickSort:"<< (double)(endQuickSort - startQuickSort)<<"\t isSort:"<<std::is_sorted(a,a+veclen)<<endl;;for (int i = 0; i < veclen; ++i) {a[i]=rand();}clock_t startMergingSort,endMergingSort;startMergingSort = clock();Sort::sort<int>(a, a+veclen,Sort::MergingSort) ;endMergingSort = clock();cout<<"6.MergingSort:"<< (double)(endMergingSort - startMergingSort)<<"\t isSort:"<<std::is_sorted(a,a+veclen)<<endl;for (int i = 0; i < veclen; ++i) {a[i]=rand();}// int b[8] = {49,38,65,97,76,13,27,49};clock_t startHeapSort,endHeapSort;startHeapSort = clock();Sort::sort<int>(a, a+veclen,Sort::HeapSort) ;endHeapSort = clock();cout<<"7.HeapSort:"<< (double)(endHeapSort - startHeapSort)<<"\t isSort:"<<std::is_sorted(a,a+veclen)<<endl;// print(a,veclen);for (int i = 0; i < veclen; ++i) {a[i]=rand();}clock_t startSTLSort,endSTLSort;startSTLSort = clock();std::sort(a, a+veclen) ;endSTLSort = clock();cout<<"8.STLSort:"<< (double)(endSTLSort - startSTLSort)<<"\t isSort:"<<std::is_sorted(a,a+veclen)<<endl;}
输出结果