树(四):二叉树的遍历

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

一、深度优先遍历

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<treeNode> p=new Stack<treeNode>();
        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<treeNode> p=new Stack<treeNode>();
        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<treeNode> n1=new Stack<treeNode>();
        Stack<treeNode> n2=new Stack<treeNode>();
        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<treeNode> n=new LinkedList<treeNode>();
        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入队,进入循环——判空、队首元素出队、输出该元素、该元素左孩子、右孩子入队(注意先左后右),直至队空。

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

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容