中国矿业大学数据结构实验3

A 二叉链表存储的二叉树

空格代表NULL,这样就可以唯一的确定一个二叉树,先序序列怎么遍历,就怎么建树
(中序,中序。。。。。神入题目)

#include<iostream>
#include<vector>
#include<string>
using namespace std;

struct TreeNode {
    char val;
    TreeNode* lc, * rc;
    TreeNode(char c) : val(c), lc(nullptr), rc(nullptr) {}
};

int idx = 0;

TreeNode* build(string& pre) {
    if (idx >= pre.size() || pre[idx] == ' ') {
        idx++;  
        return nullptr;
    }

    TreeNode* node = new TreeNode(pre[idx++]);
    node->lc = build(pre);  
    node->rc = build(pre); 
    return node;
}

vector<char> preOrder, inOrder, postOrder;


void dfs(TreeNode* root) {
    if (!root) return;

    preOrder.push_back(root->val);
    dfs(root->lc);
    inOrder.push_back(root->val);
    dfs(root->rc);
    postOrder.push_back(root->val);
}


void print(vector<char>& v) {
    for (int i = 0; i < v.size(); i++) {
        cout << (i > 0 ? " " : "") << v[i]; 
    }
}

int main() {
    string s;
    getline(cin, s);

    idx = 0;  
    TreeNode* root = build(s);

    dfs(root);

    print(preOrder);
    cout << endl;
    print(inOrder);
    cout << endl;
    //print(postOrder);
    print(inOrder);
    return 0;
}

B 哈夫曼树

完全可以不用建树,本题只需要计算WPL

完整代码

#include<iostream>
#include<queue>
using namespace std;
int n, w;


int main()
{
	while (cin >> n)
	{
		priority_queue<int, vector<int>, greater<int>> q;
		for (int i = 1; i <= n; i++)
		{
			cin >> w;
			q.push(w);
		}
		int ans = 0;
		for (int i = 1; i <= n - 1; i++)
		{
			int s1 = q.top(); q.pop();
			int s2 = q.top(); q.pop();
			ans += (s1 + s2);
			q.push((s1 + s2));
		}
		cout << ans << endl;
	}

	return 0;
}

C 树的遍历

问题(1) 为什么前序+后序不能唯一的确定一个二叉树

答 :明确pre和post的结构

pre 结构:  [ 根节点 ][ 左子树序列 ][ 右子树序列 ]
post 序列结构:  [左子树序列]  [右子树序列]  [根节点]

如果出现:

pre 结构:  [ 根节点 ][   子树    ]
post 序列结构:  [   子树   ]  [根节点]

这样的情况,我们无法确定“子树”究竟是左还是右,称为“歧义现象”
(ps:题目描述有问题,说是任意一种都可以,实际上是默认右子树)

问题(2) 什么情况下能确定只有一个子树

\(pre[L1,R1]\)的第二个节点\(pre[L1+1]\)是左子树的根,\(post[L2,R2]\)的倒数第二个节点\(post[R2-1]\)是右子树的根
\(pre[L1+1]=post[R2-1]\)时,代表只有一个子树

完整代码

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

int n;
vector<int> in;
bool uniqueTree = true;

void build(vector<int>& pre, int L1, int R1, vector<int>& post, int L2, int R2) {
    if (L1 > R1) return;
    int root = pre[L1];
    if (L1 == R1) {
        in.push_back(root);
        return;
    }
    int leftRoot = pre[L1+1], pos = -1;
    for (int i = L2; i <= R2; i++) {
        if (post[i] == leftRoot) {
            pos = i;
            break;
        }
    }
    if (pos == -1) return;
    int leftSize = pos - L2 + 1;
    if (leftSize == R1 - L1) {
        uniqueTree = false;
        in.push_back(root);
        build(pre, L1+1, R1, post, L2, R2-1);
        return;
    }
    build(pre, L1+1, L1+leftSize, post, L2, pos);
    in.push_back(root);
    build(pre, L1+leftSize+1, R1, post, pos+1, R2-1);
}

int main() {
    cin >> n;
    vector<int> pre(n), post(n);
    for (int i = 0; i < n; i++) cin >> pre[i];
    for (int i = 0; i < n; i++) cin >> post[i];
    build(pre, 0, n-1, post, 0, n-1);
    cout << (uniqueTree ? "Yes" : "No") << endl;
    for (int i = 0; i < in.size(); i++)
        cout << (i ? " " : "") << in[i];
    cout << endl;
    return 0;
}

DE

均为模板,不解释

posted @ 2025-06-17 17:35  _P_D_X  阅读(24)  评论(0)    收藏  举报