排序算法总结

来源:互联网 发布:小精灵字幕软件下载 编辑:程序博客网 时间:2024/05/31 13:16
#ifndef SORT_H#define SORT_H#include<iostream>using namespace std;//内部排序分为五大类,分别为插入排序、交换排序、选择排序、归并排序以及分配排序//插入排序又可分为直接插入排序(insertSort/binInsertSort)与希尔排序(shellSort)//直接插入排序//最好的情况:原始序列是一个按值递增序列时,时间复杂度O(n)//最坏的情况:原始序列是一个按值递减序列时,时间复杂度O(n^2)//平均时间复杂度O(n^2)//整个排序过程只需要一个辅助空间temp,所以空间复杂度O(1),就地排序//属于稳定性排序方法void insertSort(int* arr,int n){int temp=0;int j=0;for(int i=1;i<n;++i){temp=arr[i];j=i-1;while(j>=0 && arr[j]>temp){arr[j+1]=arr[j];j=j-1;}arr[j+1]=temp;}}//希尔排序//希尔排序的时间性能优于直接插入排序的原因//1.当原始序列基本有序时直接插入排序所需的比较和移动次数均较少//2.当n值较小时,n和n^2的差别也较小,即直接插入排序的最好时间复杂度O(n)和最坏时间复杂度O(n^2)差别不大//3.在希尔排序开始时增量d=n/2较大,每组的记录数目少,故各组内直接插入较快,后来增量d逐渐缩小,各组的记录数目逐渐增多,但是经过上次的排序,使序列接近于有序状态,所以新的一趟排序过程也较快//希尔排序属于不稳定性排序void shellSort(int* arr,int n){for(int d=n/2;d>=1;d=d/2){int j=0;int temp=0;for(int i=d;i<n;++i){temp=arr[i];j=i-d;while(j>=0&&arr[j]>temp){arr[j+d]=arr[j];j=j-d;}arr[j+d]=temp;}}}//交换排序可以分为冒泡排序(bubbleSort)和快速排序(quickSort)//冒泡排序//最好的情况:原始序列是一个按值递增序列时,时间复杂度O(n)//最坏的情况:原始序列是一个按值递减序列时,时间复杂度O(n^2)//平均时间复杂度O(n^2)//空间复杂度O(1),就地排序//属于稳定性排序方法void bubbleSort(int* arr,int n){int flag=0;int temp=0;for(int i=1;i<n;++i){flag=0;for(int j=0;j<n-i;++j){if(arr[j]>arr[j+1]){temp=arr[j+1];arr[j+1]=arr[j];arr[j]=temp;flag=1;}}if(flag==0)return;}}//快速排序//最好的情况:每趟排序后,分界元素正好定位在序列的中间,从而把当前参加排序的序列分成大小相等的前后两个子序列,每次划分比较次数不大于n,需要经过lgn次的划分,所以最好的情况下,时间复杂度为O(nlgn)//最坏的情况:原始序列在有序的情况下,快速排序的方法用时最长,此时,第一趟排序经过n-1次比较,将第一个元素仍确定在原来的位置上,并得到一个长度为n-1的子序列;第二趟排序经过n-2次比较,将第2个元素确定在它原来的位置上,又得到一个长度为n-2的子序列;以此类推,其最坏的i时间复杂度为O(n^2)//平均时间复杂度为O(nlgn)//空间复杂度:快速排序在系统内部需要一个栈来实现递归。若每次划分较为均匀,则其递归树的高度为O(lgn),故递归后需栈空间为O(lgn)。最坏情况下,递归树的高度为O(n),所需的栈空间为O(n)。//属性不稳定性排序方法int getQuick(int* arr,int begin,int end){int temp=0;while(begin!=end){while(end>begin && arr[end]>=arr[begin])end=end-1;if(end==begin)return begin;temp=arr[end];arr[end]=arr[begin];arr[begin]=temp;begin=begin+1;while(end>begin && arr[end]>=arr[begin])begin=begin+1;if(end==begin)return begin;temp=arr[end];arr[end]=arr[begin];arr[begin]=temp;end=end-1;}return begin;}void quickSort(int* arr,int begin,int end){if(begin<end){int num=getQuick(arr,begin,end);quickSort(arr,begin,num-1);quickSort(arr,num+1,end);}}//选择排序分为直接选择排序(selectSort)和堆排序(heapSort)//直接选择排序//无论序列中元素的初始排列状态如何,第i趟排序要找出值最小元素都需要进行n-i次元素之间的比较,总共的比较次数为n*(n-1)/2。这说明选择排序法所进行的元素之间的比较次数与序列的原始状态无关,可以确定算法的时间复杂度为O(n^2)//选择排序法属于不稳定性排序方法void selectSort(int* arr,int n){int min=0;int temp=0;for(int i=1;i<n;++i){min=arr[i-1];for(int j=i-1;j<n;++j){if(arr[min]>arr[j])min=j;}temp=arr[i-1];arr[i-1]=arr[min];arr[min]=temp;}}//堆排序//时间复杂度O(nlgn)//空间复杂度O(1)//属于不稳定性排序void adjust(int* arr,int n,int m){//从i=1开始的序列int temp=arr[m];int i=2*m;while(i<=n){if(i<n&&arr[i+1]>arr[i]) ++i;if(arr[i]<=temp){arr[i/2]=temp;return;}arr[i/2]=arr[i];i=i*2;}arr[i/2]=temp;}void buildHeap(int* arr,int n){for(int i=n/2;i>=1;--i)adjust(arr,n,i);}void print(int* arr,int n);void heapSort(int* arr,int n){int temp=0;buildHeap(arr,n);print(arr,9);for(int i=1;i<n;++i){temp=arr[1];arr[1]=arr[n-i+1];arr[n-i+1]=temp;adjust(arr,n-i,1);}}void print(int* arr,int n){for(int i=0;i<n;++i){cout<<arr[i]<<" ";}cout<<endl;}#endif SORT_H

原创粉丝点击