数据结构之树的遍历

       树是数据结构中非常重要的一个结构,二叉树的遍历也是非常重要的知识。温故而知新,今天来复习下树的遍历方法。

       二叉树的遍历分为:前序遍历,中序遍历,后序遍历,以及层序遍历。前序遍历、中序遍历、后序遍历可以分别通过递归方法和非递归方法实现。代码如下:

---------------------------------------------------------------------------------------

今天新加了层序遍历的实现,详见代码 layerTranverse。


package test;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

/**
 *   该二叉树的原型如下:
 *         A
 *       /   \
 *      B     C
 *     / \    / \
 *    D   E  F   G
 *       / \  \  /
 *      H   I  J P
 **/
public class BinaryTree {
	
	//打印节点信息
	public static void printNode(Node<String> node){
		System.out.print("" + node.getData() + " " );
	}
	
	//定义节点
	class Node<T>{
		private T data;
		private Node<T> leftNode;
		private Node<T> rightNode;
		
		public Node( T data, Node<T> leftNode, Node<T> rightNode){
			this.data = data;
			this.leftNode = leftNode;
			this.rightNode = rightNode;
		}
		public T getData() {
			return data;
		}
		public void setData(T data) {
			this.data = data;
		}
		
		public Node<T> getLeftNode() {
			return leftNode;
		}
		public void setLeftNode(Node<T> leftNode) {
			this.leftNode = leftNode;
		}
		
		public Node<T> getRightNode() {
			return rightNode;
		}
		public void setRightNode(Node<T> rightNode) {
			this.rightNode = rightNode;
		}
	}
	
	// 初始化二叉树  
    public Node<String> init() {  
        Node<String> D = new Node<String>("D", null, null);  
        Node<String> H = new Node<String>("H", null, null);  
        Node<String> I = new Node<String>("I", null, null);  
        Node<String> J = new Node<String>("J", null, null);  
        Node<String> P = new Node<String>("P", null, null);  
        Node<String> G = new Node<String>("G", P, null);  
        Node<String> F = new Node<String>("F", null, J);  
        Node<String> E = new Node<String>("E", H, I);  
        Node<String> B = new Node<String>("B", D, E);  
        Node<String> C = new Node<String>("C", F, G);  
        Node<String> A = new Node<String>("A", B, C);  
        return A;  
    }  
    
    // 递归前序遍历
    protected void preOrder(Node<String> node){
    	BinaryTree.printNode(node);
    	if(node.getLeftNode() != null){
    		this.preOrder(node.getLeftNode());
    	}
    	if(node.getRightNode() != null){
    		this.preOrder(node.getRightNode());
    	}
    }

	// 递归中序遍历
    protected void middleOrder(Node<String> node){
		if( node.getLeftNode() != null ){
			this.middleOrder(node.getLeftNode());
		}
		BinaryTree.printNode(node);
		if(node.getRightNode() != null){
			this.middleOrder(node.getRightNode());
		}
	}
	
	// 递归后序遍历
	protected void afterOrder(Node<String> node){
		if(node.getLeftNode() != null){
			this.afterOrder(node.getLeftNode());
		}
		if(node.getRightNode() != null){
			this.afterOrder(node.getRightNode());
		}
		BinaryTree.printNode(node);
	}
	
	// 层序遍历
	public static void layerTranverse(Node<String> root){
		if(root==null){
			return;
		}
		Queue<Node> q = new LinkedList<Node>();
		q.add(root);
		while(!q.isEmpty()){
			Node node = q.poll();
			System.out.print(node.data+" ");
			if(node.leftNode != null){
				q.add(node.leftNode);
			}
			if(node.rightNode != null){
				q.add(node.rightNode);
			}
		}
	}
	/**
	 * 非递归方式进行遍历,需要构造栈
	 * 以前序为例:
	 * 对于任一结点,其可看做是根结点,因此可以直接访问。
	 * 当访问完其根节点时,若其左孩子不为空,则再访问它的左子树;
	 * 当访问完其左子树时,若其有孩子不为空,则再访问它的右子树。
	 * 
	 *  对于任一结点P:
	 *  1)访问结点P,并将结点P入栈;
	 *  2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至1);若不为空,则将P的左孩子置为当前的结点P;
	 *  3)直到P为NULL并且栈为空,则遍历结束。
	 */
	
	// 非递归方式前序遍历
	protected static void preOrder1(Node node){
		Stack<Node> stack = new Stack<Node>();
		if(node!=null){
			stack.push(node);
			while(!stack.isEmpty()){
				node = stack.pop();
				BinaryTree.printNode(node);
				if(node.getRightNode() != null){
					stack.push(node.getRightNode()); 
				}
				if(node.getLeftNode() != null){
					stack.push(node.getLeftNode()); 
				}
			}
		}
	}
	
	// 非递归实现中序遍历
    protected static void midOrder1(Node p) {  
        Stack<Node> stack = new Stack<Node>();  
        Node node = p;  
        while (node != null || stack.size() > 0) {  
            while (node != null) {  
                stack.push(node);  
                node = node.getLeftNode();  
            }  
            if (stack.size() > 0) {  
                node = stack.pop();  
                BinaryTree.printNode(node);  
                node = node.getRightNode();  
            }  
        }  
    }  
    

    // 非递归实现后序遍历 双栈法1   
    protected static void afterOrder1(Node p) {  
        Stack<Node> lstack = new Stack<Node>();  
        Stack<Node> rstack = new Stack<Node>();  
        Node node = p, right;  
        do {  
            while (node != null) {  
                right = node.getRightNode();  
                lstack.push(node);  
                rstack.push(right);  
                node = node.getLeftNode();  
            }  
            node = lstack.pop();  
            right = rstack.pop();  
            if (right == null) {  
                BinaryTree.printNode(node);  
            }
            else {  
                lstack.push(node);  
                rstack.push(null);  
            }
            node = right;  
        } while (lstack.size() > 0 || rstack.size() > 0);  
    } 
    
    // 非递归实现后序遍历 双栈法2
    protected static void iterativePostorder4(Node p) {  
        Stack<Node> stack = new Stack<Node>();  
        Stack<Node> temp = new Stack<Node>();  
        Node node = p;  
        while (node != null || stack.size() > 0) {  
            while (node != null) {  
                temp.push(node);  
                stack.push(node);  
                node = node.getRightNode();  
            }  
            if (stack.size() > 0) {  
                node = stack.pop();  
                node = node.getLeftNode();  
            }  
        }  
        while (temp.size() > 0) {  
            node = temp.pop();  
            BinaryTree.printNode(node);  
        }  
    } 
    
    
    // 非递归实现后序遍历 单栈法  
    protected static void iterativePostorder3(Node p) {  
        Stack<Node> stack = new Stack<Node>();  
        Node node = p, prev = p;  
        while (node != null || stack.size() > 0) {  
            while (node != null) {  
                stack.push(node);  
                node = node.getLeftNode();  
            }  
            if (stack.size() > 0) {  
                Node temp = stack.peek().getRightNode();  
                if (temp == null || temp == prev) {  
                    node = stack.pop();  
                    BinaryTree.printNode(node);  
                    prev = node;  
                    node = null;  
                } else {  
                    node = temp;  
                }  
            }  
  
        }  
    }  
    public static void main(String[] args){
		BinaryTree binaryTree = new BinaryTree();
		Node<String> node = binaryTree.init();
		System.out.println("二叉树层序遍历的结果:-->");
		BinaryTree.layerTranverse(node);
		System.out.println("递归前序遍历的结果:-->");
		binaryTree.preOrder(node);
		System.out.println('\n');
		System.out.println("非递归前序遍历的结果:-->");
		BinaryTree.preOrder1(node);
		System.out.println('\n');
		System.out.println("------------------------------------------");
		System.out.println("递归中序遍历的结果:-->");
		binaryTree.middleOrder(node);
		System.out.println("非递归中序遍历方法的结果:-->");
		BinaryTree.midOrder1(node);
		System.out.println('\n');
		System.out.println("------------------------------------------");
		System.out.println("递归后序遍历的结果:-->");
		binaryTree.afterOrder(node);
		System.out.println('\n');
		System.out.println("非递归后序遍历的结果:-->");
		binaryTree.iterativePostorder4(node);
		System.out.println('\n');
		
	}





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值