Java学习手册:(数据结构与算法-二叉树)已知先序遍历和中序遍历,如何求后序遍历?

算法思想:已知先序遍历和中序遍历,如何求后序遍历?(1)确定树的根结点。树根是当前树中所有元素在先序遍历中最先出现的元素,即先序遍历的第一个结点就是二叉树的根。(2)求解树的子树。找到根在中序遍历的位置,位置左边是二叉树的左孩子,位置右边是二叉树的右孩子,如果根结点左边或右边为空,那么该方向子树为空;如果根结点左边和右边都为空,那么根结点已经成为叶子结点。(3)对二叉树的左、右孩子分别进行步骤(1)(2),直到求出二叉树结构为止。

代码如下:

package com.haobi;
/*
 * 已知先序遍历和中序遍历,如何求后序遍历?
 * 
 * (1)确定树的根结点。树根是当前树中所有元素在先序遍历中最先出现的元素,即先序遍历的第一个结点就是二叉树的根。
 * (2)求解树的子树。找到根在中序遍历的位置,位置左边是二叉树的左孩子,位置右边是二叉树的右孩子,
 * 	      如果根结点左边或右边为空,那么该方向子树为空;如果根结点左边和右边都为空,那么根结点已经成为叶子结点。
 * (3)对二叉树的左、右孩子分别进行步骤(1)(2),直到求出二叉树结构为止。
 */
//定义结点结构
class Node3{
	public int data;
	public Node3 left;
	public Node3 right;
	public Node3(int data) {
		this.data = data;
		this.left = null;
		this.right = null;
	}
	public Node3() {}
}

public class Test3 {
	//定义根结点
	private Node3 root;
	//构造方法
	public Test3() {
		root = null;
	}
	
	/**
	 * 后序遍历方法递归实现
	 * @param root
	 */
	public void postOrder(Node3 root) {
		if(root != null) {
			postOrder(root.left);
			postOrder(root.right);
			System.out.print(root.data + " ");
		}
	}
	
	/**
	 * 初始化树(由先序和中序生成 后序)
	 * @param preOrder
	 * @param inOrder
	 */
	public void initTree(int[] preOrder, int[] inOrder) {
		this.root = this.initTree(preOrder, 0, preOrder.length-1, inOrder, 0, inOrder.length-1);
	}
	
	/**
	 * 递归构建左右子树
	 * @param preOrder
	 * @param start1
	 * @param end1
	 * @param inOrder
	 * @param start2
	 * @param end2
	 * @return
	 */
	public Node3 initTree(int[] preOrder, int start1, int end1, int[] inOrder, int start2, int end2) {
		if(start1 > end1 || start2 > end2) {
			return null;
		}
		int rootData = preOrder[start1];
		Node3 head = new Node3(rootData);
		//从中序遍历里找到根结点所在的位置
		int rootIndex = findIndexInArray(inOrder, rootData, start2, end2);
		//offSet代表左子树的长度-1(也就是中序遍历中,左子树最后一个元素的下标)
		int offSet = rootIndex - start2 - 1;
		//递归构建左子树
		Node3 left = initTree(preOrder, start1+1, start1+1+offSet, inOrder, start2, start2+offSet);
		//递归构建右子树
		Node3 right = initTree(preOrder, start1+offSet+2, end1, inOrder, rootIndex+1, end2);
		head.left = left;
		head.right = right;
		return head;
	}
	
	/**
	 * 找到x在数组中的下标
	 * @param a
	 * @param x
	 * @param begin
	 * @param end
	 * @return
	 */
	public int findIndexInArray(int[] a, int x, int begin, int end) {
		for(int i=begin;i<=end;i++) {
			if(a[i] == x) {
				return i;
			}
		}
		return -1;
	}
	
	public static void main(String[] args) {
		Test3 tree = new Test3();
		int[] preOrder = {1,2,4,8,9,5,10,3,6,7};
		int[] inOrder = {8,4,9,2,10,5,1,6,3,7};
		tree.initTree(preOrder, inOrder);
		System.out.print("二叉树的后序遍历:");
		tree.postOrder(tree.root);
	}
}

程序输出结果如下:

二叉树的后序遍历:8 9 4 10 5 2 6 7 3 1 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值