堆树——大顶堆的实现

本文详细介绍了堆树的概念,包括父结点与子节点的键值关系,以及堆的存储方式。通过数组实现堆排序,展示了左儿子和右儿子的计算公式。提供了C++代码实现大顶堆,包括添加元素、获取堆顶元素和使堆顶元素出堆等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

堆树的定义

  • 父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。
  • 每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。

堆的存储

  • 堆排序,通过数组实现

  • 一个点的左儿子等于其下标乘2,右儿子等于下标乘2加1(及a[i]的左儿子a[2i]右儿子a[2i+1])

C++代码实现大顶堆,注释已表明

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
//堆排序,通过数组实现 
//一个点的左儿子等于其下标乘2,右儿子等于下标乘2加1
//及a[i]的左儿子a[2*i]右儿子a[2*i+1]


//以下为大顶堆的实现 
struct heap{
	
	int a[1000005];
	int n; //堆中一共有多少元素 
	
	//添加元素进堆 O(logn) 
	void push(int key){
		a[++n] = key;
		insert(n);
	}
	//对第i个元素进行从下到上的修正 
	void insert(int i){
		if(i == 1)
			return;
		if(a[i] > a[i/2]){
			swap(a[i],a[i/2]);
			insert(i/2);
		}
		return;
	}
	
	//获取对顶元素 O(1) 
	int top(){
		return a[1]; 
	}
	
	//使堆顶元素出堆 
	void pop(){
		swap(a[n],a[1]);
		n--;
		repair(1);
	}
	//对第i个元素进行从上到下的修正 
	void repair(int i){
		//获取孩子结点中元素最大的下标 
		int maxIndex = 0;
		if(2*i+1<=n)
			maxIndex = a[2*i]>a[2*i+1]?2*i:2*i+1;
		else if(2*i==n)
			maxIndex = 2*i;
		
		if(a[i]<a[maxIndex] && maxIndex!=0){
			swap(a[i],a[maxIndex]);
			repair(maxIndex);
		}
	}
};

heap h;
int main(){
	int i,j,b;
	int n,x;
	cin>>n;
	for(i=1;i<=n;i++){
		scanf("%d",&x);
		h.push(x);
	}
	for(i=n;i>=1;i--){
		b = h.top();
		printf("%d ",b);
		h.pop();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值