数据结构-堆-PTA-7-5 堆中的路径

写本题的时候距离学习堆已经过去了一个月,很多东西都忘得差不多了,本博客为思路重新整理。

堆的主要操作

  1. 首先,堆的出现体现了二叉树的数组储存形式的应用,与传统二叉树相比,这种完全二叉树利用数组下标的特性免去了左右子树的繁复。这种繁复第一体现在树的结构上,第二体现在应用的时候只有单向性,不能快速查找其父节点。
  2. 由此我们首先谈堆的结构。
typedef int ElementType;
typedef struct MinHeap *Heap;
struct MinHeap{
	ElementType *Elements;
	int Size;
	int MaxSize;
};

此处应用了一个数组Elements,这种体现方式便于后续分配内存空间的式子表示。Size就是当前二叉树上有几个元素了,也能实时体现下一个元素该插入到哪里,在实现上就是数组下标。MaxSize就是数组的最大值,即二叉树最多增加到哪里。

与传统的二叉树相比,数组的储存结构免去了左右子树但是增加了当前数组元素个数的记录以及元素最大个数。
3. 空堆的建立

Heap CreateHeap(int Max)
{
	Heap H=(Heap)malloc(sizeof(struct MinHeap));
	H->Elements=(ElementType*)malloc((Max+1)*sizeof(ElementType));
	H->Size=0;
	H->MaxSize=Max;
	H->Elements[0]=-10002;
	
	return H;
}

这里我忽略了哨兵的设置,同时注意哨兵是设小顶堆还是大顶堆的。
错误之处是数组分配空间的时候malloc之前的指针类型不会写。另一个编译没通过的地方,sizeof后面的是ElementType而不是int,虽然二者等价。
另外,我之前经常会忘了在结构分配空间的时候在sizeof后面写一个struct,经常只写一个MaxHeap就会导致编译错误。
4. 从空的堆开始插入新元素

void InsertHeap(Heap H)
{
	int i=++H->Size;
	int tmp;
	
	while(i<=H->MaxSize){
		scanf("%d",&tmp);
		for(;tmp<H->Elements[i/2];i/=2)
		    H->Elements[i]=H->Elements[i/2];
		H->Elements[i]=tmp;
		i=++H->Size;
	}
}

这里我一开始和乱序数组排序成堆搞混了。如果堆一开始是空的,那么插入的时候就可以保证它是有序的,具体思路就是新建一个坑然后从后往前入坑最后将新的元素填入换位后的坑,完成排序。
另,乱序数组排成堆就是从最后一个元素开始,逐个令其i/2的元素检查往下轮换就行。

通过的代码

#include<stdio.h>
#include<stdlib.h>

typedef int ElementType;
typedef struct MinHeap *Heap;
struct MinHeap{
	ElementType *Elements;
	int Size;
	int MaxSize;
};

Heap CreateHeap(int Max)
{
	Heap H=(Heap)malloc(sizeof(struct MinHeap));
	H->Elements=(ElementType*)malloc((Max+1)*sizeof(ElementType));
	H->Size=0;
	H->MaxSize=Max;
	H->Elements[0]=-10002;
	
	return H;
}

void InsertHeap(Heap H)
{
	int i=++H->Size;
	int tmp;
	
	while(i<=H->MaxSize){
		scanf("%d",&tmp);
		for(;tmp<H->Elements[i/2];i/=2)
		    H->Elements[i]=H->Elements[i/2];
		H->Elements[i]=tmp;
		i=++H->Size;
	}
}

void PrintHeap(int Num,Heap H)
{
	int i=1;
	int addr;
	for(;i<=Num;i++){
		scanf("%d",&addr);
		int j=addr;
		for(;j>1;j/=2){
			printf("%d ",H->Elements[j]);
		}
		printf("%d\n",H->Elements[j]);
	}
}

int main()
{
	int N,M;
	scanf("%d%d",&N,&M);
	
	Heap H=CreateHeap(N);
	InsertHeap(H);
	PrintHeap(M,H);
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值