《剑指offer》-- 二叉树的下一个结点、对称二叉树、按之字性顺序打印二叉树、把二叉树打印成多行

版权声明:本文为原创文章,如有不足之处可以指出,欢迎大家转载,记得标明出处。 https://blog.csdn.net/a745233700/article/details/82726758

一、二叉树的下一个结点:

1、题目:

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

2、解题思路:

分析二叉树的下一个节点,一共有以下情况:
(1)二叉树为空,则返回空;
(2)节点右孩子存在,则设置一个指针从该节点的右孩子出发,一直沿着指向左子结点的指针找到的叶子节点即为下一个节点;
(3)节点不是根节点。如果该节点是其父节点的左孩子,则返回父节点;否则继续向上遍历其父节点的父节点,重复第三步的判断,返回结果。

3、代码实现:

public class Test15 {
	
	 public TreeLinkNode GetNext(TreeLinkNode pNode){
		 
		 if(pNode == null){
			 return null;
		 }
		 if(pNode.right != null){
			 pNode = pNode.right;
			 while(pNode.left!=null){
				 pNode = pNode.left;
			 }
			 return pNode;
		 }
		 while(pNode.next!=null){
			 TreeLinkNode parent = pNode.next;
			 if(parent.left==pNode){
				 return parent;
			 }
			 pNode = pNode.next;
		 }
		 return null;
    }
}

class TreeLinkNode {
    int val;
    TreeLinkNode left = null;
    TreeLinkNode right = null;
    TreeLinkNode next = null;//指向改节点的父节点
    TreeLinkNode(int val) {
        this.val = val;
    }
}

二、对称二叉树:

1、题目:

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

2、代码实现:

public class Test16 {

	boolean isSymmetrical(TreeNode pRoot){
		if(pRoot == null) return true;
		return judge(pRoot.left,pRoot.right);
    }
	
	boolean judge(TreeNode leftNode,TreeNode rightNode){
		if(leftNode == null) return rightNode==null;
		if(rightNode == null) return false;
		if(leftNode.val != rightNode.val) return false;
		return judge(leftNode.left,rightNode.right) && judge(leftNode.right,rightNode.left);
	}
	
}

class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int val) {
        this.val = val;

    }
}

三、按之字性顺序打印二叉树:

1、题目:

请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。

2、解题思路:

利用栈先进后出的性质,创建两个栈分别存放奇数层与偶数层的节点。

3、代码实现:

public class Test18 {
	public ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
		int layer = 1;
		//s1存奇数层节点:
		Stack<TreeNode> s1 = new Stack<TreeNode>();
		s1.push(pRoot);
		//s2存放偶数层节点:
		Stack<TreeNode> s2 = new Stack<TreeNode>();
		ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
		
		while(!s1.empty() || !s2.empty()){
			if(layer%2 !=0){
				//奇数层:
				ArrayList<Integer> temp = new ArrayList<Integer>();
				while(!s1.empty()){
					TreeNode node = s1.pop();
					if(node!=null){
						temp.add(node.val);
						s2.push(node.left);
						s2.push(node.right);
					}
				}
				if(!temp.isEmpty()){
					list.add(temp);
					layer++;
				}
			}else{
				//偶数层:
				ArrayList<Integer> temp = new ArrayList<Integer>();
				while(!s2.isEmpty()){
					TreeNode node = s2.pop();
					if(node!=null){
						temp.add(node.val);
						s1.push(node.right);
						s1.push(node.left);
					}
				}
				if(!temp.isEmpty()){
					list.add(temp);
					layer++;
				}
			}
		}
		return list;
    }
}

class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int val) {
        this.val = val;
    }
}

四、把二叉树打印成多行:

1、题目:

从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。

2、代码实现:

public class Test19 {
	
	 ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
		 ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
		 if(pRoot == null){
			 return result;
		 }
		 
		 Queue<TreeNode> queue = new LinkedList<TreeNode>();
		 ArrayList<Integer> queueList = new ArrayList<Integer>();
		 queue.add(pRoot);
		 int start = 0 ,end = 1;

		 while(!queue.isEmpty()){
			 TreeNode current = queue.remove();
			 queueList.add(current.val);
			 start++;
			 if(current.left!=null){
				 queue.add(current.left);
			 }
			 if(current.right!=null){
				 queue.add(current.right);
			 }
			 if(start == end){
				 end = queue.size();
				 start=0;
				 result.add(queueList);
				 queueList = new ArrayList<Integer>();
			 }
			 
		 }
		 return result;
    }
}

class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int val) {
        this.val = val;
    }
}

猜你喜欢

转载自blog.csdn.net/a745233700/article/details/82726758