常用排序算法详解

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值