树总结

文章目录

  • 前序遍历
  • 中序遍历
  • 后序遍历
  • 层序遍历
  • [层次遍历 II](https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/)
  • 锯齿形层次遍历
  • 树的子结构
  • 二叉树的深度
  • 二叉树的镜像
  • 二叉树的下一节点
  • 重建二叉树
  • [面试题68 - I. 二叉搜索树的最近公共祖先](https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-zui-jin-gong-gong-zu-xian-lcof/)
  • [113. 路径总和 II](https://leetcode-cn.com/problems/path-sum-ii/)
  • [257. 二叉树的所有路径](https://leetcode-cn.com/problems/binary-tree-paths/)
  • [129. 求根到叶子节点数字之和](https://leetcode-cn.com/problems/sum-root-to-leaf-numbers/)
  • [222. 完全二叉树的节点个数](https://leetcode-cn.com/problems/count-complete-tree-nodes/)
  • [226. 翻转二叉树](https://leetcode-cn.com/problems/invert-binary-tree/)
  • [108. 将有序数组转换为二叉搜索树](https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/)
  • [114. 二叉树展开为链表](https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list/)
  • [剑指 Offer 36. 二叉搜索树与双向链表](https://leetcode-cn.com/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof/)
  • [剑指 Offer 54. 二叉搜索树的第k大节点](https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof/)
  • 验证二叉搜索树

前序遍历

  • 递归
/**
 * 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:
    vectorres;
    vector preorderTraversal(TreeNode* root) {
        if(root)
        {
            res.push_back(root->val);
            preorderTraversal(root->left);
            preorderTraversal(root->right);
        }   

        return res;   

    }
};
  • 迭代
/**
 * 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:
    vector preorderTraversal(TreeNode* root) {
        vectorres;
        if(root==NULL)
            return res;
        stackst;
        st.push(root);
        while(!st.empty())
        {
            TreeNode* node=st.top();
            st.pop();
            res.push_back(node->val);
            if(node->right) st.push(node->right);
            if(node->left)  st.push(node->left);
        }

        return res;

    }
};

中序遍历

  • 递归

    /**
     * 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:
        vectorres;
        vector inorderTraversal(TreeNode* root) {
            if(root)
            {
                inorderTraversal(root->left);
                res.push_back(root->val);
                inorderTraversal(root->right);
            }   
    
            return res;   
    
        }
    };
    
  • 迭代

    /**
     * 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:
        vector inorderTraversal(TreeNode* root) {
            vectorres;
            if(root==NULL)
                return res;
            stackst;
            TreeNode* node=root;
            while(node || !st.empty())
            {
                while(node)
                {
                    st.push(node);
                    node=node->left;
                }
    
                node=st.top();
                st.pop();
                res.push_back(node->val);
                node=node->right;
    
            }
    
            return res;
            
        }
    };
    
    /**
     * 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:
        vector inorderTraversal(TreeNode* root) {
            vectorres;
            if(root==NULL)
                return res;
            stackst;
            while(root || !st.empty())
            {
                while(root)
                {
                    st.push(root);
                    root=root->left;
                }
    
                root=st.top();
                st.pop();
                res.push_back(root->val);
                root=root->right;//看该节点有没有右子树节点
    
            }
    
            return res;
            
        }
    };
    

后序遍历

/**
 * 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:
    vector postorderTraversal(TreeNode* root) {
        vectorres;
        if(!root)
            return res;
        stackst;
        st.push(root);
        //根->右->左
        while(!st.empty())
        {
            TreeNode* node=st.top();
            res.push_back(node->val);
            st.pop();
            if(node->left)
                st.push(node->left);
            if(node->right)
                st.push(node->right);
        }
        //根->右->左翻转变为左->右->根
        reverse(res.begin(),res.end());
        return res;

    }
};

层序遍历

/**
 * 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:
    vector> levelOrder(TreeNode* root) {
        vector>res;
        if(root==NULL)
            return res;
        //利用队列先见先出,求解层序遍历
        //栈可以求二叉树的遍历
        vectortemp;
        int toBePrint=1;
        int nextLevel=0;
        queuest;
        st.push(root);
        while(!st.empty())
        {
            TreeNode* node=st.front();
            temp.push_back(node->val);
            st.pop();
            toBePrint--;
            if(node->left)
            {
                st.push(node->left);
                nextLevel++;
            }
            if(node->right)
            {
                st.push(node->right);
                nextLevel++;
            }

            if(toBePrint==0)
            {
                toBePrint=nextLevel;
                nextLevel=0;
                res.push_back(temp);
                temp.clear();
            }
            
        }

        return res;
        
    }
};

层次遍历 II

给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)

/**
 * 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:
    vector> levelOrderBottom(TreeNode* root) {
        vector>res;
        if(root==NULL)
            return res;
        //利用队列先见先出,求解层序遍历
        //栈可以求二叉树的遍历
        vectortemp;
        int toBePrint=1;
        int nextLevel=0;
        queuest;
        st.push(root);
        while(!st.empty())
        {
            TreeNode* node=st.front();
            temp.push_back(node->val);
            st.pop();
            toBePrint--;
            if(node->left)
            {
                st.push(node->left);
                nextLevel++;
            }
            if(node->right)
            {
                st.push(node->right);
                nextLevel++;
            }

            if(toBePrint==0)
            {
                toBePrint=nextLevel;
                nextLevel=0;
                res.push_back(temp);
                temp.clear();
            }
            
        }

        reverse(res.begin(),res.end());

        return res;

    }
};
/**
 * 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:
    vector> levelOrder(TreeNode* root) {
        vector>res;
        if(root==NULL)return res;
        queueq;
        q.push(root);
        while(!q.empty()){
            vectorr;
            int l=q.size();
            for(int i=0;ival);
                q.pop();
                if(t->left)q.push(t->left);
                if(t->right)q.push(t->right);
            }
            res.push_back(r);
        }
        return res;
    }
};

锯齿形层次遍历

法1:
在层序遍历基础上

  • 奇数层从左至右
  • 偶数层从右至左,翻转
/**
 * 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:
    vector> zigzagLevelOrder(TreeNode* root) {
        vector>res;
        if(!root)
           return res;
        //奇数层从左至右
        //偶数层从右至左
        int Level=1;
        int toBeprint=1;
        int nextLevel=0;
        queuest;
        st.push(root);
        vectortemp;
        while(!st.empty())
        {
            TreeNode* node=st.front();
            temp.push_back(node->val);
            st.pop();
            toBeprint--;
            if(node->left)
            {
                st.push(node->left);
                nextLevel++;
            }
            if(node->right)
            {
                st.push(node->right);
                nextLevel++;
            }

            if(toBeprint==0)
            {
                toBeprint=nextLevel;
                nextLevel=0;
                if(Level%2==0)
                    reverse(temp.begin(),temp.end());
                res.push_back(temp);
                Level++;
                temp.clear();
            }

        }

        return res;

        
    }
};

树的子结构

输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

注意检测空指针

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
    {
        bool result=false;
        if(pRoot1!=NULL&& pRoot2!=NULL)
        {
            if(abs(pRoot1->val-pRoot2->val)<1e-8)
                result=Tree1HaveTree2(pRoot1,pRoot2);
            if(!result)
                result=HasSubtree(pRoot1->left,pRoot2);
            if(!result)
                result=HasSubtree(pRoot1->right,pRoot2);
        }
        return result;
    }
    
    bool Tree1HaveTree2(TreeNode* pRoot1,TreeNode* pRoot2)
    {
        if(pRoot2==NULL)
            return true;
        if(pRoot1==NULL)
            return false;
        
        if(abs(pRoot1->val-pRoot2->val)>=1e-8)
            return false;
        else
            return Tree1HaveTree2(pRoot1->left,pRoot2->left) && Tree1HaveTree2(pRoot1->right,pRoot2->right);
    }
};

二叉树的深度

输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    int TreeDepth(TreeNode* pRoot)
    {
        if(pRoot==NULL)
            return 0;
        
        int nleft=TreeDepth(pRoot->left);
        int nright=TreeDepth(pRoot->right);
        
        return (nleft>nright)?(nleft+1):(nright+1);
    
    }
};

二叉树的镜像

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

输入描述:

二叉树的镜像定义:源二叉树 
    	    8
    	   /  \
    	  6   10
    	 / \  / \
    	5  7 9 11
    	镜像二叉树
    	    8
    	   /  \
    	  10   6
    	 / \  / \
    	11 9 7  5

先序遍历这棵树的每个结点,如果遍历到的结点有子结点,则交换它的两个子结点。当交换完所有非叶子结点的左右子结点之后,就得到了树的镜像。

递归:

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    void Mirror(TreeNode *pRoot) {
        if(pRoot==NULL)
            return;
        if(pRoot->left==NULL && pRoot->right==NULL)
            return;
        
        TreeNode *temp=pRoot->left;
        pRoot->left=pRoot->right;
        pRoot->right=temp;
        
        if(pRoot->left)
            Mirror(pRoot->left);
        if(pRoot->right)
            Mirror(pRoot->right);

    }
};

循环:

利用栈的“后进先出”特性

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    void Mirror(TreeNode *pRoot) {
        
	if (pRoot == NULL)
	{
		return;
	}
 
	stack stackTreeNode;
	stackTreeNode.push(pRoot);
 
	while (stackTreeNode.size() > 0)
	{
		TreeNode *parent = stackTreeNode.top();
		stackTreeNode.pop();
 
		TreeNode *Temp = parent->left;
		parent->left= parent->right;
		parent->right = Temp;
 
		if (parent->left)
		{
			stackTreeNode.push(parent->left);
		}
 
		if (parent->right)
		{
			stackTreeNode.push(parent->right);
		}
    }
 

二叉树的下一节点

题目:
给定一棵二叉树的其中一个节点,请找出中序遍历序列的下一个节点。
树中的结点不仅包含左右子节点的指针,同时包含指向父结点的指针。
思路:

  • 如果一个节点有右子树,那么它的下一个节点就是它的右子树的最左子节点
  • 没有右子树,分两种情况

1.它是它父节点的左子节点,那么它的下一个节点就是它的父节点
2.它是它父节点的右子节点,可以沿着指向父节点的指针一直向上遍历,直到找到一个是它的父节点的左子节点的节点,如果这个节点存在,那么这个节点的父节点就是要找的下一个节点
C++

 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode *father;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL), father(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* inorderSuccessor(TreeNode* p) {
        if(p==NULL)
            return NULL;
            
        TreeNode* p_next=NULL;
        
        if(p->right)
        {
            TreeNode* p_right=p->right;
            while(p_right->left)
            {
               p_right=p_right->left;
            }
            
            p_next=p_right;
        }
        
        else if(p->father)
        {
            TreeNode* p_current=p;
            TreeNode* p_father=p->father;
            while(p_father && p_current==p_father->right)
            {
                p_current=p_father;
                p_father=p_father->father;
            }
            
            p_next=p_father;
        }
        
        return p_next;
    }
};

重建二叉树

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{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 pre,vector vin) {
        if(pre.empty()||vin.empty())
            return NULL;
        //前序遍历的第一个数值就是根节点的值
        TreeNode* root=new TreeNode(pre[0]);
        //在中序遍历序列中找到根节点的值
        int root_index,i;
        for(int i=0;i pre_left,pre_right,vin_left,vin_right;
        for(i=0;ileft=reConstructBinaryTree(pre_left,vin_left);
        //构建右子树
        root->right=reConstructBinaryTree(pre_right,vin_right);
        
        return root;

    }
};

面试题68 - I. 二叉搜索树的最近公共祖先

/**
 * 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* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root==NULL)
            return NULL;
        if(root==p || root==q)
            return root;
        //root不等于p或q
        TreeNode* left=lowestCommonAncestor(root->left,p,q);
        TreeNode* right=lowestCommonAncestor(root->right,p,q);
        
        if(left==NULL)
            return right;
        if(right==NULL)
            return left;
        if(p && q)
            return root;
        return NULL;
        
    }
};

113. 路径总和 II

给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。

说明: 叶子节点是指没有子节点的节点。

示例:
给定如下二叉树,以及目标和 sum = 22

          5
         / \
        4   8
       /   / \
      11  13  4
     /  \    / \
    7    2  5   1

返回:

[
   [5,4,11,2],
   [5,8,4,5]
]
/**
 * 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:
    vector> pathSum(TreeNode* root, int sum) {
        vector>res;
        vectortemp;  
        dfs(res,temp,root,sum);
        return res;    
    }

    void dfs(vector>&res,vector&temp,TreeNode* root,int sum)
    {
        if(root==NULL )//不能这样写,重复push两次
        {
            //当root子节点为空,就会push两次
            return;
        }
        temp.push_back(root->val);
        if(!root->left && !root->right)
        {
            if(root->val == sum)
                res.push_back(temp);
                //不能加return,这样上一次temp没有pop掉
        }
        dfs(res,temp,root->left,sum-root->val);
        dfs(res,temp,root->right,sum-root->val);
        temp.pop_back();
    }
};

257. 二叉树的所有路径

给定一个二叉树,返回所有从根节点到叶子节点的路径。

说明: 叶子节点是指没有子节点的节点。

示例:

输入:

   1
 /   \
2     3
 \
  5

输出: ["1->2->5", "1->3"]

解释: 所有根节点到叶子节点的路径为: 1->2->5, 1->3

```c++
class Solution {
public:
//temp不能定义成数据成员变量
    vectorres;
    vector binaryTreePaths(TreeNode* root) {
        if(!root)
            return vector();
        dfs(root,"");
        return res;

    }

    void dfs(TreeNode* root,string temp)
    {
        temp+=to_string(root->val);      
        if(!root->left && !root->right)
        {
            res.push_back(temp);
            return;
        }
        //至少有一个子节点
        temp+="->";
        if(root->left)
            dfs(root->left,temp);//不能定义数据成员变量temp,dfs每一次递归会多次调用
        if(root->right)
            dfs(root->right,temp);//从根节点到叶子节点的路径      
    }
};
```

129. 求根到叶子节点数字之和

/**
 * 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:
//    int res=0;
    int sumNumbers(TreeNode* root) {
        int sum=0,res=0;
        dfs(root,sum,res);
        return res;

    }
    /*加&引用,res地址作为参数,res值可变
    不加&,函数调用退出后不会改变res值
    sum不加*/
    void dfs(TreeNode* root,int sum,int &res)
    {
        if(!root)
            return;
        sum=root->val+10*sum;//提前加,不能在dfs内写sum+root->val,这样sum一直为0
        if(!root->left && !root->right)
        {
            res+=sum;//sum全局的
        }
        else
        {
            dfs(root->left,sum,res);//连续两次递归调用
            dfs(root->right,sum,res);
        }

    }
};

222. 完全二叉树的节点个数

/**
 * 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:
    int countNodes(TreeNode* root) {
        int res=0;
        if(!root)
            return 0;
        res++;
        dfs(res,root);

        return res;

    }

    void dfs(int &res,TreeNode *root)
    {
        if(!root->left && !root->right )
        {
            return;
        }

        if(root->left)
        {
            res++;
            dfs(res,root->left);
        }

        if(root->right)
        {
            res++;
            dfs(res,root->right);
        }

    }
};

226. 翻转二叉树

/**
 * 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* invertTree(TreeNode* root) {
        if(root==NULL)
            return root;
        swap(root->left,root->right);
        invertTree(root->left);
        invertTree(root->right);
        return root;
    }
};

108. 将有序数组转换为二叉搜索树

给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。

本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。

示例:

给定的有序链表: [-10, -3, 0, 5, 9],

一个可能的答案是:[0, -3, 9, -10, null, 5], 它可以表示下面这个高度平衡二叉搜索树:

      0
     / \
   -3   9
   /   /
 -10  5
  • 法1:

BFS:将链表转为数组

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
/**
 * 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* sortedListToBST(ListNode* head) {
        vectornums;
        while(head)
        {
            nums.push_back(head->val);
            head=head->next;   
        }

        TreeNode *res=binarySearch(nums,0,nums.size()-1);
        return res;
    }

    TreeNode* binarySearch(vector& nums,int start, int end)
    {
        if(start>end)
            return NULL;
        int mid=(start+end)/2;
        TreeNode *root=new TreeNode(nums[mid]);
        root->left=binarySearch(nums,start,mid-1);
        root->right=binarySearch(nums,mid+1,end);
        return root;
    }
};
  • 法2

快慢指针+递归

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
/**
 * 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* sortedListToBST(ListNode* head) {
        if(head==nullptr) return nullptr;
        if(head->next == nullptr) return new TreeNode(head->val);
        ListNode *start = new ListNode(0);
        start ->next=head;
        ListNode *fast = start, *slow = start, *slow_pre = nullptr;
        while(fast!=nullptr&&fast->next!=nullptr){
            fast = fast->next->next;
            slow_pre = slow;
            slow = slow->next;
        }
        TreeNode *root = new TreeNode(slow->val);
        slow_pre->next = nullptr;
        root->left = sortedListToBST(start->next);
        root->right = sortedListToBST(slow->next);
        return root;
    }
};

114. 二叉树展开为链表

class Solution {
public:
    void flatten(TreeNode *root) {
        if(root==NULL)
            return;
        if(root->left)  flatten(root->left);
        if(root->right) flatten(root->right);
        TreeNode *temp= root->right;
        root->right=root->left;
        root->left=NULL;
        while(root->right)
            root=root->right;//找到最右节点
        root->right=temp;//把左节点连接到原左子树最右边的节点上
    }
};

从根节点开始出发,先检测其左子结点是否存在,如存在则将根节点和其右子节点断开,将左子结点及其后面所有结构一起连到原右子节点的位置,把原右子节点连到原左子结点最后面的右子节点之后。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    void flatten(TreeNode *root) {
        TreeNode *cur=root;

        while(cur)
        {
            if(cur->left)
            {
                TreeNode *temp=cur->left;
                while(temp->right)
                    temp=temp->right;
                    
                // TreeNode *right=cur->right;
                // cur->right=cur->left;
                // temp->right=right;
                temp->right=cur->right;
                cur->right=cur->left;
                cur->left=NULL;
            }
            cur=cur->right;
        }
    }
};

剑指 Offer 36. 二叉搜索树与双向链表

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。

我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。

下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。

img

特别地,我们希望可以就地完成转换操作。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。还需要返回链表中的第一个节点的指针。

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* left;
    Node* right;

    Node() {}

    Node(int _val) {
        val = _val;
        left = NULL;
        right = NULL;
    }

    Node(int _val, Node* _left, Node* _right) {
        val = _val;
        left = _left;
        right = _right;
    }
};
*/
class Solution {
    vectorarr;
public:
    Node* treeToDoublyList(Node* root) {
        if(root==NULL)
            return NULL;
        help(root);
        int i;
        for(i=0;iright=arr[i+1];
            arr[i+1]->left=arr[i]; 
        } 
        arr[i]->right=arr[0];
        arr[0]->left=arr[i];

        return arr[0]; 
    }
    
    void help(Node *root)
    {
        if(root==NULL)
            return;
        help(root->left);
        arr.push_back(root);
        help(root->right);
    }
};

剑指 Offer 54. 二叉搜索树的第k大节点

给定一棵二叉搜索树,请找出其中第k大的节点。

示例 1:

输入: root = [3,1,4,null,2], k = 1
   3
  / \
 1   4
  \
   2
输出: 4

示例 2:

输入: root = [5,3,6,2,4,null,null,1], k = 3
       5
      / \
     3   6
    / \
   2   4
  /
 1
输出: 4

限制:

1 ≤ k ≤ 二叉搜索树元素个数

中序遍历

递归

/**
 * 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 {
    vectorres;
public:
    int kthLargest(TreeNode *root, int k) {
        helper(root);
        return res[res.size()-k];
    }
    //右根左
    void helper(TreeNode *root){
        if(root==NULL){
            return;
        }
        helper(root->left);
        res.push_back(root->val);
        helper(root->right); 
    }
};

迭代

/**
 * 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:
    int kthLargest(TreeNode* root, int k) {
        if(root==NULL)
            return 0;
        vectorres;
        stackst;
        TreeNode* node=root;
        while(node || !st.empty())
        {
            while(node)
            {
                st.push(node);
                node=node->left;
            }

            node=st.top();
            st.pop();
            res.push_back(node->val);
            node=node->right;
        }

        return res[res.size()-k];
    }
};

验证二叉搜索树

给定一个二叉树,判断其是否是一个有效的二叉搜索树。

假设一个二叉搜索树具有如下特征:

节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。

示例 1:

输入:
    2
   / \
  1   3
输出: true

示例 2:

输入:
    5
   / \
  1   4
     / \
    3   6
输出: false
解释: 输入为: [5,1,4,null,null,3,6]。
     根节点的值为 5 ,但是其右子节点值为 4 。

二叉搜索树

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结构的值
  • 若它的右子树不空 ,则右子树上所有结点的值均大于它的根结点的值
  • 它的左、右子树也分别为二叉排序树。

树总结_第1张图片

long的原因,当输出eg:[-2147483648,-2147483648]时,-2147483648 - 1越界了,所以需用long防止越界

/**
 * 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:
    bool isValidBST(TreeNode* root) {
        return isValidOrder(root,INT_MIN,INT_MAX);
        
    }

    bool isValidOrder(TreeNode *root,long min,long max)
    {
        if(root==NULL)
        {
            return true;
        }
        if(root->val < min)
            return false;
        if(root->val > max)
            return false;
        //不加l会内存溢出
        return isValidOrder(root->left,min,root->val-1l) && isValidOrder(root->right,root->val+1l,max);
    }
};

你可能感兴趣的:(复习笔记)