最小堆的建立及堆排序

堆的建立
堆在很多方面都有运用,这里写一下将一个完全二叉树用一维数组保存后再转化为一个最小堆
代码如下(假如树中的数据都为整数)

#include<stdio.h>
int a[50];
int n;
void swap(int p,int q){//交换函数
	int tmp;
	tmp=a[p];
	a[p]=a[q];
	a[q]=tmp;
}
void siftdown(int i){//处理树的元素
	int t,flag=0;
	while(i*2<=n&&flag==0){//有左子结点
		if(a[i]>a[i*2]) t=2*i;
		else t=i;
		if(i*2+1<=n){//有右子结点
			if(a[t]>a[i*2+1]) t=2*i+1;
		}
		if(t!=i){//不相等则父结点大于某个更小的子结点
			swap(t,i);//交换
			i=t;//继续对这个数进行判断
		}
		else flag=1;//父结点小于子结点,循环结束
	}
}
void creat(){//最小堆的建立函数
	int i;
	for(i=n/2;i>=1;i--){//最后一层无需判断
		siftdown(i);
	}
}
int main()
{
	int i;
	scanf("%d",&n);
	for(i=1;i<=n;i++) scanf("%d",&a[i]);
	creat();
	return 0;
}

以上就是将一个完全二叉树转化为最小堆的过程,下面再介绍在最小堆建立完成后的堆排序


堆排序
直接进入代码部分

#include<stdio.h>
int a[50];
int n;
void swap(int p,int q){//交换函数
 	int tmp;
 	tmp=a[p];
 	a[p]=a[q];
 	a[q]=tmp;
}
void siftdown(int i){//处理树的元素
 	int t,flag=0;
 	while(i*2<=n&&flag==0){//有左子结点
  		if(a[i]>a[i*2]) t=2*i;
  		else t=i;
  		if(i*2+1<=n){//有右子结点
   			if(a[t]>a[i*2+1]) t=2*i+1;
  		}
  		if(t!=i){//不相等则父结点大于某个更小的子结点
   			swap(t,i);//交换
   			i=t;//继续对这个数进行判断
  		}
  		else flag=1;//父结点小于子结点,循环结束
 	}
}
void creat(){//最小堆的建立函数
	int i;
 	for(i=n/2;i>=1;i--){//最后一层无需判断
  		siftdown(i);
 	}
}
int del(){//取出堆顶元素并删除
	int t;
 	t=a[1];
 	a[1]=a[n];
 	n--;
 	siftdown(1);
 	return t;
}
int main()
{
 	int i,t;
 	scanf("%d",&n);
 	t=n;
 	for(i=1;i<=n;i++) scanf("%d",&a[i]);
 	creat();
 	for(i=1;i<=t;i++) printf("%d ",del());
 	return 0;
}

堆排序的时间复杂度和快速排序一样,也是O(NlogN)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值