二叉树三种遍历方式及通过两种遍历重构二叉树(java实现)

版权声明:转载请标明出处哦 https://blog.csdn.net/easy_purple/article/details/85091405

重构方法参考文章【重构二叉树(Java实现):https://blog.csdn.net/wangbingcsu/article/details/51372695

文章目录

  • 二叉树类
  • 三种遍历方式
    • 前序遍历
    • 中序遍历
    • 后序遍历
  • 两种重构方式
    • 通过前序遍历中序遍历重构二叉树
    • 通过后序遍历中序遍历重构二叉树
  • 总代码
  • 测试代码

二叉树类

这里我们创建一个二叉树的类,并为他添加一个插入的方法(左节点总是比父节点小,右节点总是比父节点大)

public class BinaryTree {
	int data;
	BinaryTree left;
	BinaryTree right;

	public BinaryTree(int data) {
		this.data = data;
		left = null;
		right = null;
	}

	public void insert(BinaryTree root, int data) {//左节点总是比父节点小,右节点总是比父节点大
		if (data > root.data) {
			if (root.right == null) {
				root.right = new BinaryTree(data);
			} else {
				this.insert(root.right, data);
			}
		} else {
			if (root.left == null) {
				root.left = new BinaryTree(data);
			} else {
				this.insert(root.left, data);
			}
		}
	}
}

三种遍历方式

这三种遍历方式,相对的是根节点的遍历顺序。

前序遍历

1.访问根节点 
2.前序遍历左子树 
3.前序遍历右子树

public static void preOrder(BinaryTree root) {//前序遍历
	if (root != null) {
		System.out.print(root.data + ",");// 数据在同一行输出
		preOrder(root.left);
		preOrder(root.right);
	}
}

中序遍历

1.中序遍历左子树 
2.访问根节点 
3.中序遍历右子树

public static void inOrder(BinaryTree root) {//中序遍历
	if (root != null) {
		inOrder(root.left);
		System.out.print(root.data + ",");// 数据在同一行输出
		inOrder(root.right);
	}
}

后序遍历

1.后序遍历左子树 
2.后序遍历右子树 
3.访问根节点

public static void postOrder(BinaryTree root) {//后序遍历
	if (root != null) {
		postOrder(root.left);
		postOrder(root.right);
		System.out.print(root.data + ",");// 数据在同一行输出
	}
}

两种重构方式

我们可以通过前序遍历和中序遍历重构出唯一的二叉树,也可以通过中序遍历和后序遍历重构出唯一的二叉树,

但是通过前序遍历和后序遍,无法重构出唯一的二叉树。

通过前序遍历中序遍历重构二叉树

  • 值确定根节点:根据前序遍历的第一个值确定根节点
  • 递归确定左子树
  • 递归确定右子树
// 根据前序中序重构二叉树
public static BinaryTree reConstructBinaryTree1(int[] pre, int[] in) {
	if (0 == pre.length || 0 == in.length)
		return null;
	// 先序遍历数组的第一个元素作为根节点
	BinaryTree root = new BinaryTree(pre[0]);
	for (int i = 0; i < in.length; ++i) {
		if (root.data == in[i]) {
			root.left = reConstructBinaryTree1(Arrays.copyOfRange(pre, 1, i + 1), Arrays.copyOfRange(in, 0, i));
			root.right = reConstructBinaryTree1(Arrays.copyOfRange(pre, i + 1, pre.length),
					Arrays.copyOfRange(in, i + 1, in.length));
		}
	}
	return root;
}

通过后序遍历中序遍历重构二叉树

  • 值确定根节点:根据后序遍历的最后一个值确定根节点
  • 递归确定左子树
  • 递归确定右子树
// 根据后序中序重构二叉树
public static BinaryTree reConstructBinaryTree2(int[] post, int[] in) {
	if (0 == post.length || 0 == in.length)
		return null;
	BinaryTree root = new BinaryTree(post[post.length - 1]);
	for (int i = 0; i < in.length; ++i) {
		if (root.data == in[i]) {
			root.left = reConstructBinaryTree2(Arrays.copyOfRange(post, 0, i), Arrays.copyOfRange(in, 0, i));
			root.right = reConstructBinaryTree2(Arrays.copyOfRange(post, i, post.length - 1),
					Arrays.copyOfRange(in, i + 1, in.length));
		}
	}
	return root;
}

总代码

这里,为了省事,把二叉树三种遍历方式和两种重构方式都写在了这个类里。

public class BinaryTree {
	int data;
	BinaryTree left;
	BinaryTree right;

	public BinaryTree(int data) {
		this.data = data;
		left = null;
		right = null;
	}

	public void insert(BinaryTree root, int data) {// 左节点总是比父节点小,右节点总是比父节点大
		if (data > root.data) {
			if (root.right == null) {
				root.right = new BinaryTree(data);
			} else {
				this.insert(root.right, data);
			}
		} else {
			if (root.left == null) {
				root.left = new BinaryTree(data);
			} else {
				this.insert(root.left, data);
			}
		}
	}

	public static BinaryTree reConstructBinaryTree(int[] pre, int[] in) {// 根据前序中序重构二叉树
		if (pre.length == 0 || in.length == 0) {
			return null;
		}
		BinaryTree node = new BinaryTree(pre[0]);
		for (int i = 0; i < in.length; i++) {
			if (pre[0] == in[i]) {
				node.left = reConstructBinaryTree(Arrays.copyOfRange(pre, 1, i + 1), Arrays.copyOfRange(in, 0, i));
				node.right = reConstructBinaryTree(Arrays.copyOfRange(pre, i + 1, pre.length),
						Arrays.copyOfRange(in, i + 1, in.length));
			}
		}
		return node;
	}

	// 根据前序中序重构二叉树
	public static BinaryTree reConstructBinaryTree1(int[] pre, int[] in) {
		if (0 == pre.length || 0 == in.length)
			return null;
		// 先序遍历数组的第一个元素作为根节点
		BinaryTree root = new BinaryTree(pre[0]);
		for (int i = 0; i < in.length; ++i) {
			if (root.data == in[i]) {
				root.left = reConstructBinaryTree1(Arrays.copyOfRange(pre, 1, i + 1), Arrays.copyOfRange(in, 0, i));
				root.right = reConstructBinaryTree1(Arrays.copyOfRange(pre, i + 1, pre.length),
						Arrays.copyOfRange(in, i + 1, in.length));
			}
		}
		return root;
	}

	public static BinaryTree reConstructBinaryTree2(int[] post, int[] in) {// 根据后序中序重构二叉树
		if (0 == post.length || 0 == in.length)
			return null;
		BinaryTree root = new BinaryTree(post[post.length - 1]);
		for (int i = 0; i < in.length; ++i) {
			if (root.data == in[i]) {
				root.left = reConstructBinaryTree2(Arrays.copyOfRange(post, 0, i), Arrays.copyOfRange(in, 0, i));
				root.right = reConstructBinaryTree2(Arrays.copyOfRange(post, i, post.length - 1),
						Arrays.copyOfRange(in, i + 1, in.length));
			}
		}
		return root;
	}

	// 三种遍历方式
	public static void preOrder(BinaryTree root) {// 前序遍历
		if (root != null) {
			System.out.print(root.data + ",");// 数据在同一行输出
			preOrder(root.left);
			preOrder(root.right);
		}
	}

	public static void inOrder(BinaryTree root) {// 中序遍历
		if (root != null) {
			inOrder(root.left);
			System.out.print(root.data + ",");// 数据在同一行输出
			inOrder(root.right);
		}
	}

	public static void postOrder(BinaryTree root) {// 后序遍历
		if (root != null) {
			postOrder(root.left);
			postOrder(root.right);
			System.out.print(root.data + ",");// 数据在同一行输出
		}
	}
}

测试

这里为了省事,测试类直接继承二叉树类,进行测试。

public class BinaryTreeTest extends BinaryTree {

	public BinaryTreeTest(int data) {
		super(data);
	}

	public static void main(String[] args) {
		testReConstruct();
	}

	public static void testReConstruct() {// 测试重构二叉树
		int[] pre = { 12, 9, 76, 35, 22, 16, 48, 46, 40, 90 };
		int[] in = { 9, 12, 16, 22, 35, 40, 46, 48, 76, 90 };
		int[] post = { 9, 16, 22, 40, 46, 48, 35, 90, 76, 12, };
		BinaryTree root = reConstructBinaryTree2(post, in);
		postOrder(root);
	}

	public static void testOrder() {// 测试三种遍历
		int[] list = { 12, 76, 35, 22, 16, 48, 90, 46, 9, 40 };
		BinaryTree root = new BinaryTree(list[0]);
		for (int i = 1; i < list.length; i++) {
			root.insert(root, list[i]);
		}
		preOrder(root);
		System.out.println();// 换行
		inOrder(root);
		System.out.println();// 换行
		postOrder(root);
	}
}

猜你喜欢

转载自blog.csdn.net/easy_purple/article/details/85091405