二叉树类问题汇总

树数据结构允许以层级形式存储数据。根据存储数据的方式,有多种树类型,如二叉树。

和它的近亲二叉搜索树一样,它也是最流行的树数据结构之一。因此,你会看到很多相关的有趣问题。例如,如何遍历树、计算节点数量、找出深度,以及检查是否平衡。

解决二叉树问题的关键在于深厚的理论知识,如二叉树的大小或深度、什么是叶节点、什么是节点,以及了解流行的遍历算法。
1.二叉树的遍历
树的节点定义

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

<1>前序
用一个栈,压栈前先打印

    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        Stack<TreeNode> st = new Stack<TreeNode>();
        TreeNode node = root;
        while(node!=null||st.size()>0) {
        	while(node!=null) {
        		res.add(node.val);
        		st.push(node);
        		node=node.left;
        	}
        	if(!st.empty()) {
        		node=st.pop();
        		node=node.right;
        	}
        }
        return res;
    }

<2>中序
一个栈,出栈后打印

    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        Stack<TreeNode> st = new Stack<TreeNode>();
        TreeNode node = root;
        while(node!=null||st.size()>0) {
        	while(node!=null) {
        		st.push(node);
        		node=node.left;
        	}
        	if(!st.empty()) {
        		node=st.pop();
        		res.add(node.val);
        		node=node.right;
        	}
        }
        return res;
    }

<3>后序
两个栈,一个栈存储根、右节点,一个回退取左节点。
最后输出逆序的根右左,即为左右根。

public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        Stack<TreeNode> st = new Stack<TreeNode>();
        Stack<TreeNode> out = new Stack<TreeNode>();
        TreeNode node = root;
        while(node!=null||st.size()>0){
            if(node!=null){
                st.push(node);
                out.push(node);
                node=node.right;
            }else{
                node = st.pop();
                node=node.left;
            }
        }
        while(!out.empty()){
            res.add(out.pop().val);
        }
        return res;
    }   

<4>层序
队列实现

    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new LinkedList<List<Integer>>();
        Queue<TreeNode> qu = new LinkedList<TreeNode>();
        if(root==null) return res;
        qu.add(root);
        while(qu.size()>0){
            int size = qu.size();
            List<Integer> temp = new LinkedList<>();
            while(size-->0){
                TreeNode node = qu.poll();
                temp.add(node.val);
                if(node.left!=null)
                    qu.add(node.left);
                if(node.right!=null)
                    qu.add(node.right);
            }
            res.add(temp);
        }
        return res;
    }
public class Solution {
    public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
        Queue<TreeNode> qu = new LinkedList<>();
        ArrayList<Integer> res = new ArrayList<>();
        if(root == null)
            return res;
        qu.offer(root);
        while(qu.size()!=0){
            TreeNode cur = qu.poll();
            res.add(cur.val);
            if(cur.left!=null)
                qu.offer(cur.left);
            if(cur.right!=null)
                qu.offer(cur.right);
        }
        return res;
    }
}

23.二叉搜索树的后序遍历序列

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
思路:二叉搜索树的左分支比根小,右分支比根大。
如果是后序遍历,根节点在最后,则数组前部分为比根小,后部分比根大。
从后往前遍历,是否都满足该规则,不满足则false。

public class Solution {
    public boolean VerifySquenceOfBST(int [] sequence) {
        if(sequence==null||sequence.length<=0)
            return false;
        int len = sequence.length;
        while(--len>0){
            int i=0;
            while(sequence[i]<sequence[len])
                i++;
            while(sequence[i]>sequence[len])
                i++;
            if(i!=len)
                return false;
        }
        return true;
    }
}

2.二叉树反转左右节点

	public static void swapNode(Node root) {
		if(root==null)
			return ;
		Node tmp = root.getLeftNode();
		root.setLeftNode(root.getRightNode());
		root.setRightNode(tmp);
		swapNode(root.getLeftNode());
		swapNode(root.getRightNode());
	}

二叉搜索树中第K小的元素
给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素。

说明:
你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元素个数。
思路:二叉搜索树的中序遍历有序;
因此直接中序遍历即可;

	public int kthSmallest(TreeNode root, int k) {
		Stack<TreeNode> st = new Stack<TreeNode>();
		TreeNode node = root;
		int tmp = 0;
		while (node != null || st.size() > 0) {
			while (node != null) {
				st.push(node);
				node = node.left;
			}
			if (!st.empty()) {
				node = st.pop();
				tmp = node.val;
				k--;
				if (k == 0)
					return tmp;
				node = node.right;
			}
		}
		return tmp;
	}

猜你喜欢

转载自blog.csdn.net/sky_noodle/article/details/82950257