剑指offer 数据结构之树

大部分涉及的树都是二叉树
一般树的遍历方式如下:

  • 前序遍历: 先访问根节点, 再访问左子节点, 最后访问右子节点
  • 中序遍历: 先访问左子节点, 再访问根节点, 最后访问右子节点
  • 后序遍历: 先访左子节点, 再访问右子节点, 最后访问根节点

重建二叉树

给你一个二叉树的前序遍历和中序遍历, 请重建二叉树

根据 前序遍历 和 中序遍历 的结果, 可以求得树的根节点以及两个子树的大小

那么剩下的就是递归

#include <bits/stdc++.h>
using namespace std;

struct Node {
    
    
    int value;
    Node* left = NULL;
    Node* right = NULL;
    Node(int value) {
    
    
    	this->value = value;
    	left = NULL;
    	right = NULL;
	}
};

Node* buildTree(vector<int> pre, vector<int> in) {
    
    
	if(pre.size() == 0 || in.size() == 0) return NULL;
	// 找根节点, 并确定在 in 中的位置
	int index = 0;
	for(; index < in.size(); index++) {
    
    
		if(in[index] == pre[0]) break;
	}
	//如果没有找到根节点
	if(index == in.size()) {
    
    
		cout << "invalid input" << endl;
		return NULL;
	}
	// 找到了根节点, 开始构建
	Node* root = new Node(pre[0]);
	//根据中序遍历将根节点左右两侧一分为二,根节点的左侧为左子树,右侧为右子树
    vector<int> pre_left,pre_right;
    vector<int> in_left,in_right; 
    //先将前序、中序中根节点的左右子树记录下来
    for (int j = 0; j < index; j++) {
    
    
        pre_left.push_back(pre[j + 1]);
        in_left.push_back(in[j]);
    }
    for (int j = index + 1; j < in.size(); j++)
    {
    
    
        pre_right.push_back(pre[j]);
        in_right.push_back(in[j]);
    }
    //递归构造左右子树
    root->left = buildTree(pre_left, in_left);
    root->right = buildTree(pre_right, in_right);

    return root;
}
int main() {
    
    
	return 0;
}

当然, 给你 后序遍历 + 中序遍历 思想也是一样的
注意 给你 前序遍历 和 后序遍历 不能确定二叉树

Guess you like

Origin blog.csdn.net/qq_45560445/article/details/116644119