package btree;
import java.util.Queue;
import java.util.Stack;
import java.util.concurrent.LinkedBlockingQueue;
public class Btree<T> {
/**
* 结点类。
* @author Bao Yiming
*/
class Node {
int value; // 该节点存储的值。
Node leftChild; // 指向左子节点的引用。
Node rightChild; // 指向右子节点的引用。
Node(int value) {
this.value = value;
leftChild = null;
rightChild = null;
}
}
private Node root; // 根节点。
/**
* 无参构造方法。
*/
Btree() {
root = null;
}
/**
* 使用一个数组来构造二叉树。
* @param arr 值的数组。
*/
Btree(int[] arr) {
for (int i : arr) {
insert(i);
}
}
private void insert(int value) {
root = insert(root, value);
}
/**
* 将数值插入到二叉树中,比当前结点小或等于当前结点的插在当前结点的左侧,
* 比当前结点大的数插在当前结点的右侧,每次从根结点开始递归比较。
* @param node 当前的结点,就是根结点,只是每次根结点的左右子树更新。
* @param value 要插入的值。
* @return 插值结束后的树的根节点。
*/
private Node insert(Node node, int value) {
if (node == null) {
node = new Node(value);
} else {
if (value <= node.value) {
node.leftChild = insert(node.leftChild, value);
} else {
node.rightChild = insert(node.rightChild, value);
}
}
return node;
}
/**
* 访问节点:将节点的值取出来并打印。
* @param node 需访问的节点。
*/
private void visit(Node node) {
/**
* 当节点为空时返回。
*/
if (node == null) {
return;
}
int value = node.value;
System.out.print(value);
}
/**
* 从指定节点作为根节点开始递归对树进行先序遍历。
* @param node 指定节点。
*/
private void preOrderTravels(Node node) {
if (node == null) {
return;
} else {
visit(node);
preOrderTravels(node.leftChild);
preOrderTravels(node.rightChild);
}
}
/**
* 从根节点开始对整个树进行先序遍历。
*/
public void preOrderTravels() {
preOrderTravels(root);
}
//先序遍历(非递归)
public void nrPreOrderTravels() {
Stack<Node> stack = new Stack<Node>();
Node node = root;
while (node != null || !stack.isEmpty()) {
while (node != null) {
System.out.print(node.value);
stack.push(node);
node = node.leftChild;
}
node = stack.pop();
node = node.rightChild;
}
}
//中序遍历 递归
private void InOrderTraverse(Node node) {
if (node == null) {
return;
} else {
InOrderTraverse(node.leftChild);
visit(node);
InOrderTraverse(node.rightChild);
}
}
public void InOrderTraverse() {
InOrderTraverse(root);
}
//中序遍历(非递归)
public void nrInOrderTraverse() {
Stack<Node> stack = new Stack<Node>();
Node node = root;
while (node != null || !stack.isEmpty()) {
while (node != null) {
stack.push(node);
node = node.leftChild;
}
node = stack.pop();
System.out.print(node.value);
node = node.rightChild;
}
}
//后续遍历 递归
private void postOrderTraverse(Node node) {
if (node == null) {
return;
} else {
postOrderTraverse(node.leftChild);
postOrderTraverse(node.rightChild);
visit(node);
}
}
public void postOrderTraverse() {
postOrderTraverse(root);
}
//后续遍历(非递归)
public void nrPostOrderTraverse() {
Stack<Node> stack = new Stack<Node>();
Node node = root;
Node preNode = null;//表示最近一次访问的节点
while (node != null || !stack.isEmpty()) {
while (node != null) {
stack.push(node);
node = node.leftChild;
}
node = stack.peek();
if (node.rightChild == null || node.rightChild == preNode) {
System.out.print(node.value);
node = stack.pop();
preNode = node;
node = null;
} else {
node = node.rightChild;
}
}
}
//按层次遍历
public void levelTraverse() {
levelTraverse(root);
}
public void levelTraverse(Node node) {
Queue<Node> queue = new LinkedBlockingQueue<Node>();
queue.add(node);
while (!queue.isEmpty()) {
Node temp = queue.poll();
if (temp != null) {
System.out.print(temp.value);
if(temp.leftChild!=null)
queue.add(temp.leftChild);
if(temp.rightChild!=null)
queue.add(temp.rightChild);
}
}
}
}
测试类:
package btree;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] a = new int[]{6,3,9,6,4,2,1};
Btree<Integer> bt = new Btree<Integer>(a);
System.out.println("先序遍历:");
bt.preOrderTravels();
System.out.println();
bt.nrPreOrderTravels();
System.out.println();
System.out.println("中序遍历:");
bt.InOrderTraverse();
System.out.println();
bt.nrInOrderTraverse();
System.out.println();
System.out.println("后序遍历:");
bt.postOrderTraverse();
System.out.println();
bt.nrPostOrderTraverse();
System.out.println();
System.out.println("层次遍历:");
bt.levelTraverse();
}
}
二叉树的各种遍历(先序、中序、后续、层次)——递归、非递归
最新推荐文章于 2019-06-03 11:51:45 发布