11.10~11.11根据后序与中序序列重建二叉树,构建哈夫曼树(PTA)

后序为左右根,中序为左根右。

如果是空树,就直接返回。

找到根节点在中序遍历中的位置

由于是后序遍历,即左右根,所以根节点一定在后序的最后

n表示根节点在后序遍历中的位置

然后,在每层递归的循环中找到根节点在中序遍历中的位置,就可以划分出左子树与右子树

如果在中序遍历的第I位,切割中序左数组和中序右数组

切割后序数组,切成后序左数组和后序右数组

递归处理左区间和右区间

注意中序中的左子树和后序中的左子树大小是一样大的,由于中序和后序最先访问的都是左,所以序列中前一段都是根下的左子树区间里的,只不过左子树内部的结点顺序有所不同,不过都是树的根节点的左子树结点

#include
#include
#include
#include
#include
using namespace std;
struct node {
    int data;
    node* lchild, * rchild;
    node(int x) :data(x), lchild(nullptr), rchild(nullptr) {}
};
node* con(vector& i, vector& p) {
    if (p.size() == 0) {
        return nullptr;
    }
    int value = p[p.size() - 1];
    node* root = new node(value);
    if (p.size() == 1) { return root; }
    int d;
    for (d = 0; d < i.size(); d++) {
        if (i[d] == value) {
            break;
        }
    }
    vectorli(i.begin(), i.begin() + d);
    vectorri(i.begin() + d + 1, i.end());
    p.resize(p.size() - 1);
    vectorlp(p.begin(), p.begin() + li.size());
    vectorrp(p.begin() + li.size(), p.end());
    root->lchild = con(li, lp);
    root->rchild = con(ri, rp);
}
void fp(node* root) {
    if (root == nullptr) {
        return;
    }
    cout << root->data << " ";
    fp(root->lchild);
    fp(root->rchild);
}
int high(node* root) {
    if (root == nullptr) {
        return 0;
    }
    return 1 + max(high(root->lchild), high(root->rchild));
}
int main() {
    int n, temp;
    cin >> n;
    vectori;
    vectorp;
    for (int j = 1; j <= n; j++) {
        cin >> temp;
        p.push_back(temp);
    }
    for (int j = 1; j <= n; j++) {
        cin >> temp;
        i.push_back(temp);
    }
    node* root = con(i, p);
    cout << high(root);
    fp(root);

    return 0;
}

结构体构造函数

struct ListNode {
	int val;
	ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}
};

构建哈夫曼树

每次都从最小的根权值里选两个,合并在一起,最后输出大根的权值

你可能感兴趣的:(算法,算法,数据结构)