七大排序

排序的分类:


ps:我在这里实现的排序算法,都是用数组来实现的。

1.插入排序

基本思想:将一个数插入到已排好序的数组中,从而得到一个新的,个数加1的数组。

ps:index为要插入的数的下标,pos为已排好序的数组的最后一个数的下标。

时间复杂度为:O(n^2)

void InsertSort(int* a,size_t n)  //按升序
{
	for(size_t index=1;index<n;++index)
	{
		int pos=index-1;
		int tmp=a[index];
		while(pos>=0&&a[pos]>tmp)
		{
			a[pos+1]=a[pos];
			--pos;
		}
		a[pos+1]=tmp;
	}
}
2.希尔排序

基本思想:它分为预排序和插入排序,预排序:实现跳跃性的排序。

时间复杂度为:O(nlogn)~O(n^2)

void ShellSort(int* a,size_t n)
{
	//1.预排序
	int gap=n;
	while(gap>1)
	{
		gap=gap/3+1;  
		for(int index=gap;index<n;++index)
		{
		    int tmp=a[index];
			int pos=index-gap;
			while(pos>=0&&a[pos]>tmp)
			{
				a[pos+gap]=a[pos];
				pos-=gap;
			}
			a[pos+gap]=tmp;
		}
		
	}
	//2.插入排序
	InsertSort(a,n);
	
}
3.选择排序

基本思想:每一趟选出一个最小值和最大值,分别插入到左右两边的位置。

时间复杂度:O(n^2)

void SelectSort(int* a,size_t n)
{
	int left=0;
	int right=n-1;
	int min,max;
	while(left<right)
	{
		min=max=left;
		for(size_t i=left;i<=right;++i)
		{
			if(a[i]<a[min])
				min=i;
			if(a[i]>a[max])
				max=i;
		}
		swap(a[left],a[min]);
		if(left==max)
			max=min;
		swap(a[right],a[max]);
		left++;
		--right;
	}
}

4.堆排序

基本思想:将待排序的序列构成一个大堆,此时,整个序列的最大值就在堆顶,将它与堆数组的最后一位数交换,此时末尾就是最大值,将剩余的n-1个数重新调整为大堆,就会得到次大值,在交换,反复执行,就会得到一个语序序列。

时间复杂度为:O(nlogn)

void AdjustDown(int* a,int parent,size_t n)  //建大堆
{
	int sub=parent*2+1;
	while(sub<n)
	{
		if(sub<n-1&&a[sub]<a[sub+1])
		     ++sub;
		if(a[sub]>a[parent])
		{
			swap(a[sub],a[parent]);
	        parent=sub;
            sub=parent*2+1;
		}
		else
			break;
	}
}
void HeapSort(int* a,size_t n)
{
	//建大(小)堆
	for(int i=(n-2)/2;i>=0;--i)
	{
		AdjustDown(a,i,n);
	}
	//排序
	for(int j=n-1;j>0;--j)
	{
		swap(a[0],a[j]);
		AdjustDown(a,0,j);
	}
}

5.冒泡排序

基本思想:亮亮比较相邻的数,如果反序就交换,知道没有反序的数为止。

时间复杂度为:0(n^2)

void BubbleSort(int* a,size_t n)
{
	int flag=false;
	for(int i=0;i<n-1;++i)  //趟数
	{
		for(int j=0;j<n-1-i;++j)
		{
			if(a[j]>a[j+1])
			{
				swap(a[j],a[j+1]);
				flag=true;
			}
		}
		if(flag==false)
			break;
	}
}

6.快速排序

基本思想:通过一趟排序将待排序的序列分割为独立的两部分,其中一部分的值均比另一部分的值小,则可分别对这两部分值继续进行排序,以达到整个序列有序的目的。

时间复杂度为:O(nlogn)


递归的写法:

void QuickSort(int* a,int begin,int end)
{
	//一趟排序
	//int pivo=PartSort1(a,begin,end);
	//int pivo=PartSort2(a,begin,end);
	int pivo=PartSort3(a,begin,end);

	if(begin<pivo-1)  //不止一个数
		QuickSort(a,begin,pivo-1);
	if(pivo+1<end)
		QuickSort(a,pivo+1,end);
}
单趟排序有三种方法:

(1).左右指针法

//左右指针法
int PartSort1(int* a,int begin,int end)
{
	int left=begin;
	int right=end;
	//int key=a[end];

	//三数取中法
	int mid=GetMidNum(a,begin,end);
	swap(a[mid],a[end]);
	int key=a[end];

	while(left<right)
	{
		while(left<right&&a[left]<=key)
			left++;
		while(left<right&&a[right]>=key)
			right--;
		if(left<right)
			swap(a[left],a[right]);
	}
	swap(a[left],a[end]);
	return left;
}
(2).挖坑法

//挖坑法
int PartSort2(int* a,int begin,int end)
{
	//int key=a[end];

	//三数取中法
	int mid=GetMidNum(a,begin,end);
	swap(a[mid],a[end]);
	int key=a[end];

	int left=begin;
	int right=end;
	while(left<right)
	{
		while(left<right&&a[left]<=key)
			left++;
		a[right]=a[left];
		while(left<right&&a[right]>=key)
			right--;
		a[left]=a[right];
	}
	a[left]=key;
	return left;
}
(3).前后指针法

//前后指针法
int PartSort3(int* a,int begin,int end)
{
	int prev=begin-1;
	int cur=begin;//找比key小的值就停下
	int mid=GetMidNum(a,begin,end);
	swap(a[mid],a[end]);
	int key=a[end];
	while(cur<end)
	{
		if(a[cur]<key&&++prev!=cur)
			swap(a[prev],a[cur]);
		++cur;
	}
	swap(a[++prev],a[end]);
	return prev;
}


非递归的写法:

void QuickSortNonR(int* a,int begin,int end)
{
	stack<int> s;
	s.push (begin);
	s.push (end);
	while(!s.empty ())
	{
		int right=s.top ();
		s.pop();
		int left=s.top();
		s.pop();
		int pivo=PartSort1(a,left,right);
		if(left<pivo-1)//不止一个数
		{
			s.push(left);
			s.push(pivo-1);
		}
		if(pivo+1<end)
		{
			s.push(pivo+1);
			s.push(end);
		}
	}
}


7.归并排序

时间复杂度为:O(nlogn)

void _MergeSort(int* a,int* tmp,int begin,int end)
{
	int mid=begin+(end-begin)/2;
	if(begin<mid)  //不止一个数
	{
		_MergeSort(a,tmp,begin,mid);
	}
	if(mid+1<end)
	{
		_MergeSort(a,tmp,mid+1,end);
	}

	int begin1=begin;
	int end1=mid;
	int begin2=mid+1;
	int end2=end;
	int index=begin;
	while(begin1<=end1&&begin2<=end2)   //两个数组都不为空
	{
		if(a[begin1]<a[begin2])
			tmp[index++]=a[begin1++];
		else
			tmp[index++]=a[begin2++];
	}
	while(begin1<=end1)  //不为空
	{
		tmp[index++]=a[begin1++];
	}
	while(begin2<=end2)  //不为空
	{
		tmp[index++]=a[begin2++];
	}
	for(size_t i=begin;i<=end;++i)
	{
		a[i]=tmp[i];
	}
}
void MergeSort(int* a,size_t n)
{
	int* tmp=new int[n];
	_MergeSort(a,tmp,0,n-1);
	delete[] tmp;
}









            

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值