(树,递归)重建二叉树,二叉树的下一个结点
树的数据结构:
重建二叉树
链接:https://www.nowcoder.com/questionTerminal/8a19cbe657394eeaac2f6ea9b0f6fcf6
来源:牛客网
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
前序遍历的第一个节点就是树的根节点,所以我们先根据前序遍历序列的第一个数字创建根结点,接下来在中序遍历序列中找到根结点的位置,根节点的左边就是左子树,右边就是右子树,这样就能确定左、右子树结点的数量。在前序遍历和中序遍历的序列中划分了左、右子树结点的值之后,就可以递归地去分别构建它的左右子树。
/** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) { int p = pre.size(); int v = vin.size(); if(p<=0 || v<=0) return NULL; return construct(pre, vin, 0, p-1, 0, v-1); } TreeNode* construct(vector<int>& pre, vector<int>& vin, int st_p, int ed_p, int st_v, int ed_v){ if(st_p>ed_p || st_v>ed_v) return NULL; TreeNode* root = new TreeNode(pre[st_p]); for(int i=st_v; i<=ed_v; i++){ //在中序遍历中找到根结点 if(vin[i] == pre[st_p]){ root->left = construct(pre, vin, st_p+1, st_p+i-st_v, st_v, i-1); root->right = construct(pre, vin, st_p+i-st_v+1, ed_p, i+1, ed_v); break; } } return root; } };
一颗完全二叉树的节点数量为666,那么这棵树上的叶子节点数为 333
链接:https://www.nowcoder.com/questionTerminal/4e2380083eb0483592d5312703d2dfe6
来源:牛客网
设这个完全二叉树有K层,前K-1层有2^9-1=511个节点,最后一层有666-511=155个全是叶子节点;
倒数第二层有2^8=256个节点,其中155/2=77个有两个孩子,第78个有一个孩子,剩256-78=178个叶子节点;
155+178=333个
公式:完全二叉树叶子节点数=向上取整
二叉树的下一个结点
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
https://www.nowcoder.com/questionTerminal/9023a0c988684a53960365b889ceaf5e
做法:三种情况:
1)一个结点有右子树,则它的下一个结点是它的右子树中的最左结点。如b的下一个结点是h
2)一个结点没有右子树,但这个结点时它父结点的左结点时,则它的下一结点是它父结点。如d的下一个结点是b。
3)一个结点没有右子树,且这个结点时它父结点的右结点时,沿着它父结点指针一直向上遍历,直到找到第一个当前节点是父节点左孩子的节点,则这个结点的父结点就是要找的下一个结点。
下面代码把2,3两种情况合并了。
/* struct TreeLinkNode { int val; struct TreeLinkNode *left; struct TreeLinkNode *right; struct TreeLinkNode *next; TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) { } }; */ class Solution { public: TreeLinkNode* GetNext(TreeLinkNode* pNode) { if(pNode==NULL) return NULL; if(pNode->right){ // 一个结点有右子树,则它的下一个结点是它的右子树中的最左结点 TreeLinkNode* t1 = pNode->right; while(t1->left){ t1 = t1->left; } return t1; } while(pNode->next){ if(pNode->next->left == pNode) return pNode->next; pNode = pNode->next; } return NULL; } };