期末程序复习之树的小测试

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);



}


猜你喜欢

转载自blog.csdn.net/m0_46209312/article/details/108075881