7-2 堆的建立

所谓“堆的建立”,是指将已经存在的N个元素调整成最大堆或最小堆。

输入格式:

第一行是一个整数N,表示元素的个数,N<=10000。第二行N个元素的值。

输出格式:

输出2行,第一行是输入序列调整为最大堆后的元素序列,元素之间用空格分开。第二行是输入序列调整为最小堆后的元素序列,元素之间用空格分开。

输入样例:

在这里给出一组输入。例如:

8
7 5 8 4 2 3 6 1

输出样例:

在这里给出相应的输出。例如:

8 5 7 4 2 3 6 1
1 2 3 4 7 8 6 5

代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB

思路:

heapify是维护堆的重要性质,它的输入为一个数组arr和一个下标index,以及堆的大小heapsize,heapify在程序的每一步中从每一个结点与他的子树中选择最大或最小的一个进行交换,使其满足最大堆或最小堆的性质,heapify可以用递归和迭代实现,这里我采用递归的方式
我们可以用自底向上的方法利用过程heapify把一个大小为 N N N的数组转换为最大或最小堆

代码如下:

#include<iostream>
using namespace std;

//交换函数
void swap(int &a,int &b)
{
	int temp = a;
	a = b;
	b = temp;
}
// 大根堆的heapify
void maxHeapify(int arr[],int index,int heapsize)
{
	int left = 2*index+1; //左子树
	while (left < heapsize) 
	{
		int largest = left+1<heapsize && arr[left+1]>arr[left]? 
            left+1:left; //从根,左子树,右子树中选择最大的
		largest = arr[index] < arr[largest]?largest:index;
		if(index == largest)
			break;
		swap(arr[index],arr[largest]);
		index = largest;
		left = 2*index+1;
	}

}
//建立大根堆
void BuildMaxHeap(int arr[],int N){
    for(int i=N/2-1;i>=0;i--){ //自底向上
        maxHeapify(arr,i,N);
    }
}
//小根堆的heapify
void minHeapify(int arr[],int index,int heapsize)
{
	int left = 2*index+1;
	while (left < heapsize) 
	{
		int least = left+1<heapsize && arr[left+1]<arr[left]?
			left+1:left;//从根,左子树,右子树中选择最小的
		least = arr[index] > arr[least]?least:index;
		if(index == least)
			break;
		swap(arr[index],arr[least]);
		index = least;
		left = 2*index+1;
	}

}
//建立小根堆
void BuildMinHeap(int arr[],int N){
    for(int i=N/2-1;i>=0;i--){ //自底向上
        minHeapify(arr,i,N);
    }
}
int main(){
    int N;
    cin>>N;
    int arr1[N],arr2[N];
    for(int i=0;i<N;i++){
        int x;
        cin>>x;
        arr1[i]=x;
        arr2[i]=x;
    }
    BuildMaxHeap(arr1,N);
    for(int i=0;i<N;i++){
        if(i==N-1){
            cout<<arr1[i];
        }
        else{
            cout<<arr1[i]<<" ";
        }
        
    }
    cout<<endl;
    BuildMinHeap(arr2,N);
    for(int i=0;i<N;i++){
        
        if(i==N-1){
            cout<<arr2[i];
        }
        else{
            cout<<arr2[i]<<" ";
        }
    }
}
  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Haru_Yuki

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值