不论是工作还是平时学习,排序算法是非常重要的,显然对于大量数据,我们仅仅靠冒泡法来进行排序是远远不够的,虽然空间复杂度为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;
else
return 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个数据时,各算法的运算时间为:(为了方便,我只生成了一个数组,后面排序时数组已经是有序的,因为是有序的所以可能对于一些算法达到最坏情况,比如堆排序):