树(四):二叉树的遍历

二叉树的遍历分为深度优先遍历、广度优先遍历。深度优先分为前序遍历、中序遍历、后序遍历,每种方法又分为递归和非递归;广度优先只有一种。

一、深度优先遍历

1.前序遍历

- 递归实现:
public void preTree(treeNode T) {
        if(T==null)
        return;
        
        System.out.print(T.data+" ");
        preTree(T.lchild);
        preTree(T.rchild);
}

其中的参数treeNode T是已建立好的根结点root,后面也是。

- 非递归实现:
public void nonRecursivePreTree() {
        if(root==null) return;
        Stack p=new Stack();
        p.push(root);
        while(!p.isEmpty()) {
            treeNode t=p.pop();
            System.out.print(t.data+" ");
            if(t.rchild!=null)
                p.push(t.rchild);
            if(t.lchild!=null)
                p.push(t.lchild);           
        }       
}

大概思路:准备一个栈p,先将根结点压入栈,然后进入循环——判空、栈顶元素出栈、输出该元素、该元素右孩子入栈、左孩子入栈(注意先右后左),直至栈空。

2.中序遍历

- 递归实现:
public void inTree(treeNode T) {
        if(T==null)
        return;
        
        inTree(T.lchild);
        System.out.print(T.data+" ");
        inTree(T.rchild);
}
- 非递归实现:
public void nonRecursiveInTree() {
        if(root==null) return;
        treeNode n=root;
        Stack p=new Stack();
        while(!p.isEmpty()||n!=null) {
            
            while(n!=null) {
                p.push(n);
                n=n.lchild;
            }
            System.out.print(p.peek().data+" ");
            n=p.pop().rchild;           
        }
}

大概思路:准备一个栈p、一个临时结点n,将根结点root赋予n,进入循环——判断栈空或n是否为null,然后一直向左找孩子,找到一个左孩子就直接入栈,直到左孩子为null,不入栈,此时n=null,然后输出此时的栈顶元素值、出栈、让n等于该元素的右孩子。

3.后序遍历

- 递归实现:
public void postTree(treeNode T) {
        if(T==null)
        return;
        
        postTree(T.lchild);     
        postTree(T.rchild);
        System.out.print(T.data+" ");
}
- 非递归实现:
public void nonRecursivePostTree() {
        if(root==null)return;
        Stack n1=new Stack();
        Stack n2=new Stack();
        n1.push(root);
        while(!n1.isEmpty()) {
            treeNode t=n1.pop();
            n2.push(t);
            if(t.lchild!=null)
                n1.push(t.lchild);
            if(t.rchild!=null) {
                n1.push(t.rchild);
            }                       
        }
        
        while(!n2.isEmpty()) {
            System.out.print(n2.pop().data+" ");
        }
        
}

大概思路:准备两个栈,将root压入第一个栈,进入循环——第一个栈判空,出栈栈顶元素,将其压入第二个栈中,然后将该元素的左孩子、右孩子压入第一个栈中(注意先左后右),直至第一个栈空,然后按序输出第二个栈即可。

二、广度优先遍历

public void BFS() {
        if(root==null)return;

        Queue n=new LinkedList();
        n.offer(root);
        while(!n.isEmpty()) {
            treeNode t=n.poll();
            System.out.print(t.data+" ");
            if(t.lchild!=null)
                n.offer(t.lchild);
            if(t.rchild!=null)
                n.offer(t.rchild);
        }
        
}

大概思路:准备一个队列,先让根结点root入队,进入循环——判空、队首元素出队、输出该元素、该元素左孩子、右孩子入队(注意先左后右),直至队空。

广度优先遍历形式较为单一,并不像深度优先遍历那样复杂,但都有不可小视的作用。

你可能感兴趣的:(树(四):二叉树的遍历)