树的广度优先遍历和深度优先遍历(递归 非递归 Java实现)

 

树的广度优先遍历和深度优先遍历(递归非递归、Java实现)

 

在编程生活中,我们总会遇见树性结构,这几天刚好需要对树形结构操作,就记录下自己的操作方式以及过程。现在假设有一颗这样树,(是不是二叉树都没关系,原理都是一样的)

1.广度优先遍历

 英文缩写为BFS即Breadth FirstSearch。其过程检验来说是对每一层节点依次访问,访问完一层进入下一层,而且每个节点只能访问一次。对于上面的例子来说,广度优先遍历的 结果是:A,B,C,D,E,F,G,H,I(假设每层节点从左到右访问)。

先往队列中插入左节点,再插右节点,这样出队就是先左节点后右节点了。

  广度优先遍历树,需要用到队列(Queue)来存储节点对象,队列的特点就是先进先出。例如,上面这颗树的访问如下:

  首先将A节点插入队列中,队列中有元素(A);

  将A节点弹出,同时将A节点的左、右节点依次插入队列,B在队首,C在队尾,(B,C),此时得到A节点;

  继续弹出队首元素,即弹出B,并将B的左、右节点插入队列,C在队首,E在队尾(C,D,E),此时得到B节点;

  继续弹出,即弹出C,并将C节点的左、中、右节点依次插入队列,(D,E,F,G,H),此时得到C节点;

  将D弹出,此时D没有子节点,队列中元素为(E,F,G,H),得到D节点;

  。。。以此类推。。

代码:这里以二叉树为例,遍历所有节点的值

  

复制代码

/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/

public class Solution {
    public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
        ArrayList<Integer> lists=new ArrayList<Integer>();
        if(root==null)
            return lists;
        Queue<TreeNode> queue=new LinkedList<TreeNode>();
        queue.offer(root);
        while(!queue.isEmpty()){
            TreeNode tree=queue.poll();
            if(tree.left!=null)
                queue.offer(tree.left);
            if(tree.right!=null)
                queue.offer(tree.right);
            lists.add(tree.val);
        }
        return lists;
    }
}

复制代码

 

 

2、深度优先

英文缩写为DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次。对于上面的例子来说深度优先遍历的结果就是:A,B,D,E,I,C,F,G,H.(假设先走子节点的的左侧)。

深度优先遍历各个节点,需要使用到栈(Stack)这种数据结构。stack的特点是是先进后出。整个遍历过程如下:

先往栈中压入右节点,再压左节点,这样出栈就是先左节点后右节点了。

首先将A节点压入栈中,stack(A);

将A节点弹出,同时将A的子节点C,B压入栈中,此时B在栈的顶部,stack(B,C);

将B节点弹出,同时将B的子节点E,D压入栈中,此时D在栈的顶部,stack(D,E,C);

将D节点弹出,没有子节点压入,此时E在栈的顶部,stack(E,C);

将E节点弹出,同时将E的子节点I压入,stack(I,C);

...依次往下,最终遍历完成。

代码:也是以二叉树为例。非递归

复制代码

/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/

public class Solution {
    public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
        ArrayList<Integer> lists=new ArrayList<Integer>();
        if(root==null)
            return lists;
        Stack<TreeNode> stack=new Stack<TreeNode>();
        stack.push(root);
        while(!stack.isEmpty()){
            TreeNode tree=stack.pop();
      //先往栈中压入右节点,再压左节点,这样出栈就是先左节点后右节点了。
            if(tree.right!=null)
                stack.push(tree.right);
            if(tree.left!=null)
                stack.push(tree.left);
            lists.add(tree.val);
        }
        return lists;
    }
}

复制代码

 

深度优先的递归实现:

复制代码

 
public void depthOrderTraversalWithRecursive()  
    {  
        depthTraversal(root);  
    }  
      
    private void depthTraversal(TreeNode tn)  
    {  
        if (tn!=null)   
        {  
            System.out.print(tn.value+"  ");  
            depthTraversal(tn.left);  
            depthTraversal(tn.right);  
        }         
    }  

复制代码

 

 本文大量引用自:http://www.cnblogs.com/toSeeMyDream/p/5816682.html

分类: java,数据结构与算法

标签: 算法java

好文要顶 关注我 收藏该文  

夜的第八章
关注 - 6
粉丝 - 4

+加关注

« 上一篇:设计模式之组合模式
» 下一篇:设计模式之策略模式

posted on 2017-10-31 21:36 夜的第八章 阅读(11592) 评论(1) 编辑 收藏

https://www.cnblogs.com/xiaolovewei/p/7763867.html

 

 

 

 

 

 

 

邱勇Aaron

Sharing

随笔- 59  文章- 0  评论- 46 

二叉树遍历-JAVA实现

二叉树遍历分为前序、中序、后序递归和非递归遍历、还有层序遍历。

复制代码

 1 //二叉树节点
 2 public class BinaryTreeNode {
 3     private int data;
 4     private BinaryTreeNode left;
 5     private BinaryTreeNode right;
 6     
 7     public BinaryTreeNode() {}
 8 
 9     public BinaryTreeNode(int data, BinaryTreeNode left, BinaryTreeNode right) {
10         super();
11         this.data = data;
12         this.left = left;
13         this.right = right;
14     }
15 
16     public int getData() {
17         return data;
18     }
19 
20     public void setData(int data) {
21         this.data = data;
22     }
23 
24     public BinaryTreeNode getLeft() {
25         return left;
26     }
27 
28     public void setLeft(BinaryTreeNode left) {
29         this.left = left;
30     }
31 
32     public BinaryTreeNode getRight() {
33         return right;
34     }
35 
36     public void setRight(BinaryTreeNode right) {
37         this.right = right;
38     }
39 }

复制代码

 前序递归遍历算法:访问根结点-->递归遍历根结点的左子树-->递归遍历根结点的右子树

 中序递归遍历算法:递归遍历根结点的左子树-->访问根结点-->递归遍历根结点的右子树

 后序递归遍历算法:递归遍历根结点的左子树-->递归遍历根结点的右子树-->访问根结点

复制代码

  1 import com.ccut.aaron.stack.LinkedStack;
  2 
  3 public class BinaryTree {
  4     //前序遍历递归的方式
  5     public void preOrder(BinaryTreeNode root){
  6         if(null!=root){
  7             System.out.print(root.getData()+"\t");
  8             preOrder(root.getLeft());
  9             preOrder(root.getRight());
 10         }
 11     }
 12     
 13     //前序遍历非递归的方式
 14     public void preOrderNonRecursive(BinaryTreeNode root){
 15         Stack<BinaryTreeNode> stack=new Stack<BinaryTreeNode>();
 16         while(true){
 17             while(root!=null){
 18                 System.out.print(root.getData()+"\t");
 19                 stack.push(root);
 20                 root=root.getLeft();
 21             }
 22             if(stack.isEmpty()) break;
 23             root=stack.pop();
 24             root=root.getRight();
 25         }
 26     }
 27     
 28     //中序遍历采用递归的方式
 29     public void inOrder(BinaryTreeNode root){
 30         if(null!=root){
 31             inOrder(root.getLeft());
 32             System.out.print(root.getData()+"\t");
 33             inOrder(root.getRight());
 34         }
 35     }
 36     
 37     //中序遍历采用非递归的方式
 38     public void inOrderNonRecursive(BinaryTreeNode root){
 39         Stack<BinaryTreeNode> stack=new Stack<BinaryTreeNode>();
 40         while(true){
 41             while(root!=null){
 42                 stack.push(root);
 43                 root=root.getLeft();
 44             }
 45             if(stack.isEmpty())break;
 46             root=stack.pop();
 47             System.out.print(root.getData()+"\t");
 48             root=root.getRight();
 49         }
 50     }
 51     
 52     //后序遍历采用递归的方式
 53     public void postOrder(BinaryTreeNode root){
 54         if(root!=null){
 55             postOrder(root.getLeft());
 56             postOrder(root.getRight());
 57             System.out.print(root.getData()+"\t");
 58         }
 59     }
 60     
 61     //后序遍历采用非递归的方式
 62     public void postOrderNonRecursive(BinaryTreeNode root){
 63         Stack<BinaryTreeNode> stack=new Stack<BinaryTreeNode>();
 64         while(true){
 65             if(root!=null){
 66                 stack.push(root);
 67                 root=root.getLeft();
 68             }else{
 69                 if(stack.isEmpty()) return;
 70                 
 71                 if(null==stack.lastElement().getRight()){
 72                     root=stack.pop();
 73                     System.out.print(root.getData()+"\t");
 74                     while(root==stack.lastElement().getRight()){
 75                         System.out.print(stack.lastElement().getData()+"\t");
 76                         root=stack.pop();
 77                         if(stack.isEmpty()){
 78                             break;
 79                         }
 80                     }
 81                 }
 82                 
 83                 if(!stack.isEmpty())
 84                     root=stack.lastElement().getRight();
 85                 else
 86                     root=null;
 87             }
 88         }
 89     }
 90 
 91     //层序遍历
 92     public void levelOrder(BinaryTreeNode root){
 93         BinaryTreeNode temp;
 94         Queue<BinaryTreeNode> queue=new LinkedList<BinaryTreeNode>();
 95         queue.offer(root);
 96         while(!queue.isEmpty()){
 97             temp=queue.poll();
 98             System.out.print(temp.getData()+"\t");
 99             if(null!=temp.getLeft()) 
100                 queue.offer(temp.getLeft());
101             if(null!=temp.getRight()){
102                 queue.offer(temp.getRight());
103             }
104         }
105     }
106     
107     public static void main(String[] args) {
108         BinaryTreeNode node10=new BinaryTreeNode(10,null,null);
109         BinaryTreeNode node8=new BinaryTreeNode(8,null,null);
110         BinaryTreeNode node9=new BinaryTreeNode(9,null,node10);
111         BinaryTreeNode node4=new BinaryTreeNode(4,null,null);
112         BinaryTreeNode node5=new BinaryTreeNode(5,node8,node9);
113         BinaryTreeNode node6=new BinaryTreeNode(6,null,null);
114         BinaryTreeNode node7=new BinaryTreeNode(7,null,null);
115         BinaryTreeNode node2=new BinaryTreeNode(2,node4,node5);
116         BinaryTreeNode node3=new BinaryTreeNode(3,node6,node7);
117         BinaryTreeNode node1=new BinaryTreeNode(1,node2,node3);
118         
119         BinaryTree tree=new BinaryTree();
120         //采用递归的方式进行遍历
121         System.out.println("-----前序遍历------");
122         tree.preOrder(node1);
123         System.out.println();
124         //采用非递归的方式遍历
125         tree.preOrderNonRecursive(node1);
126         System.out.println();
127 
128         
129         //采用递归的方式进行遍历
130         System.out.println("-----中序遍历------");
131         tree.inOrder(node1);
132         System.out.println();
133         //采用非递归的方式遍历
134         tree.inOrderNonRecursive(node1);
135         System.out.println();
136         
137         //采用递归的方式进行遍历
138         System.out.println("-----后序遍历------");
139         tree.postOrder(node1);
140         System.out.println();
141         //采用非递归的方式遍历
142         tree.postOrderNonRecursive(node1);
143         System.out.println();
144         
145         //采用递归的方式进行遍历
146         System.out.println("-----层序遍历------");
147         tree.levelOrder(node1);
148         System.out.println();
149     }
150 }

复制代码

 

一直特立独行的二本僧,书写属于他的天空

分类: 数据结构

好文要顶 关注我 收藏该文  

邱勇Aries
关注 - 13
粉丝 - 43

+加关注

« 上一篇:Java容器-引入Guava类库
» 下一篇:Java实现-每天三道剑指Offre(2-4)

posted @ 2017-04-06 21:16 邱勇Aries 阅读(6804) 评论(0) 编辑 收藏

https://www.cnblogs.com/qiuyong/p/6675492.html

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值