排序算法的总结

排序算法总结以及实现。

#include <iostream>

using namespace std;
/*
直接插入排序,主要是找到需要插入位置,while循环就是为了找到插入位置。
数组存放从1开始。
算法是稳定的。
性能分析:最佳情况为输入数组已经排好序 O(n),最差为逆序O(n^2);
*/

void Insert_Sort(int *array,int len)
{
	for (int j=2;j<=len;j++)
	{
		int key=array[j];
		int i;
		i=j-1;
		while (i>0&&array[i]>key)
		{
			array[i+1]=array[i];
			i--;
		}
		array[i+1]=key;
	}
}

void swap(int &a,int &b)
{
	int temp=a;
	a=b;
	b=temp;
}
/*
直接选择排序实现,找到最小的放在1位置,以此类推操作后面知道倒数第二个数,此时数组排序完成。
从1开始存
算法稳定性:不稳定。如下例
排序前:
2,4,4*,3
排序后:
2,3,4*,4
时间复杂度:O(n^2)
*/
void Select_Sort(int *array,int len)
{
	int i,j,m;
	for (i=1;i<len;i++)
	{
		m=i;
		for (j=i+1;j<=len;j++)
		{
			if (array[j]<array[m])
			{
				m=j;
			}
		}
		if (m!=i)
		{
			swap(array[i],array[m]);
		}
	}
}

void merge(int *array,int start,int middle,int end)
{
	int len1=middle-start+1;
	int len2=end-middle;
	int *L=new int[len1+1];
	int *R=new int[len2+1];
	int i,j,k;
	for (i=1;i<=len1;i++)
	{
		L[i]=array[start+i-1];
	}
	for (j=1;j<=len2;j++)
	{
		R[j]=array[middle+j];
	}
	i=j=1;
	//k的初始存放位置一定是start开始
	k=start;
	while (i<=len1&&j<=len2)
	{
		if (L[i]>=R[j])
		{
			array[k++]=R[j];
			j++;
		}
		else
		{
			array[k++]=L[i];
			i++;
		}
	}
	while(i<=len1)
	{
		array[k++]=L[i++];
	}
	while (j<=len2)
	{
		array[k++]=R[j++];
	}
}
/*
归并排序:递归到单个元素,然后合并
稳定排序。
复杂度当规模足够大时为O(lgn),最坏情况下要比插入排序(O(n^2))好。
*/
void Merge_Sort(int *array,int start,int end)
{
	if(start<end)
	{
		int middle=(start+end)/2;
		Merge_Sort(array,start,middle);//递归到左边单个元素
		Merge_Sort(array,middle+1,end);//递归到右边单个元素
		merge(array,start,middle,end);//合并两个有序的部分
	}
}
/*
冒泡排序思想每次把最小的元素气泡一样浮起到上面
稳定排序
复杂度:O(n^2)
如果序列已经有序冒泡排序不会时间有优化。
*/
void Bubble_Sort(int *array,int len)
{
	int i,j;
	for (i=1;i<=len;i++)
	{
		for (j=len;j>=i+1;j--)
		{
			if (array[j]<array[j-1])
			{
				swap(array[j],array[j-1]);
			}
		}
	}
}

int partition(int *array,int low,int high)
{
	int pivotkey=array[low];
	while (low<high)
	{
		while (low<high&&array[high]>=pivotkey)
		{
			high--;
		}
		array[low]=array[high];
		while (low<high&&array[low]<=pivotkey)
		{
			low++;
		}
		array[high]=array[low];
	}
	array[low]=pivotkey;
	return low;
}
/*
时间复杂度:最坏情况是划分不对称退化为插入排序效率,为O(n^2)
最好情况为每次划分平均,为O(nlgn)
不是稳定排序算法:例如5 3 3 4 3 8 9 10 11 partition后发现最后一个3元素到最前面。
所以快速排序是一个不稳定的排序算法,不稳定发生在中枢元素和a[j]交换的时刻。
*/
void Quick_Sort(int *array,int start,int end)
{
	int middle;
	if (start<end)
	{
		middle=partition(array,start,end);
		Quick_Sort(array,start,middle-1);
		Quick_Sort(array,middle+1,end);
	}
}

void PrintArray(int *A,int len)
{
	for (int i=1;i<=len;i++)
	{
		cout<<A[i]<<" ";
	}
	cout<<endl;
}

int main()
{
	int len;
	cin>>len;
	int *A=new int[len+1];
	int i;
	for (i=1;i<=len;i++)
	{
		cin>>A[i];
	}
	//数组元素都是从1开始存 
	Insert_Sort(A,len);
	Select_Sort(A,len);
	Merge_Sort(A,1,len);
	Bubble_Sort(A,len);
	Quick_Sort(A,1,len);
	PrintArray(A,len);
	return 0;
}


 选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、归并排序和基数排序是稳定的排序算法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值