排序之选择排序

简单选择排序

基本操作

1.首先通过n-1次关键字比较,从n个记录中找出关键字最小的记录,将它与第一个记录交换
2.再通过n-2次比较,从剩余的n-1个记录中找出关键字次序最小的记录,将它与第二个记录交换
3.重复上面操作,共进行n-1趟排序后,排序结束

代码

void Select_Sort(Sq_List& L)
	{
		for(int i=0;i<n;i++)
		{
			//找最小值并记录 
			int k=i;
			for(int j=i+1;j<n;j++)
			{
				if(L.r[k].key>L.r[j].key)
					k=j;
			}
			//交换 
			if(k!=i)
			{
				Red_Type temp=L.r[i];
				L.r[i]=L.r[k];
				L.r[k]=temp;
			}
		}
	}

堆排序

基本操作

大根堆的排序:
1.输出堆顶元素,以堆中最后一个元素代替之
2.然后又将根结点与左、右子树的根结点进行比较,并与其中大者进行交换
3.重复上述操作,直至叶子结点,将得到新的堆,称这个从堆顶至叶子的调整过程为“筛选”
堆建立:
单结点的二叉树是堆
在完全二叉树中所有以叶子结点(序号i>n/2)为根的子树是堆
这样,我们只需一次将以序号为n/2,n/2-1……1的结点为根的子树调整为堆即可
(对应由n个元素组成的无序序列,“筛选”只需从第n/2个元素开始)

代码

//堆调整
	//已知R[s...m]中记录的关键字除R[s]之外均满足堆的定义
	//本函数调整R[s]的关键字,使R[s...m]成为一个大根堆 
	void Heap_Adjust(T R[],int s,int m) 
	{
		T rc=R[s];	//不满足堆定义的R[s]拿出来 
		//j是R[s]的左孩子,j+1是右孩子,m是终止结点 
		//每次调整要到叶子结点为止 
		for(int j=2*s,j<=m;j=2*j)	 
		{
			//j在范围内,找比较大的j 
			if(j<m&&R[j]<R[j+1])
				j++;	//j是两个孩子中key最大的 
			if(rc>=R[j])//rc是R[s],R[s]>=R[j],满足堆定义,跳出 
				break;
			R[s]=R[j];//将R[s]和R[j]交换 
			s=j;	//将光标移到j上 
		}
		R[s]=rc;	//此时s的值变化了,相当于做交换 
	}

	void Heap_Sort(T R[])
	{
		int i;
		//堆的建立 
		for(int i=n/2;i>=1;i--)
		{
			Heap_Adjust(R,i,n);	
		} 
		//调整+排序
		//进行n-1次排序 
		for(i=n;i>1;i--)
		{
			Swap(R[1],R[i]);	//将根与最后一个元素交换
			Heap_Adjust(R,1,i-1);	//重新调整为堆 
		} 
	} 
	//交换 
	void Swap(T &a,T &b)
	{
		T temp=a;
		a=b;
		b=temp;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值