排序汇总

//各种排序总结:直接插入排序,折半插入,希尔排序,快速排序,选择排序,冒泡排序,堆排序,归并排序
//稳定性:直接插入排序,折半插入排序,冒泡排序归并排序是稳定的,希尔排序,快速排序不稳定,对于选择排序,每一次都要那样的执行,和序列的组成元素无关
//时间复杂度:O(n^2),O(n^2),O的一点几次幂,O(nlog2n),o(n^2),O(n^2),O(nlog2n),O(nlog2n)


#include <iostream>
using namespace std;
#define N 10

/*插入排序类*/

//直接插入排序:直接插入排序:即每一次把一个数字往前插入一个已经排好序的数组之中。
//算法的时间复杂度是O(n^2);
//稳定排序算法:就是指如果该序列之中未排序之前的两个或者多个数据,在排序之后相对位置还是不会改变
//该直接插入属于稳定排序算法;
/*
void insert(int *a)
{
	for (int i=2;i<=N;++i)
	{
		int key=a[i];
		int j=i-1;
		while (j>0&&a[j]>key)
		{
			a[j+1]=a[j];
			--j;
		}
		a[j+1]=key;
	}
}
int main()
{
	int a[N+1];
	for (int i=0;i<=N;++i)
	{
		cin>>a[i];
	}
	insert(a);
	for (int k=1;k<=N;++k)
	{
		cout<<a[k]<<" ";
	}
	cout<<endl;
}
*/

//折半插入
//对于前面的直接插入的话是要求某一个数字插入到已经排序的队列之中,对于小的数据而言比较不错,但是对于大的数据就不行
//考虑一种折中的折半插入
//时间复杂度:最差情况下还是O(n^2);但是平摊效果比直接插入好
/*int high,low,m,key,j;
void bininsert(int *a)
{
	for (int i=2;i<=N;++i)//和上面一样数组以下标为1开始,而不是0
	{
		high=i-1;
		low=1;
		key=a[i];
		while (low<=high)
		{
			m=(high+low)/2;
			if(a[m]>key)
				high=m-1;
			else 
				low=m+1;
		}
		for(j=i-1;j>=high+1;--j)
			a[j+1]=a[j];
		a[high+1]=key;
	}
}

int main()
{
	int a[N+1];
	for (int i=0;i<=N;++i)
	{
		cin>>a[i];
	}
	bininsert(a);
	for (int k=1;k<=N;++k)
	{
		cout<<a[k]<<" ";
	}
	cout<<endl;
}*/

//希尔排序
//希尔排序是插入排序的一种,只不过是平摊下来的时间复杂度好一点,进行多次直接插入排序,只不过每一次的插入前的序列间隔是逐次减少的
//不是稳定的排序算法;
//时间复杂度为n的一点几次幂
/*int d[N/2];
void shellinsert(int* a,int d)
{
	for (int i=d+1;i<=N;++i)//每一次进行插入d间隔,对于各个数组初始化
	{
		int key=a[i];
		int j;
		if (key<a[i-d])
		{
			for(j=i-d;j>0&&key<a[j];j-=d)
			{
				a[j+d]=a[j];
			}
			a[j+d]=key;//这里简单的把d当做1就和直接插入一样
		}
	}
}
void shell(int *a,int *d)
{
	for(int i=0;i<N;++i)
	{
		shellinsert(a,d[i]);		
	}
}

int main()
{
	int dis;
	int a[N+1];
	for (int j=0;j<=N;++j)
	{
		cin>>a[j];
		}
	for (int i=0;i<N/2;++i)
	{
		cin>>dis;
		d[i]=dis;
	}
	shell(a,d);
	for (int k=1;k<=N;++k)
	{
		cout<<a[k]<<" ";
	}
	cout<<endl;
	
}*/
/*
#include<algorithm>
//快速排序:时间复杂度是最快的,对于一个数组来说,比较快O(nlog2(n))和堆排序一样
//不是稳定的排序算法,但是快速排序是根据冒泡排序修改,冒泡排序是稳定的
int fastsort(int* a,int s,int e)
{
	int i=s-1;
	int key=a[e];
	for (int j=s;j<e;++j)
	{
		if(key>=a[j])
		{
			++i;
			swap(a[j],a[i]);
		}
	}
	
	swap(a[i+1],key);
	return i+1;
}
void fast(int *a,int s,int e)
{ 
	int q;
	if (s<e)
	{
		q=fastsort(a,s,e);
		fast(a,s,q-1);
		fast(a,q+1,e);
	}
}


int main()
{
	int a[N+1];
	for (int i=0;i<=N;++i)
	{
		cin>>a[i];
	}
	fast(a,1,N);
	for (int k=1;k<=N;++k)
	{
		cout<<a[k]<<" ";
	}
	cout<<endl;
}

*/
//选择排序(堆排序是选择排序的一种,等到算法导论复习到第六章再去搞下,下面再就是写一个归并排序,对于计数排序,桶排序,基数排序则看到第十章再去搞,对于鸽巢排序等了解下即可)
//不是稳定的排序算法这个和堆排序一样,时间复杂度O(n^2)
//思想很简单,就是从小到大的找每一趟的最小,放在最前面。
/*#include<algorithm>
void select(int *a)
{
	int min,i,j;
	for (i=1;i<N+1;++i)
	{
		min=i;
		for (j=i+1;j<N+1;++j)
		{
			if(a[min]>a[j])
			{
				min=j;//交换的是下标,注意,如果交换的是数值,就会重复
			}
		}
		if (i!=min)
		{	
			swap(a[i],a[min]);
		}
	}
}

int main()
{
	int a[N+1];
	for (int i=0;i<=N;++i)
	{
		cin>>a[i];
	}
	select(a);
	for (int k=1;k<=N;++k)
	{
		cout<<a[k]<<" ";
	}
	cout<<endl;
}
*/

//最后一个,归并排序;
//归并排序的效率比较高而且,排序的时间复杂度和快速排序一样O(nlog2(n))
//且归并排序使用的是分支法进行解决,核心思想就是把2有序数组归并为一个数组在,如何得到有序的数组呢,算法进行多次的递归分割数组,最后只有一个的时候就是有序
/*void mergearry(int *a,int first ,int mid,int last ,int* temp)
{
	int i=first ,j=mid+1,m=mid,n=last,k=0;
	while (i<=m&&j<=n)
	{
		if (a[i]<=a[j])
		{
			temp[k++]=a[i++];
		}else 
		{
			temp[k++]=a[j++];
		}
	}
	while (i<=m)
	{
		temp[k++]=a[i++];
	}
	while (j<=n)
	{
		temp[k++]=a[j++];
	}
	for (i=0;i<k;++i)
	{
		a[first+i]=temp[i];
	}
}

void mersort(int* a,int first ,int last ,int *temp)
{
	if(first<last)
	{
		int mid=(first+last)/2;
		mersort(a,first,mid,temp);
		mersort(a,mid+1,last,temp);
		mergearry(a,first,mid,last,temp);
	}
}

bool merge(int *a,int n)
{
	int* p=new int [n];
	if(p==NULL)
		return false;
	mersort(a,1,n-1,p);
	delete p;
	return true;
}


int main()
{
	int a[N+1];
	for (int i=0;i<=N;++i)
	{
		cin>>a[i];
	}
	merge(a,N+1);
	for (int k=1;k<=N;++k)
	{
		cout<<a[k]<<" ";
	}
	cout<<endl;
}*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值