算法复习之二叉树的遍历

节点类:

public class Node <T>{
    public T data;
    public Node<T> left = null;
    public Node<T> right = null;
    public Node(T data) {
        super();
        this.data = data;
    }
}

先根遍历:先访问根节点元素,然再访问左右子树节点

    /**
     * 递归方法
     * @param root
     */
    public <T> void  traverse(Node<T> root){
        if(root == null){
            return ;
        }
        out.println(root.data);
        traverse(root.left);
        traverse(root.right);
    }
    /**
     * 非递归方法,利用LinkedList模拟函数栈
     * @param root
     */
    public <T> void  traverse2(Node<T> root){
        LinkedList<Node<T>> list = new LinkedList<>();
        list.push(root);
        while(list.size()>0){
            Node<T> now = list.pop();
            if(now==null){
                continue;
            }
            out.println(now.data);
            list.push(now.right);//先添加右节点再添加左节点确保左节点先被访问
            list.push(now.left);
        }
    }
}

中根遍历

package binaryTree;

import java.io.PrintStream;
import java.util.LinkedList;

import org.junit.Test;

public class InorderTraversal {
    protected PrintStream out =null;
    public void setOut(PrintStream out) {
        this.out = out;
    }
    /**
     * 递归方法
     * @param root
     */
    public <T> void  traverse(Node<T> root){
        if(root == null){
            return ;
        }
        traverse(root.left);
        out.println(root.data);
        traverse(root.right);
    }
    /**
     * 非递归方法,利用2个LinkedList模拟遍历过程,第一个栈中存放第二个栈顶元素的左节点,第一个栈空,说明第二个栈顶元素左节点访问完毕
     * @param root
     */
    public <T> void  traverse2(Node<T> root){
        LinkedList<Node<T>> first = new LinkedList<>();
        LinkedList<Node<T>> secend = new LinkedList<>();
        first.push(root);
        while(first.size()>0||secend.size()>0){
            if(first.size()==0){
                Node<T> now = secend.removeLast();
                out.println(now.data);
                if(now.right!=null){
                    first.push(now.right);
                }
                continue;
            }
            Node<T> now = first.pop();
            secend.add(now);
            if(now.left!=null){
                first.add(now.left);
            }
        }
    }
    /**
     * 非递归方法,利用LinkedList模拟栈,now指向stack栈顶元素的左子树,now指向空,说明栈顶元素左子树访问完毕
     * @param root
     */
    public <T> void  traverse3(Node<T> root){
        LinkedList<Node<T>> stack = new LinkedList<>();
        Node<T> now  = root;
        while(now!=null||stack.size()>0){
            if(now==null){
                now = stack.pop();
                out.println(now.data);
                now=now.right;
            }else{
                stack.push(now);
                now = now.left;
            }
        }
    }
}

后根遍历:

package binaryTree;

import java.io.PrintStream;
import java.util.LinkedList;

import org.junit.Test;

public class PostorderTraversal {
    protected PrintStream out =null;
    public void setOut(PrintStream out) {
        this.out = out;
    }
    /**
     * 递归方法
     * @param root
     */
    public <T> void  traverse(Node<T> root){
        if(root == null){
            return ;
        }
        traverse(root.left);
        traverse(root.right);
        out.println(root.data);
    }
    /**
     * 非递归方法,利用两个指针,stack中记录访问过的节点
     * @param root
     */
    public <T> void  traverse2(Node<T> root){
        LinkedList<Node<T>> stack = new LinkedList<>();
        Node<T> now ;
        Node<T> pre = null;
        stack.push(root);
        while(stack.size()>0){
            now = stack.peek();
            if((now.left==null&&now.right==null)||
                ( pre!=null&&(pre==now.left||pre==now.right)) ){//now没有子节点或者上次访问的节点是now的子节点
                out.println(now.data);
                stack.pop();
                pre = now;
            }else{
                if(now.right!=null){
                    stack.push(now.right);
                }
                if(now.left!=null){
                    stack.push(now.left);
                }
            }
        }
    }
}

层次遍历:

package binaryTree;

import java.io.PrintStream;
import java.util.LinkedList;

import org.junit.Test;

public class LevelTraversal {
    protected PrintStream out =null;
    public void setOut(PrintStream out) {
        this.out = out;
    }
    /**
     * 非递归方法,利用LinkedList模拟队列,很简单
     * @param root
     */
    public <T> void  traverse(Node<T> root){
        LinkedList<Node<T>> queue = new LinkedList<>();
        Node<T> now ;
        queue.offer(root);
        while(queue.size()>0){
            now = queue.poll();
            out.println(now.data);
            if(now.left!=null) queue.add(now.left);
            if(now.right!=null) queue.add(now.right);
        }
    }
}

测试函数:

@Test
    public void test(){
        Node<Integer> root1 = new Node<Integer>(1);
        Node<Integer> root2 = new Node<Integer>(2);
        Node<Integer> root3 = new Node<Integer>(3);
        Node<Integer> root4 = new Node<Integer>(4);
        Node<Integer> root5 = new Node<Integer>(5);
        Node<Integer> root6 = new Node<Integer>(6);
        Node<Integer> root7 = new Node<Integer>(7);
        this.out = System.out;
        root1.left = root2;
        root1.right = root5;
        root2.left = root3;
        root2.right = root4;
        root5.left = root6;
        root5.right = root7;
        traverse(root1);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值