常用排序算法详解

来源:互联网 发布:保利地产工资待遇知乎 编辑:程序博客网 时间:2024/05/29 16:50

    不论是工作还是平时学习,排序算法是非常重要的,显然对于大量数据,我们仅仅靠冒泡法来进行排序是远远不够的,虽然空间复杂度为o(n),但是时间复杂度为o(n^2),对于大量的数据来说是致命的缺陷,所以需要其他优秀的算法,比如用的比较多的快排、堆排序,插入排序,归并排序等等,STL中的Sort排序算法一般是几个算法结合起来,一般为了防止递归层次太深导致函数调用的时间花费,对于大于一定长度的数据,先进行几次快排算法,如果经过若干次分割后递归层次达到一定的深度后就该用插入排序(可能经过排序有子序列局部有序了,这样能大大加快排序的速度),下面就对这几种排序算法自己子写了一下代码,作为简单的记录:

#include <iostream>#include <string>#include <algorithm>#include <vector>#include <time.h>using namespace std;//插入排序class insert_sort{public:void _insert_sort(int *first,int *last){if(first==last)return ;for(int *i=first+1;i!=last;i++)_linear_insert(first,i);}void _linear_insert(int *first,int *last){int value=*last;if(*last<*first){copy_backward(first,last,last+1);*first=value;}else__unguarded_linear_insert(last,value);}void __unguarded_linear_insert(int *last,int value){int *next=last;next--;while(*next>value){*last=*next;last=next;next--;}*last=value;}};//快速排序class fast_sort{public:void _fast_sort(int *arr,int *last,int len){//为了避免最坏的情况的发生,取中间大小的元素作为分割点if(len>1)//只有一个元素{int medile=_median(*arr,*(arr+(last-arr)/2),*(last-1));//int *last=arr+len;int *tem=_unguarded_partition(arr,last,medile);_fast_sort(arr,tem,tem-arr);_fast_sort(tem,last,last-tem);}}int * _unguarded_partition(int *first,int *last,int pivot){int tem=0;while(true){while(*first<pivot)first++;last--;while(*last>pivot)last--;if(last<=first)return first;tem=*first;*first=*last;*last=tem;first++;}}int _median(const int a,const int b,const int c){if(a<b)if(b<c)return b;else if(a<c)return c;elsereturn a;else if(a<c)return a;else if(b<c)return c;else return b;}};//归并排序class merge_sort{public:vector<int> part_arr(int *arr,int len){vector<int> tem1;if(len<2){tem1.push_back(*arr);return tem1;}tem=merge_arr(part_arr(arr,len/2),part_arr(arr+len/2,len-len/2));return tem;}vector<int> merge_arr(vector<int> arr1,vector<int> arr2){unsigned int i=0,j=0;vector<int> result;while(i<arr1.size()&&j<arr2.size()){if(arr1[i]<arr2[j]){result.push_back(arr1[i]);i++;}else{result.push_back(arr2[j]);j++;}}while(i<arr1.size()){result.push_back(arr1[i]);i++;}while(j<arr2.size()){result.push_back(arr2[j]);j++;}return result;}void print(){unsigned int i=0;while(i<tem.size()){cout<<tem[i]<<" ";i++;}endl(cout);}private://vector<int> result;vector<int> tem;};//堆排序class myheap_sort{public:void heap_sort(int* arr,int len){build_max_heap(arr,len);while(true){int tem=arr[0];arr[0]=arr[len-1];arr[len-1]=tem;len--;if(len==0)break;build_max_heap(arr,len);}}void build_max_heap(int* arr,int len){//堆是完全二叉树for(int i=len/2-1;i>=0;i--){keep_max_heap(arr,i,len);}}void keep_max_heap(int *arr,int i,int len){int left_child=2*i+1;int right_child=2*i+2;int largest=i;if(arr[left_child]>arr[largest]&&left_child<len)largest=left_child;if(arr[right_child]>arr[largest]&&right_child<len)largest=right_child;if(largest!=i){int tem=arr[i];arr[i]=arr[largest];arr[largest]=tem;keep_max_heap(arr,largest,len);}}};int main(){int arr[]={16,0,5,6,11,7,9,1,8,4,19,17,3,18,10,14,12,15,13,2};time_t c_start,c_end;insert_sort s;c_start=clock();s._insert_sort(arr,arr+sizeof(arr)/sizeof(int));c_end=clock();for(int i=0;i<sizeof(arr)/sizeof(int);i++)cout<<arr[i]<<" ";cout<<endl;cout<<"插入排序耗时:"<<c_end-c_start<<"ms"<<endl;cout<<endl;int arr1[]={16,0,5,6,11,7,9,1,8,4,19,17,3,18,10,14,12,15,13,2};fast_sort f;c_start=clock();f._fast_sort(arr1,arr1+sizeof(arr1)/sizeof(int),sizeof(arr1)/sizeof(int));c_end=clock();for(int i=0;i<sizeof(arr1)/sizeof(int);i++)cout<<arr1[i]<<" ";cout<<endl;cout<<"快速排序耗时:"<<c_end-c_start<<"ms"<<endl;cout<<endl;int arr2[]={16,0,5,6,11,7,9,1,8,4,19,17,3,18,10,14,12,15,13,2};merge_sort m;c_start=clock();m.part_arr(arr2,sizeof(arr2)/sizeof(int));c_end=clock();m.print();cout<<"归并排序耗时:"<<c_end-c_start<<"ms"<<endl;cout<<endl;int arr3[]={16,0,5,6,11,7,9,1,8,4,19,17,3,18,10,14,12,15,13,2};myheap_sort h;c_start=clock();h.heap_sort(arr3,sizeof(arr3)/sizeof(int));c_end=clock();for(int i=0;i<sizeof(arr3)/sizeof(int);i++)cout<<arr3[i]<<" ";cout<<endl;cout<<"堆排序耗时:"<<c_end-c_start<<"ms"<<endl;return 0;}

当我随机生成20000个数据时,各算法的运算时间为:(为了方便,我只生成了一个数组,后面排序时数组已经是有序的,因为是有序的所以可能对于一些算法达到最坏情况,比如堆排序):


0 0