Leetcode 面试题07 重建二叉树

题目链接
Leetcode 面试题07 重建二叉树

题目要求
输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

例如,给出

前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:

     3
    / \
   9  20
     /  \
    15   7

分析

  • 遍历顺序:前序(根-左-右),中序(左-根-右)
  • 前序遍历的第一个节点一定是根节点,中序遍历的左右位置代表节点在二叉树中左右相对位置。
  • 按前序遍历顺序创建二叉树,节点生成顺序为前序遍历顺序。每次新生成的节点,根据中序遍历确定其位置。
  • 当前前序遍历节点下标为pr,下一个节点,即新生成的节点下标为pr+1
    使用堆栈保存之前生成的节点,当新生成的节点确定位置并加入二叉树后,将节点压栈。
  • 利用中序遍历中pr和pr+1节点值对应位置判断新节点位置,当pr+1节点位置inNext<inCur,说明新节点在当前遍历节点的左边,当前遍历节点左孩子指针指向新节点。
  • 当inNext>inCur,说明新节点在当前遍历节点及当前遍历节点到根节点间的某一个节点右边。该位置应该在最后一个满足inNext>inStack处,inStack为之前压栈节点所在中序遍历序列中位置。
  • 采用迭代法进行二叉树建立。

代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if(preorder.size() == 0) return NULL;
        TreeNode* root = new TreeNode(preorder[0]);
        TreeNode* stack[5001];
        TreeNode* nodeNow = NULL;
        TreeNode* nodeNext = NULL;
        nodeNow = root;
        int top = 0;
        stack[++top]= nodeNow;
        int pr,i;
        vector<int>::iterator itInCur,itInNext,itInStack;
        for(pr=0;pr<preorder.size()-1; pr++){
            nodeNext = new TreeNode(preorder[pr+1]);
            itInCur = find(inorder.begin(), inorder.end(), preorder[pr]);
            itInNext = find(inorder.begin(), inorder.end(), preorder[pr+1]);
            if(itInNext<itInCur){
                nodeNow->left = nodeNext;
                stack[++top]= nodeNext;
                nodeNow = nodeNext;
            }
            else{
                if(top!=0){
                    i = top;
                    do{
                        itInStack = find(inorder.begin(), inorder.end(), stack[i]->val);
                        if(itInStack<itInNext) i--;
                    }while(i!=0 && itInStack<itInNext);
                    top = i + 1;
                    stack[top]->right = nodeNext;
                    top--;
                    stack[++top]= nodeNext;
                    nodeNow = nodeNext;
                }
            }
        }
        return root;
    }
};

扩展
只采用前序遍历进行二叉树创建,空节点用“#”表示,则上面的用例表示为[3,9,#,#,20,15,#,#,7,#,#]
创建时采用堆栈进行迭代

代码

Status CreateBiTree(BiTree T, char *String) {//用先序序列建立二叉链表
	//String保存输入字符,按先序序列,无空格进行输入,‘#’代表结点为空。根据输入字符进行二叉树创建
	BiTree stack[100], Tr, Tq;
	int i = 1, top = 0, n = 1;
	T->data.num = 0;
	T->lchild = T->rchild = NULL;
	if (String[0] == '#') {//若树根不存在,返回不执行
		return INFEASTABLE;
	}

	Tr = (BiTree)malloc(sizeof(BiTNode));//为当前指针分配存储空间
	Tr->data.value = String[0];	//为当前节点赋值
	Tr->data.num = 1;	//为当前节点打标记
	Tr->lchild = Tr->rchild = NULL;

	T->lchild = Tr;	//将当前树根结点指针赋给*T的左孩子
	stack[top] = Tr;//根节点入栈
	while (String[i] != '\n') { //输入字符还未读取完
		if (String[i] != '#') {//读入字符不为空‘#’
			Tr = (BiTree)malloc(sizeof(BiTNode));
			Tr->data.value = String[i];
			Tr->data.num = n+1;
			Tr->lchild = Tr->rchild = NULL;
			while (stack[top]->rchild != NULL ) top--;//退回至子节点未满的结点上
			if (top <= -1) return FALSE;
			Tq = stack[top];//栈顶元素赋值给Tq
			stack[++top] = Tr;//当前元素进栈
			if (String[i - 1] != '#') Tq->lchild = Tr;
			else {
				Tq->rchild = Tr;
			}
			n++;
		}
		else {//读入字符为空‘#’
			while (stack[top]->rchild != NULL) top--;
			Tq = stack[top];
			if (String[i - 1] != '#')//若前一字符不为空,则将栈顶元素左孩子赋空
				Tq->lchild = NULL;
			else {//前一字符为空,将栈顶元素右孩子赋空值,栈顶元素退栈,栈顶指针左移
				Tq->rchild = NULL;
				top--;
			}
		}
		i++;//下一个字符
	}
	T->data.num = n;	//头结点保存二叉树结点数
	return OK;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值