部分文章内容为公开资料查询整理,原文出处可能未标注,如有侵权,请联系我,谢谢。邮箱地址:gnivor@163.com ►►►需要气球么?请点击我吧!

编程之美--3.10分层遍历二叉树

问题一:给定一棵二叉树,要求按分层遍历该二叉树,即从上到下的层次访问该二叉树(每一层将单独输出一行),每一层要求访问的顺序为从左到右,并将节点依次编号。
问题二:写一个函数,打印二叉树中某层次的节点(从左到右),其中根节点为第0层,函数原型为int PrintNodeAtLevel(Node* root, int level),成功返回1,失败返回0。

 

解:问题1

利用队列(书上的方法没用队列,不过和队列的原理一样)

//从上到下层序遍历
public static void GetTreeByLayer(ChainTree mytree){
    Queue queue = new LinkedList<Node>();
    Node node = mytree.rootnode ;
    queue.add(node);
    while(!queue.isEmpty()){
        node = (Node) queue.poll();
        System.out.print(node.key+" ");
        if(node.lnode!=null)
            queue.add(node.lnode);
        if(node.rnode!=null)
            queue.add(node.rnode);
    }
}

 

从下到上,从左到右层序遍历

其实可以将从上到下层序遍历的结果入栈,然后再输出。这里采用另一种方法。用list存放

//从下到上层序遍历。其实可以将从上到下层序遍历的结果入栈,然后再输出。
//采用另一种方法。用list存放    
public static void GetTreeByLayerRevLR(ChainTree mytree){
    List list = new LinkedList();
    Node node = mytree.rootnode ;
    list.add(node);
    int start = 0;
    int end = 1;
    while(start!=end){
        node = (Node) list.get(start);
        start++;            
        //System.out.print(node.key+" ");
        
        if(node.rnode!=null){
            list.add(node.rnode);
            end++;
        }
        
        if(node.lnode!=null){
            list.add(node.lnode);
            end++;
        }
    }
    while(start!=0){
        node = (Node) list.get(--start);
        System.out.print(node.key+" ");
    }
}


从下到上,从右到左层序遍历,和从左到右基本一致,只是插入子节点的顺序不同

public static void GetTreeByLayerRevRL(ChainTree mytree){
    List list = new LinkedList();
    Node node = mytree.rootnode ;
    list.add(node);
    int start = 0;
    int end = 1;
    while(start!=end){
        node = (Node) list.get(start);
        start++;            
        if(node.lnode!=null){
            list.add(node.lnode);
            end++;
        }
        if(node.rnode!=null){
            list.add(node.rnode);
            end++;
        }            
    }
    while(start!=0){
        node = (Node) list.get(--start);
        System.out.print(node.key+" ");
    }

}

 

解:问题2
问题2为问题1的子问题。可以利用第一问的方法。

书上用了递归的方法

//输出所有第level层的元素,根节点为第0层
    public static boolean printNodeAtLevel(Node node,int level){
        if(node==null) return false;
        if(level==0){
            System.out.print(node.key+" ");
            return true;
        }
        else return printNodeAtLevel(node.lnode,level-1)|printNodeAtLevel(node.rnode,level-1);
    }

 

main()函数

public static void main(String args[]){
    ChainTree mytree = new ChainTree();
    mytree.insert(24);
    mytree.insert(14);
    mytree.insert(45);
    mytree.insert(13);
    mytree.insert(23);
    mytree.insert(25);
    mytree.insert(70);
    mytree.insert(38);
    mytree.insert(50);
    mytree.insert(95);
    mytree.insert(59);
    mytree.insert(96);
    System.out.println("---先序遍历---");
    mytree.preOrder(mytree.rootnode);
    System.out.println("\n---中序遍历---");
    mytree.inOrder(mytree.rootnode);
    System.out.println("\n---层序遍历---");
    GetTreeByLayer(mytree);
    System.out.println("\n---层序遍历(从下到上,从左到右)---");
    GetTreeByLayerRevLR(mytree);
    System.out.println("\n---层序遍历(从下到上,从右到左)---");
    GetTreeByLayerRevRL(mytree);
    System.out.println("\n---第i层元素---");
    System.out.println(printNodeAtLevel(mytree.rootnode,2));
}


运行结果:

---先序遍历---
24 14 13 23 45 25 38 70 50 59 95 96 
---中序遍历---
13 14 23 24 25 38 45 50 59 70 95 96 
---层序遍历---
24 14 45 13 23 25 70 38 50 95 59 96 
---层序遍历(从下到上,从左到右)---
59 96 38 50 95 13 23 25 70 14 45 24 
---层序遍历(从下到上,从右到左)---
96 59 95 50 38 70 25 23 13 45 14 24 
---第i层元素---
13 23 25 70 true

 

完整代码:

package com310.fenceng.bianli.erchashu;

import java.util.LinkedList;
import java.util.List;
import java.util.Queue;



public class MyGetTreeByLayer {
    public static void main(String args[]){
        ChainTree mytree = new ChainTree();
        //mytree.rootnode=new Node(100,"张三");
        mytree.insert(24);
        mytree.insert(14);
        mytree.insert(45);
        mytree.insert(13);
        mytree.insert(23);
        mytree.insert(25);
        mytree.insert(70);
        mytree.insert(38);
        mytree.insert(50);
        mytree.insert(95);
        mytree.insert(59);
        mytree.insert(96);
        System.out.println("---先序遍历---");
        mytree.preOrder(mytree.rootnode);
        System.out.println("\n---中序遍历---");
        mytree.inOrder(mytree.rootnode);
        System.out.println("\n---层序遍历---");
        GetTreeByLayer(mytree);
        System.out.println("\n---层序遍历(从下到上,从左到右)---");
        GetTreeByLayerRevLR(mytree);
        System.out.println("\n---层序遍历(从下到上,从右到左)---");
        GetTreeByLayerRevRL(mytree);
        System.out.println("\n---第i层元素---");
        System.out.println(printNodeAtLevel(mytree.rootnode,2));
    }
    
    //从上到下层序遍历
    public static void GetTreeByLayer(ChainTree mytree){
        Queue queue = new LinkedList<Node>();
        Node node = mytree.rootnode ;
        queue.add(node);
        while(!queue.isEmpty()){
            node = (Node) queue.poll();
            System.out.print(node.key+" ");
            if(node.lnode!=null)
                queue.add(node.lnode);
            if(node.rnode!=null)
                queue.add(node.rnode);
        }
    }
    
    //从下到上层序遍历。其实可以将从上到下层序遍历的结果入栈,然后再输出。
    //采用另一种方法。用数组存放    
    public static void GetTreeByLayerRevLR(ChainTree mytree){
        List list = new LinkedList();
        Node node = mytree.rootnode ;
        list.add(node);
        int start = 0;
        int end = 1;
        while(start!=end){
            node = (Node) list.get(start);
            start++;            
            //System.out.print(node.key+" ");
            
            if(node.rnode!=null){
                list.add(node.rnode);
                end++;
            }
            
            if(node.lnode!=null){
                list.add(node.lnode);
                end++;
            }
        }
        while(start!=0){
            node = (Node) list.get(--start);
            System.out.print(node.key+" ");
        }
    }
    
    public static void GetTreeByLayerRevRL(ChainTree mytree){
        List list = new LinkedList();
        Node node = mytree.rootnode ;
        list.add(node);
        int start = 0;
        int end = 1;
        while(start!=end){
            node = (Node) list.get(start);
            start++;            
            if(node.lnode!=null){
                list.add(node.lnode);
                end++;
            }
            if(node.rnode!=null){
                list.add(node.rnode);
                end++;
            }            
        }
        while(start!=0){
            node = (Node) list.get(--start);
            System.out.print(node.key+" ");
        }

    }

    //输出所有第level层的元素,根节点为第0层
    public static boolean printNodeAtLevel(Node node,int level){
        if(node==null) return false;
        if(level==0){
            System.out.print(node.key+" ");
            return true;
        }
        else return printNodeAtLevel(node.lnode,level-1)|printNodeAtLevel(node.rnode,level-1);
    }
}

class Node{ //节点类
    int key; //关键字
    Node lnode; //左节点
    Node rnode; //右节点
    
    public Node(int key){this.key=key;}
    public Node(){}
}

class ChainTree{//树类,这里为有序二叉树
    Node rootnode; //树根
    
    //方法
    
    public void insert(int key){//插入元素
        Node node = new Node(key);
        if(rootnode==null){
            rootnode = node;
        }
        else{
            Node temp = rootnode;
            Node parent ;
            while(true){//寻找插入位置
                parent = temp;
                if(key<temp.key){ //进入左子树内查找
                    temp=temp.lnode;
                    if(temp==null){
                        parent.lnode=node;    
                        return;
                    }
                }
                else{//进入右子树内查找
                    temp=temp.rnode;
                    if(temp==null){
                        parent.rnode=node;
                        return;                                
                    }
                }
            }
        }
    }//end insert
    
    public void DisplayNode(Node node){//显示该节点信息
        System.out.print(node.key+" ");
    }
    
    public void preOrder(Node node){//先序遍历 递归
        if(node!=null){
            DisplayNode(node);
            preOrder(node.lnode);            
            preOrder(node.rnode);
        }
    }
    
    public void inOrder(Node node){//中序遍历 递归
        if(node!=null){            
            inOrder(node.lnode);
            DisplayNode(node);
            inOrder(node.rnode);
        }
    }
    
}
View Code

程序中用到的Tree数据结构见如下链接
http://www.cnblogs.com/gnivor/articles/4418235.html

posted @ 2015-06-29 21:15  流了个火  阅读(114)  评论(0)    收藏  举报
►►►需要气球么?请点击我吧!►►►
View My Stats