package chapter_4_TreesandGraphs;
import java.util.Scanner;
import java.util.Stack;
class TreeNode {
public int data;
public TreeNode lchild;
public TreeNode rchild;
public boolean isFirst;
}
class Tree {
public TreeNode root;
public Tree() {
root = null;
}
public void insertNode(TreeNode curNode, TreeNode node) {
if(node.data < curNode.data) {
if(curNode.lchild == null) {
curNode.lchild = node;
return;
} else {
insertNode(curNode.lchild, node);
}
} else {
if(curNode.rchild == null) {
curNode.rchild = node;
return;
} else {
insertNode(curNode.rchild, node);
}
}
}
}
public class Question_4_4_2 {
public static Tree createBineryTree(int array[]) {
if(array.length == 0) {
return null;
}
TreeNode treeNode = new TreeNode();
treeNode.data = array[0];
treeNode.lchild = null;
treeNode.rchild = null;
Tree tree = new Tree();
tree.root = treeNode;
for(int i=1; i<array.length; i++) {
TreeNode node = new TreeNode();
node.data = array[i];
node.lchild = null;
node.rchild = null;
tree.insertNode(tree.root, node);
}
return tree;
}
/**
*
* 中序递归遍历
*
*/
public static void inOrderTraverse(TreeNode node) {
if(node != null) {
inOrderTraverse(node.lchild);
System.out.print(" " + node.data + " ");
inOrderTraverse(node.rchild);
}
}
/**
*
* 中序非递归遍历
*
*/
public static void inOrderTraverseByStack(TreeNode node) {
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode curNode = node;
while(curNode != null || !stack.empty()) {
while(curNode != null) {
stack.push(curNode);
curNode = curNode.lchild;
}
curNode = stack.pop();
System.out.print(" " + curNode.data + " ");
curNode = curNode.rchild;
}
}
/**
*
* 后序递归遍历
*
*/
public static void postOrderTraverse(TreeNode node) {
if(node != null) {
postOrderTraverse(node.lchild);
postOrderTraverse(node.rchild);
System.out.print(" " + node.data + " ");
}
}
/**
*
* 后序非递归遍历 方法一
* 由于后序遍历需要先遍历左子树,右子数,然后遍历根节点,
* 所以如果存在左右字树,则该节点会两次出现栈顶,一次是遍历完左子树,第二吃出现在遍历完右子树,所以
* 需要记录该节点出现在栈顶的时候是第几次遍历该节点,如果是第一次,则无需出站,继续遍历右子树,
* 如果是第二次出现在栈顶,则遍历该节点
* 所以需要使用变量记录该节点是第几次出现在栈顶
*
*/
public static void postOrderTraverseByStack(TreeNode root) {
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode curNode = root;
while(curNode!=null || !stack.empty()) {
while(curNode !=null) {
curNode.isFirst = true;
stack.push(curNode);
curNode = curNode.lchild;
}
curNode = stack.peek();
if(curNode.isFirst == true) {
curNode.isFirst = false;
curNode = curNode.rchild;
} else {
System.out.print(" " + curNode.data + " ");
stack.pop();
curNode = null;
}
}
}
/**
*
* 后序非递归遍历 方法二
*
* 保证先访问左子树、右子树再访问根节点,首先对于任意非空结点p,首先入栈,然后每次获取栈顶结点,首先判断该结点是否为叶子结点,叶子结点直接出栈访问,
* 如果不是叶子结点,则需要判断该栈顶结点是否已经访问左子树以及右子树,如果左右都已经访问则遍历该结点。
* 如果判断左右子树是否已经访问,则需要使用pre变量记录前一个已经遍历的结点,则可以判断pre是否为当前结点的左右孩子结点
*
*/
public static void postOrderTraverseByStack2(TreeNode root) {
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode curNode = root;
TreeNode preNode = null;
stack.push(curNode);
while(!stack.empty()) {
curNode = stack.peek();
if((curNode.lchild == null && curNode.rchild == null)
|| (preNode != null && (curNode.lchild==preNode || curNode.rchild==preNode))) {
stack.pop();
System.out.print(" " + curNode.data + " ");
preNode = curNode;
} else {
if(curNode.rchild != null) {
stack.push(curNode.rchild);
}
if(curNode.lchild != null) {
stack.push(curNode.lchild);
}
}
}
}
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
String string = scanner.nextLine();
// 2 1 3 5 4 6
String strs[] = string.split(" ");
int array[] = new int[strs.length];
for(int i=0; i<array.length; i++) {
array[i] = Integer.parseInt(strs[i]);
}
Tree tree = createBineryTree(array);
System.out.println("中序递归遍历二叉树:");
inOrderTraverse(tree.root);
System.out.println("\n");
System.out.println("中序非递归遍历二叉树:");
inOrderTraverseByStack(tree.root);
System.out.println("\n");
System.out.println("后序递归遍历二叉树:");
postOrderTraverse(tree.root);
System.out.println("\n");
System.out.println("后序非递归遍历二叉树,方法一:");
postOrderTraverseByStack(tree.root);
System.out.println("\n");
System.out.println("后序非递归遍历二叉树,方法二:");
postOrderTraverseByStack(tree.root);
System.out.println("\n");
}
}
数据结构:二叉树的非递归遍历
最新推荐文章于 2024-09-20 19:40:22 发布