剑指 Offer 07. 重建二叉树【 JAVA - 二叉树 - 递归】

题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof

输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

示例1:

Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]

示例二:

Input: preorder = [-1], inorder = [-1]
Output: [-1]

参考:[ 剑指Offer第二版 ]

这个题目主要考到的知识点是:

  • 在二叉树的前序遍历中, 第一个数字总是树的根节点的值

  • 在中序遍历中,根节点的值在序列中间,左子树的节点的值位于根节点的左边,右子树的节点的值位于根节点的值的右边

代码【JAVA】:

/**
 * Definition for a binary tree TreeNode.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        //判空处理
    	if(preorder == null || inorder == null) return null;
        if(preorder.length == 0 || inorder.length == 0) return null;
    	
    	return constructionTree(preorder , inorder , 0 , preorder.length - 1, 0 , inorder.length - 1);
    }
	
	//starPreorder  ====  前序遍历数组中的开始位置[根节点位置];
	//endPreorder === 前序遍历数组中的结束位置
	//starInorder ===中序遍历数组中的开始位置
	//endInorder ===中序遍历数组中的结束位置
	public TreeNode constructionTree(int[] preorder, int[] inorder , int starPreorder , int endPreorder , int starInorder ,int endInorder){
		
        //前序遍历中, 第一个数字总是树的根节点的值
		TreeNode root = new TreeNode(preorder[starPreorder]);
		
		//开始位置和结束位置相同时 后面无子节点
		if(starPreorder == endPreorder) {
			if(starInorder == endInorder && preorder[starPreorder] == inorder[starInorder]) return root;
//			else return null; //输入的二叉树不合法
		}
		
        //中序遍历中,根节点的值在序列中间,左子树的节点的值位于根节点的左边,右子树的节点的值位于根节点的右边
		//找到中序遍历中的根节点位置
		int rootInorder = starInorder;
		while((rootInorder <= endInorder) && inorder[rootInorder] != root.val) {
			rootInorder++;
		}
		
		//左子树的长度
		int leftLength = rootInorder - starInorder;
		//前序遍历中 左子树的结束位置
		int endleftPreorder = starPreorder + leftLength;
		
        //递归构建左子树
		if(leftLength > 0) {
			root.left = constructionTree(preorder, inorder , starPreorder + 1 , endleftPreorder , starInorder , rootInorder - 1 );
		}

		//递归构建右子树
		if(leftLength <  (endPreorder - starPreorder)) {
			root.right= constructionTree( preorder, inorder , endleftPreorder + 1 , endPreorder , rootInorder + 1 , endInorder );
		}
		
		return root;
	}
}

学习到这一部分,于是又去额外地补充学习了 Java和二叉树的结合 ,二叉树真的好难好难好难好难!!!!!/(ㄒoㄒ)/~~

参考:http://t.csdn.cn/NDHVU

以下为二叉树的插入二叉树三种遍历的递归实现代码。

package algorithm;
public class BinaryTree {
	
	//定义节点
	class Node{
		int value;
		Node leftChild;
		Node rightChild;
		
		//构造函数
		Node(int value){
			this.value = value;
		}
		
		public void display() {
			System.out.print(this.value + "->");
		}
		
		//重写输出方法
		@Override
		public String toString() {
			return String.valueOf(this.value);
		}
	}
	
	Node root; //根节点
	
	//构造函数
	BinaryTree(int value){
		root = new Node(value);
		root.leftChild = null ; 
		root.rightChild = null;
	}
	
	//插入节点
	public void insertNode(int value) {
		
		Node node = new Node(value);
		if(root == null) {
			root = node;
			root.leftChild = null;
			root.rightChild = null;
		}else {
			Node current = root;
			Node parent = null;
			
			while(true) {
				if(value > current.value) {
					parent = current;
					current =  current.rightChild;
					if(current == null) {
						parent.rightChild = node;
						return;
					}
				}
				else if(value < current.value){
					parent = current;
					current = current.leftChild;
					if(current == null) {
						parent.leftChild = node;
						return;
					}
				}
				else {
					System.out.print("含有重复数字");
					return;
				}
			}
			
		}
	}
	
	//递归前序遍历
	public void PreOrderTraverse(Node node) {
		if(node == null) {
			return;
		}
		node.display();
		PreOrderTraverse(node.leftChild);
		PreOrderTraverse(node.rightChild);
	}
	
	//递归中序遍历
	public void InOrderTraverse(Node node) {
		if(node == null) {
			return;
		}
		InOrderTraverse(node.leftChild);
		node.display();
		InOrderTraverse(node.rightChild);
	}
	
	//递归后序遍历
	public void PostOrderTraverse(Node node) {
		if(node == null) {
			return;
		}
		PostOrderTraverse(node.leftChild);
		PostOrderTraverse(node.rightChild);
		node.display();
	}

	//测试
	public static void main(String[] args) {
		
		BinaryTree bt = new BinaryTree(10);
		
		bt.insertNode(6);
		bt.insertNode(11);
		bt.insertNode(5);
		bt.insertNode(7);
		
		System.out.println(bt.root);
		
		System.out.println("前序遍历: ");
		bt.PreOrderTraverse(bt.root);
		System.out.println("\n");
		
		System.out.println("中序遍历: ");
		bt.InOrderTraverse(bt.root);
		System.out.println("\n");
		
		System.out.println("后序遍历: ");
		bt.PostOrderTraverse(bt.root);		
	}
}

两天时间,终于把这一个题搞定了,二叉树太难啦啦啦啦啦!!!!!/(ㄒoㄒ)/~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值