排序:选择排序&堆排序(树形选择排序的改进)

选择排序

1、基本思想:首先在待排序序列中选出最小记录,然后将这个最小的数据元素与第一个记录交换,第一个记录到位后即为第一趟排序;第二趟则为第二个记录到最后一个记录中选最小的记录,之后将所选的最小的记录与第二个记录交换。以此类推,进行n-1趟。即第i趟选择排序是在n-i+1(1=1,2,…,n-1)个记录中进行选择。
2、稳定性:稳定
3、时间复杂度:O(n²),空间复杂度:O(1)
4、代码实现:

#include<stdio.h>
#define MAX 100
void SelectSort(int array[],int n);
int main()
{
	int array[MAX];
	int n,s,q;
	printf("请输入待排序数的个数:\n");
	scanf("%d",&n);
	printf("请输入待排序的数据:\n");
	for(s=0;s<n;s++)
	scanf("%d",&array[s]);
	SelectSort(array,n);/*函数调用*/
	printf("选择排序结果为:\n");
	for(s=0;s<n;s++)  /*输出排序后节点序列*/ 
	printf("%d",array[s]);
}
void SelectSort(int array[],int n)
{
	int k,q,s,temp;
	for(s=0;s<n;s++)
	{
		k=s;  /*k用来记录最小元素位置*/ 
		for(q=s+1;q<n;q++)
		if(array[k]>array[q])
		k=q;
		temp=array[s];
		array[s]=array[k];
		array[k]=temp;
	}
}

堆排序——树形选择排序的改进

树形选择排序(锦标赛排序)

1、基本思想:首先对n个记录的关键字进行两两比较,然后在n/2个较小者之间再进行两两比较,如此重复,直至选出最小的记录为止。
2、方法说明:这个过程可用一棵有n个结点的树表示。每个非终端结点中的数均等于其左右孩子结点中较小的数值,则根结点中的数即为叶子结点的最小数。在输出最小数之后,想选出次小数,仅需将叶子结点中的最小数设为∞,再进行刚才的比较,直至所有记录全部输出为止。(即每一次最小数的选择所形成的树建立过程从最末端叶子开始,根节点即为一次选择所求)
3、时间复杂度:O(n lbn)
4、缺点:辅助存储空间较多、和∞进行多余比较等缺点。

堆排序(原地排序)

1、堆:设有n个元素的序列{k1,k2,…,kn},当且仅当,满足下关系之一时,称之为堆。(ki <= k2i且ki <= k2i+1)或者(ki >= k2i且ki >= k2i+1), (i = 1,2,3,4…n/2)。若某数列为堆,则k1(堆顶元素)必为数列中最小值或最大值,堆顶元素最小的序列称为小堆顶,反之为大堆顶。 若将堆看成一个完全二叉树则根节点为整棵二叉树中的最小或最大值。
2、堆排序基本思想:先将序列建成堆,以根节点与第n个结点交换,调整前n-1个结点重新构造成一个堆,再以根节点与第一个n-1个结点交换。反复执行,直至序列有序。 其中,将n-1个元素建成新堆的过程称为筛选。初始序列建堆过程则为反复进行筛选的过程。
3、时间复杂度(最坏): O(n lbn)
4、稳定性:不稳定
5、代码实现:

void PercDown(int array[],int s,int n)/*序列调整为堆*/
{
	int q;
	int t;
	t=array[s];
	while((q=2*s+1)<n)               /*有左孩子*/ 
	{
		if(q<n-1&&array[q]<array[q+1])
			q++;
		if(t<array[q])
		{
			array[(q-1)/2]=array[q];
			s=q;
		}
		else
			break;
	}
	array[(q-1)/2]=t             ;  /*t放在最后一个位置*/ 
}
void HeapSort(int array[],int n)    /*堆排序*/ 
{
	int s;
	int t;
	s=(n-1)/2;
	while(s>=0)
	{
		PercDown(array,s,n);
		s--;		 
	}
	s=n-1;
	while(s>0)
	{
		t=array[0];                /*交换结点*/ 
		array[0]=array[s];
		array[s]=t;
		PercDown(array,0,s);
		s-- ;
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值