package 基础算法;
import java.util.LinkedList;
import java.util.Queue;
public class BinaryTreeTraverseTest {
public static void main(String[] args) {
BinarySortTree<Integer> tree = new BinarySortTree<Integer>();
//用先序序列构造一棵二叉搜索树
tree.insertNode(35);
tree.insertNode(20);
tree.insertNode(15);
tree.insertNode(16);
tree.insertNode(29);
tree.insertNode(28);
tree.insertNode(30);
tree.insertNode(40);
tree.insertNode(50);
tree.insertNode(45);
tree.insertNode(55);
System.out.print("先序遍历(递归):");
tree.preOrderTraverse(tree.getRoot());
System.out.println();
System.out.print("中序遍历(递归):");
tree.inOrderTraverse(tree.getRoot());
System.out.println();
System.out.print("后序遍历(递归):");
tree.postOrderTraverse(tree.getRoot());
System.out.println();
System.out.print("先序遍历(非递归):");
tree.preOrderTraverseNoRecursion(tree.getRoot());
System.out.println();
System.out.print("中序遍历(非递归):");
tree.inOrderTraverseNoRecursion(tree.getRoot());
System.out.println();
System.out.print("后序遍历(非递归):");
tree.postOrderTraverseNoRecursion(tree.getRoot());
System.out.println();
System.out.print("广度优先遍历:");
tree.breadthFirstTraverse(tree.getRoot());
}
}
//结点类
class Node<E extends Comparable<E>>{
E value;
Node<E> left;
Node<E> right;
Node(E value){
this.value = value;
this.left = null;
this.right = null;
}
}
//二叉搜索树类
class BinarySortTree<E extends Comparable<E>>{
private Node<E> root;
BinarySortTree(){
this.root = null;
}
//在二叉搜索树内插入节点
public void insertNode(E value) {
if(root==null) {
root = new Node<E>(value);
return;
}
Node<E> currentNode = root;
while(true){
if(value.compareTo(currentNode.value)>0) { //如果插入节点值大于当前结点
if(currentNode.right==null) { //当前结点的右子树为空, 在当前结点的右子节点位置插入
currentNode.right = new Node<E>(value);
break;
}
currentNode = currentNode.right; //当前结点的右子树不为空, 在当前结点的右子树中插入
}else if(value.compareTo(currentNode.value)<0) {
if(currentNode.left==null) {
currentNode.left = new Node<E>(value);
break;
}
currentNode = currentNode.left;
}
}
return;
}
public Node<E> getRoot(){
return root;
}
//前序遍历, 递归:先遍历根结点, 再前序遍历左子树, 再前序遍历右子树
public void preOrderTraverse(Node<E> node) {
if(node==null) {
return;
}
System.out.print(node.value+" ");
preOrderTraverse(node.left);
preOrderTraverse(node.right);
}
//中序遍历, 递归:先中序遍历左子树, 再遍历根结点, 最后中序遍历右子树
public void inOrderTraverse(Node<E> node) {
if(node==null) {
return;
}
inOrderTraverse(node.left);
System.out.print(node.value+" ");
inOrderTraverse(node.right);
}
//后序遍历,递归: 先后序遍历左子树, 再后序遍历右子树, 最后遍历根结点
public void postOrderTraverse(Node<E> node) {
if(node==null) {
return;
}
postOrderTraverse(node.left);
postOrderTraverse(node.right);
System.out.print(node.value+" ");
}
//前序遍历,非递归
public void preOrderTraverseNoRecursion(Node<E> node) {
if(node==null) {
return;
}
LinkedList<Node<E>> stack = new LinkedList<Node<E>>();
stack.push(node); //node结点先入栈, 表示要遍历node结点这棵树
Node<E> currentNode = null;
while(!stack.isEmpty()) {
//先访问根结点
currentNode = stack.pop();
System.out.print(currentNode.value+" ");
//然后分别入栈右子节点, 左子节点, 表示后面先遍历左子节点这棵树, 再遍历右子节点这棵树
if(currentNode.right!=null) {
stack.push(currentNode.right);
}
if(currentNode.left!=null) {
stack.push(currentNode.left);
}
}
}
//中序遍历, 非递归
public void inOrderTraverseNoRecursion(Node<E> node) {
if(node==null) {
return;
}
LinkedList<Node<E>> stack = new LinkedList<Node<E>>();
Node<E> currentNode = node;
while(currentNode!=null || !stack.isEmpty()){
//先找到左子节点为空的第一个结点
while(currentNode!=null){
stack.push(currentNode);
currentNode = currentNode.left;
}
currentNode = stack.pop();
//输出这个结点
System.out.print(currentNode.value+" ");
//然后遍历其右子节点, 如果为空, 该节点是叶子节点, 下一个输出的就是其父结点, 如果不为空, 找右子树的第一个左子节点为空的结点输出
currentNode = currentNode.right;
}
}
//后序遍历, 非递归
public void postOrderTraverseNoRecursion(Node<E> node) {
if(node==null) {
return;
}
LinkedList<Node<E>> stack = new LinkedList<Node<E>>();
Node<E> currentNode = node;
Node<E> lastNode = null;
while(true) {
//找第一个左子节点为空的结点
while(currentNode!=null){
stack.push(currentNode);
currentNode = currentNode.left;
}
currentNode = stack.pop();
//如果其右子节点也为空, 叶子节点, 输出;如果父结点的右子节点是上次输出的结点(第三次访问), 输出
while(currentNode.right==null || currentNode.right == lastNode){
System.out.print(currentNode.value+" ");
lastNode = currentNode;
if(stack.isEmpty()) {
return;
}
//找其父结点
currentNode = stack.pop();
}
//如果右子节点不为空遍历其右子树
stack.push(currentNode);
currentNode = currentNode.right;
}
}
//广度优先遍历
public void breadthFirstTraverse(Node<E> node) {
if(node==null) {
return;
}
Queue<Node<E>> queue = new LinkedList<Node<E>>();
queue.offer(node); //node入队表示遍历node这棵树
Node<E> currentNode = null;
while(!queue.isEmpty()) {
currentNode = queue.poll(); //先遍历结点
System.out.print(currentNode.value+" ");
//左子节点右子节点分别入队, 表示下面遍历的分别是是左子结点和右子结点
if(currentNode.left!=null) {
queue.offer(currentNode.left);
}
if(currentNode.right!=null) {
queue.offer(currentNode.right);
}
}
}
}
二叉树的深度优先遍历和广度优先遍历
最新推荐文章于 2024-07-21 13:38:21 发布