期末程序复习之树的小测试
1:从下至上按层遍历二叉树
【问题描述】
给定一颗二叉树,要求从下至上按层遍历二叉树,每层的访问顺序是从左到右,每一层单独输出一行。
【输入形式】
广义表表示的二叉树,结点元素类型为整型,且都大于0,例如:1( 2( 3 ( 4, 5 ) ), 6( 7, 8( 9, 10 ) ) )
【输出形式】
从下至上,打印每一层的结点元素值,元素间以空格隔开。每层的访问顺序是从左到右,每一层单独输出一行。
【样例输入】
1(2(3(4,5)),6(7,8(9,10))),字符串内没有空格
【样例输出】
4 5 9 10
3 7 8
2 6
1
题目思路
首先看了一下广义表表示的二叉树,觉得真奇葩,其实就是相邻括号内的两个元素分别是它的左右儿子节点,即a(b,c)
a的左儿子是b,a的右儿子是c
然后这个输出很简单,直接判断是第几层括号内就行了
2:使用前序字符串构建一个二叉树,并中序遍历这棵树。
【问题描述】使用前序字符串构建一个二叉树,并中序遍历这棵树。
字符串使用“#”表示孩子为空的情况。
【输入形式】
abd#g###ce##f##
【输出形式】
dgbaecf
题目思路
这个忘得差不多了,其实很简单,直接模拟题意即可
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=6e3+7;
int n;
char val[maxn<<1],mlval[maxn<<1];
void build(int rt){
scanf("%c",&val[rt]);
if(val[rt]=='#') return ;
build(rt<<1);
build(rt<<1|1);
}
void dis2(int root){
if(val[root]=='#') return ;
dis2(root<<1);
printf ("%c",val[root]);
dis2(root<<1|1);
}
int main(){
build(1);
dis2(1);
}
3:求节点的哈夫曼的带权路径长度
【问题描述】
已知输入一串正整数,正整数之间用空格键分开,请建立一个哈夫曼树,以输入的数字为叶节点,求这棵哈夫曼树的带权路径长度。
【输入形式】
首先输入正整数的个数,然后接下来为接下来的正整数,正整数个数不超过10个
【输出形式】
输出相应的权值
【样例输入】
5 4 5 6 7 8
【样例输出】
69
题目思路
去百度了一下哈夫曼树是什么东西
百度百科:给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
带权路径长度就是节点的权值乘以路径长度
构造哈夫曼树的方法
我原来一直理解错哈夫曼树的意义了,原来是n个数变成n个叶子节点。。。而不是n个节点,构造就是贪心,当有几个合并了之后就把他们当作叶子节点就行了,用优先队列维护贪心过程
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=6e3+7;
int n,ans;
priority_queue<int, vector<int>, greater<int>> que;
int x;
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>x;
que.push(x);
}
int ans = 0;
while (que.size() > 1){
int a, b;
a = que.top();
que.pop();
b = que.top();
que.pop();
ans += (a + b);
que.push(a + b);
}
printf("%d\n", ans);
}
推荐阅读