7-5 堆中的路径 思路分析及代码解析 v1.0
一、前导
1. 需要掌握的知识
- 堆的基本知识
2. 题目信息
题目来源:PTA / 拼题A
题目地址:https://pintia.cn/problem-sets/15/problems/713
二、解题思路分析
1. 题意理解
基础题,小顶堆的代码实现
- 输入数据
5 3 \\向小顶堆中插入5个元素;需要打印3条路径
46 23 26 24 10 \\插入的具体元素
5 4 3 \\打印路径:从数组下标到根节点,这些是数组下标
- 输出数据
24 23 10 \\打印的路径
46 23 10
26 10
- 题意
代码的核心是建堆
2. 思路分析(重点)
- 建小顶堆并打印
三、具体实现
1. 弯路和bug
- 这道题属于基础知识的应用,考察了建堆,个人建议再练习下删除堆中的元素,为后面的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 各分支函数
- 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;
}
- 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;
}
- 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;
}