PTA 堆中的路径 思路分析及代码解析

一、前导

1. 需要掌握的知识

  1. 堆的基本知识

2. 题目信息

题目来源:PTA / 拼题A
题目地址:https://pintia.cn/problem-sets/15/problems/713

二、解题思路分析

1. 题意理解

基础题,小顶堆的代码实现

  1. 输入数据
5 3    \\向小顶堆中插入5个元素;需要打印3条路径
46 23 26 24 10  \\插入的具体元素
5 4 3  \\打印路径:从数组下标到根节点,这些是数组下标
  1. 输出数据
24 23 10  \\打印的路径
46 23 10
26 10
  1. 题意
    代码的核心是建堆

2. 思路分析(重点)

  1. 建小顶堆并打印

三、具体实现

1. 弯路和bug

  1. 这道题属于基础知识的应用,考察了建堆,个人建议再练习下删除堆中的元素,为后面的Huffman Tree创建打基础

2. 代码框架(重点)

堆是一种树结构:完全二叉树,可以通过结构体数组实现

2.1 采用的数据结构

使用结构体数组

typedef int ElementType;  //通过变量ElementType增加代码的灵活性
struct HNode
{
	ElementType *a; 
	int size;
	int capability;
};
typedef struct HNode *Heap;
typedef Heap MinHeap;

2.2 程序主体框架

主要分为三部分:建空堆,插入元素,打印,难点在插入元素

               程序伪码描述
int main()
{	
	1.建空堆
	2.通过循环,插入各个元素
	3.打印
}

2.3 各分支函数

  1. MinHeap Creat(int size); 建一个空堆,结构体数组首元素作为哨兵
typedef struct HNode *Heap;
typedef Heap MinHeap

MinHeap Creat(int size)
{
	MinHeap H;
	H=(MinHeap)malloc(sizeof(struct HNode));
	H->a=(ElementType*)malloc(sizeof(ElementType)*(size+1));
	H->size=0;
	H->capability=size;
	H->a[0]=Min;
	return H;
}
  1. void Insert(MinHeap H,ElementType x); 将元素插入最小堆中,通过for循环进行上滤:和父节点比较,值小的话向上走,直到遇到哨兵
void Insert(MinHeap H,ElementType x)
{
   int i;
   i=++H->size;
   
   for(; x < H->a[i/2]; i=i/2)
   		H->a[i]=H->a[i/2];
   	
   H->a[i]=x;
}
  1. void Print(MinHeap H,int i); 从小顶堆的指定位置向上打印
void Print(MinHeap H,int i)
{
	cout<<H->a[i];
	i=i/2;
	for(;i>0;i=i/2) 
		cout<<" "<<H->a[i];
	cout<<endl;
}

3. 完整编码

#include <cstdlib>
#include <iostream>
using namespace std;

#define  Min -10000

typedef int ElementType;
struct HNode
{
	ElementType *a;
	int size;
	int capability;
};
typedef struct HNode *Heap;
typedef Heap MinHeap;

MinHeap Creat(int size);
void Insert(MinHeap H,ElementType x);
void Print(MinHeap H,int i);

int main()
{
	int N,M,x;
	cin>>N>>M;
	MinHeap H;
	H=Creat(N);
	while(N)
	{
		cin>>x;
		Insert(H,x);
		N--;
	}
	while(M)
	{
		cin>>x;
		//cout<<"Print Func. will start"<<endl;
		Print(H,x);
		M--;
	} 
	
	
	
	return 0;
 } 

MinHeap Creat(int size)
{
	MinHeap H;
	H=(MinHeap)malloc(sizeof(struct HNode));
	H->a=(ElementType*)malloc(sizeof(ElementType)*(size+1));
	H->size=0;
	H->capability=size;
	H->a[0]=Min;
	return H;
}

void Insert(MinHeap H,ElementType x)
{
	int i;
	i=++H->size;
	for(;x<H->a[i/2];i=i/2)
	{
		H->a[i]=H->a[i/2];
	}
	H->a[i]=x;
	//cout<<"Here is Insert"<<endl;
}

void Print(MinHeap H,int i)
{
	//cout<<"Here is Print"<<endl;
	cout<<H->a[i];
	i=i/2;
	for(;i>0;i=i/2) 
		cout<<" "<<H->a[i];
	cout<<endl;
}

2021.10.11 AC代码:编码模拟建堆的步骤;堆是一个完全二叉树,因此可以通过数组进行存储

#include <iostream>
using namespace std;

typedef int ElementType;
#define Min -10001

ElementType* a; //通过数组存储数据. 通过变量标记最后一个元素
ElementType LastIndex = 1; //位置0存储哨兵,实际数据从1开始存储

void Insert(ElementType Value);
void Print(int Index);

int main()
{
	int N, M; cin >> N >> M;

	a = new ElementType[N + 1];
	a[0] = Min;//哨兵

	ElementType Value;
	for (int i = 0; i < N; i++)
	{
		cin >> Value;
		Insert(Value);//建堆 core Func.
	}

	while (M--)
	{
		cin >> Value;
		Print(Value);
	}

	return 0;
}

void Insert(ElementType Value)
{
	a[LastIndex++] = Value;

	int i = LastIndex - 1, Tmp = a[i];

	while (Tmp < a[i / 2] && i>0)
	{
		a[i] = a[i / 2];
		a[i / 2] = Tmp;
		i = i / 2;
	}

	return;
}

void Print(int Index)
{
	cout << a[Index]; Index /= 2;
	while (Index > 0)
	{
		cout << " " << a[Index];
		Index /= 2;
	}
	cout << endl;
	return;
}

四、参考资料

  1. 浙江大学 陈越、何钦铭老师主讲的数据结构
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值