• (树,递归)重建二叉树,二叉树的下一个结点


    树的数据结构:

     

    重建二叉树

    链接: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;
        }
    };
  • 相关阅读:
    LINQ to SQL语句(9)之Top/Bottom和Paging和SqlMethods
    LINQ to SQL语句(8)之Concat/Union/Intersect/Except
    LINQ to SQL语句(7)之Exists/In/Any/All/Contains
    LINQ to SQL语句(6)之Group By/Having
    LINQ to SQL语句(5)之Order By
    LINQ to SQL语句(4)之Join
    LINQ to SQL语句(3)之Count/Sum/Min/Max/Avg
    LINQ to SQL语句(2)之Select/Distinct
    java 开发工具记录
    H5播放器内置播放视频(兼容绝大多数安卓和ios)
  • 原文地址:https://www.cnblogs.com/Bella2017/p/11821657.html
Copyright © 2020-2023  润新知