java实现二叉树二叉排序树的创建,二叉树的先序、中序、后序(递归和非递归)、层序遍历
package com.lmm.test;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
/**
* @author lmm E-mail:violet_mmhh@163.com
* @time 时间:2019年4月8日
* @function 功能:
*/
// 实现二叉排序树
public class BinarySortTree {
public static void main(String[] args) {
BinaryTree biTree = new BinaryTree();
int[] data = { 2, 8, 7, 4, 9, 3, 1, 6, 7, 5 };
biTree.buildTree(data);
System.out.println("二叉树的中序遍历:");
biTree.inOrder();
System.out.println();
System.out.println("二叉树非递归的中序遍历:");
biTree.nonrecursiveinOrder();
System.out.println();
System.out.println("二叉树的先序遍历:");
biTree.preOrder();
System.out.println();
System.out.println("二叉树非递归的先序遍历:");
biTree.nonrecursivepreOrder();
System.out.println();
System.out.println("二叉树的后序遍历:");
biTree.postOrder();
System.out.println();
System.out.println("二叉树非递归的后序遍历:");
biTree.nonrecursivepostOrder();
System.out.println();
System.out.println("二叉树的层序遍历:");
biTree.levelTraversal();
System.out.println();
// System.out.println("带行号的二叉树层序遍历:");
// biTree.levelTraversalWithLineNo();
// System.out.println();
}
}
class Node {
public int data;
public Node left;
public Node right;
public Node(int val) {
this.data = val;
this.left = null;
this.right = null;
}
}
class BinaryTree {
public Node root;
public BinaryTree() {
root = null;
}
// 将data插入到二叉排序树中
public void insert(int data) {
Node newNode = new Node(data);
if (root == null) {
root = newNode;
} else {
Node current = root;
Node parent;
while (true) {// 寻找插入的位置
parent = current;
if (data < current.data) {
current = current.left;
if (current == null) {
parent.left = newNode;
return;
}
} else {
current = current.right;
if (current == null) {
parent.right = newNode;
return;
}
}
}
}
}
// 将数值输入构建二叉树
public void buildTree(int[] data) {
for (int i = 0; i < data.length; i++) {
insert(data[i]);
}
}
// 中序遍历方法递归实现
public void inOrder(Node localRoot) {
if (localRoot != null) {
inOrder(localRoot.left);
System.out.print(localRoot.data + " ");
inOrder(localRoot.right);
}
}
public void inOrder() {
this.inOrder(this.root);
}
// 非递归实现中序遍历
public void nonrecursiveinOrder(Node localRoot) {
Stack<Node> st = new Stack<>();
Node node = localRoot;
while (node != null || !st.empty()) {
while (node != null) {
st.push(node);
node = node.left;
}
if (!st.empty()) {
node = st.pop();
System.out.print(node.data + " ");
node = node.right;
}
}
}
public void nonrecursiveinOrder() {
this.nonrecursiveinOrder(this.root);
}
// 先序遍历方法递归实现
public void preOrder(Node localRoot) {
if (localRoot != null) {
System.out.print(localRoot.data + " ");
preOrder(localRoot.left);
preOrder(localRoot.right);
}
}
public void preOrder() {
this.preOrder(this.root);
}
// 非递归实现先序遍历
public void nonrecursivepreOrder(Node localRoot) {
Stack<Node> st = new Stack<>();
Node node = localRoot;
while (node != null || !st.empty()) {
while (node != null) {
System.out.print(node.data + " ");
st.push(node);
node = node.left;
}
node = st.pop();
node = node.right;
}
}
public void nonrecursivepreOrder() {
this.nonrecursivepreOrder(this.root);
}
// 后序遍历方法递归实现
public void postOrder(Node localRoot) {
if (localRoot != null) {
postOrder(localRoot.left);
postOrder(localRoot.right);
System.out.print(localRoot.data + " ");
}
}
public void postOrder() {
this.postOrder(this.root);
}
// 非递归实现后序遍历
public void nonrecursivepostOrder(Node localRoot) {
Stack<Node> st = new Stack<>();
Node node = localRoot;
Node node2 = localRoot;
while (node != null) {
// 左子树入栈
while (node.left != null) {
st.push(node);
node = node.left;
}
// 当前结点无右子树或右子树已经输出
while (node.right == null || node.right == node2) {
System.out.print(node.data + " ");
node2 = node;// 纪录上一个已输出结点
if (st.empty())
return;
node = st.pop();
}
// 处理右子树
st.push(node);
node = node.right;
}
}
public void nonrecursivepostOrder() {
this.nonrecursivepostOrder(this.root);
}
/**
* 层序遍历二叉树(每一行从左到右,整体上从上到下) 主要思路:利用队列先进先出的性质保存顺序
*
* @param root
* 要遍历的二叉树的根节点
*/
public void levelTraversal(Node root) {
Queue<Node> q = new LinkedList<>();
q.add(root);
while (!q.isEmpty()) {
Node temp = q.poll();
if (temp != null) {
System.out.print(temp.data + " ");
if (temp.left != null)
q.add(temp.left);
if (temp.right != null)
q.add(temp.right);
}
}
}
public void levelTraversal() {
this.levelTraversal(this.root);
}
/**
* 层序遍历二叉树(每一行从左到右,整体上从上到下),并附带行号 主要思路:利用队列先进先出的性质保存顺序来层序遍历二叉树。
* 使用curLineLast与nextLineLast两个节点标志来标识遍历过程中当前行结尾节点与下一行结尾节点,
* 再使用一个lineNo整形量来记录当前行号(初始设为1),并在curLineLast节点更替时,更新lineNo的值并按格式打印即可。
* 注:nextLineLast始终指向最新遍历到的节点
*
* @param root
* 要遍历的二叉树的根节点
*/
public void levelTraversalWithLineNo(Node root) {
// 加入断言,保证root不为null
assert root != null;
// curLineLast : 当前行结尾节点
// nextLineLast : 下一行结尾节点
// 刚开始时,curLineLast与nextLineLast均指向根节点
Node curLineLast = root, nextLineLast = root;
// 设根节点所在的行为第1行
int lineNo = 1;
System.out.print(lineNo + " : ");
Queue<Node> q = new LinkedList<>();
q.add(root);
while (!q.isEmpty()) {
Node temp = q.poll();
// 只有当前节点的子节点不为空时,nextLineLast才需要更改指向的目标
if (temp.left != null) {
q.add(temp.left);
nextLineLast = temp.left;
}
if (temp.right != null) {
q.add(temp.right);
nextLineLast = temp.right;
}
System.out.print(temp.data + " ");
// 当出栈节点为当前行尾节点时,说明该换行了
if (curLineLast == temp) {
// 将当前行尾节点指向下一行尾节点
curLineLast = nextLineLast;
System.out.print(System.lineSeparator() + ++lineNo + " : ");
}
}
}
public void levelTraversalWithLineNo() {
this.levelTraversalWithLineNo(this.root);
}
}