常见二叉树基础算法汇总

来源:互联网 发布:c 网络爬虫 编辑:程序博客网 时间:2024/05/16 16:56

1、二叉树的深度

class Solution {public:    int TreeDepth(TreeNode* pRoot)    {        if(!pRoot){            return 0;        }        int a = 1+TreeDepth(pRoot->left);        int b = 1+TreeDepth(pRoot->right);        return (a>b?a:b);    }};

要点:递归,思想简化

2、最大二叉树

描述:给出一个list,构建一个二叉树,其中根节点为list中的最大值
LeetCode

class Solution {public:    TreeNode* constructMaximumBinaryTree(vector<int>& nums) {        if(nums.size()==0)            return nullptr;        auto maxPosition = max_element(nums.begin(), nums.end());        TreeNode *head=new TreeNode(*maxPosition);        vector<int> left_sub(nums.begin(), maxPosition);        vector<int> right_sub(maxPosition+1, nums.end());        head->left = constructMaximumBinaryTree(left_sub);        head->right = constructMaximumBinaryTree(right_sub);        return head;    }};

3、融合两个二叉树

描述:如果两个节点overlap,就将两个节点的和作为新的节点
image

class Solution {public:    TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {        if (!t1) return t2;        if (!t2) return t1;        int value = t1->val + t2->val;        TreeNode *head = new TreeNode(value);        head->left =  mergeTrees(t1->left, t2->left);        head->right =  mergeTrees(t1->right, t2->right);        return head;    }};

4、镜像二叉树(翻转二叉树)

描述:操作给定的二叉树,将其变换为源二叉树的镜像

class Solution {public:    void Mirror(TreeNode *pRoot) {        if(!pRoot){            return;        }        auto temp1 = pRoot->left;        pRoot->left = pRoot->right;        pRoot->right = temp1;        Mirror(pRoot->left);        Mirror(pRoot->right);    }};

要点:不要忘记递归

5、判断二叉树是否是平衡二叉树

描述:平衡二叉树(Self-balancing binary search tree)又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

class Solution {public:    int Tree_depth(TreeNode* pRoot){        if(!pRoot){            return 0;        }        int dep1 = Tree_depth(pRoot->left);        int dep2 = Tree_depth(pRoot->right);        return(dep1>dep2?(dep1+1):(dep2+1));    }    bool IsBalanced_Solution(TreeNode* pRoot) {        if(!pRoot){            return true;        }        int dep1 = Tree_depth(pRoot->left);        int dep2 = Tree_depth(pRoot->right);        int diff = dep1-dep2;        if(diff>1||diff<-1){            return false;        }        bool result = IsBalanced_Solution(pRoot->left)&IsBalanced_Solution(pRoot->right);        return result;    }};

6、对称二叉树

描述:请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。

class Solution {public:    bool isSymmetrical(TreeNode* pRoot)    {        return isSymmetrical(pRoot,pRoot);    }    bool isSymmetrical(TreeNode* pRoot1,TreeNode* pRoot2)    {        if(pRoot1==nullptr&&pRoot2==nullptr)            return true;        if(pRoot1==nullptr||pRoot2==nullptr)            return false;        if(pRoot1->val!=pRoot2->val)            return false;        return isSymmetrical(pRoot1->left,pRoot2->right)&& isSymmetrical(pRoot1->right,pRoot2->left);    }};

要点:首先根节点以及其左右子树,左子树的左子树和右子树的右子树相同,左子树的右子树和右子树的左子树相同即可,采用递归

7、把二叉树打印成多行

class Solution {public:        vector<int> vec;        vector<int> index;        int max_depth(TreeNode* pRoot){            if(!pRoot){                return 0;            }            int dep1 = max_depth(pRoot->left) + 1;            int dep2 = max_depth(pRoot->right) + 1;            return (dep1>dep2?dep1:dep2);        }        void front(TreeNode* pRoot){            if(!pRoot){                return;            }            vec.push_back(pRoot->val);            int layer = max_depth(pRoot);            index.push_back(layer);            front(pRoot->left);            front(pRoot->right);        }        vector<vector<int> > Print(TreeNode* pRoot) {            if(!pRoot){                vector<vector<int> > result;                return result;            }            front(pRoot);            int max_depth = *max_element(index.begin(),index.end());            vector<vector<int> > result(max_depth);            for(int i=0;i<index.size();i++){                result[max_depth-index[i]].push_back(vec[i]);            }            return result;        }};

更简单的解为利用队列先进先出的特性

8、二叉树的下一个结点

描述:给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。

class Solution {public:    TreeLinkNode* GetNext(TreeLinkNode* pNode)    {        if(!pNode){            return nullptr;        }        if(pNode->right==NULL){            if(pNode->next==NULL){                return nullptr;            }            if(pNode==pNode->next->left){                return pNode->next;            }            else{                if(pNode->next==pNode->next->next->left) return pNode->next->next;                else{                    TreeLinkNode* t = pNode->next->next;                    while(t->next!=NULL){                        if(t==t->next->left){                            return t->next;                        }                        t = t->next;                    }                    return nullptr;                }            }        }        else{            TreeLinkNode* r= pNode->right;            if(!r->left){                return pNode->right;            }            else{                TreeLinkNode* l = r;                while(l->left!=NULL){                    l = l->left;                 }                return l;            }        }    }};

9、二叉树中和为某个值的路径

描述:输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。

class Solution {public:    vector<vector<int> > vec;    vector<int> tem;    void subfind(TreeNode* root,int left){        tem.push_back(root->val);        if(left-root->val==0 && !root->left && !root->right){            vec.push_back(tem);        }        else{            if(root->left) subfind(root->left, left-root->val);            if(root->right) subfind(root->right, left-root->val);        }        tem.pop_back();    }    vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {        if(root) subfind(root,expectNumber);        return vec;    }};

10、修剪二叉树

描述:给定一个二叉树及一个上界R和一个下界L,修剪二叉树

image

class Solution {public:    TreeNode* trimBST(TreeNode* root, int L, int R) {        if(!root) return nullptr;        if(root->val < L) return trimBST(root->right, L, R);        if(root->val > R) return trimBST(root->left, L, R);        root->left = trimBST(root->left, L, R);        root->right = trimBST(root->right, L, R);        return root;    }};