数据结构:二叉树的非递归遍历

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");
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值