• 10、二叉树的遍历+查找


      1 package ren.laughing.datastructure.baseImpl;
      2 
      3 import ren.laughing.datastructure.base.Iterator;
      4 import ren.laughing.datastructure.base.LinkedList;
      5 import ren.laughing.datastructure.base.Queue;
      6 import ren.laughing.datastructure.base.Stack;
      7 
      8 /**
      9  * 关于二叉树的三种遍历+层次遍历+查找元素
     10  * ⑴ 遍历左子树,访问根,遍历右子树(LDR)中根(序)遍历
     11  * ⑵ 遍历左子树,遍历右子树,访问根(LRD)后根(序)遍历
     12  * ⑶ 访问根,遍历左子树,遍历右子树(DLR)先根(序)遍历
     13  * ⑷ 访问根,遍历右子树,遍历左子树(DRL)
     14  * ⑸ 遍历右子树,遍历左子树,访问根(RLD)
     15  * ⑹ 遍历右子树,访问根,遍历左子树(RDL)
     16  * @author Laughing_Lz
     17  * @time 2016年4月13日
     18  */
     19 public class TreeInteator{
     20     /**
     21      * 先序遍历
     22      * @param root 树的根结点
     23      * @return
     24      */
     25     public Iterator preOrder(BinTreeNode root){
     26         LinkedList list = new DLinkedList();
     27 //        preOrderRecursion(list,root);//先序遍历的递归算法
     28         preOrderTraverse(list, root);//先序遍历的非递归算法
     29         return list.elements();
     30     }
     31     /**
     32      * 先序遍历的递归算法
     33      * @param list 遍历后存入list中
     34      * @param btn 要遍历的树结点
     35      */
     36     public void preOrderRecursion(LinkedList list,BinTreeNode btn){
     37         if(btn == null){
     38             return;
     39         }
     40         list.insertLast(btn);
     41         preOrderRecursion(list, btn.getLChild());
     42         preOrderRecursion(list, btn.getRChild());
     43         
     44     }
     45     /**
     46      * 先序遍历的非递归算法
     47      * 先遍历根结点,左结点
     48      * 将右结点依次存入栈中
     49      * 再出栈遍历
     50      * @param list
     51      * @param btn
     52      */
     53     public void preOrderTraverse(LinkedList list,BinTreeNode btn){
     54         if(btn == null){
     55             return;
     56         }
     57         Stack s = new StackLinked();//
     58         BinTreeNode p = btn;
     59         while(p !=null){
     60             while(p != null){
     61                 list.insertLast(p);
     62                 if(p.hasRChild()){
     63                     s.push(p.getRChild());
     64                 }
     65                 p=p.getLChild();
     66             }
     67             if (!s.isEmpty()) {
     68                 p = (BinTreeNode)s.pop(); //★右子树根退栈遍历右子树
     69             }
     70         }
     71     }
     72     /**
     73      * 中序遍历
     74      * @return
     75      */
     76     public Iterator inOrder(BinTreeNode root){
     77         LinkedList list = new DLinkedList();
     78 //        inOrderRecursion(list, root);
     79         inOrderTraverse(list, root);
     80         return list.elements();
     81     }
     82     /**
     83      * 中序遍历的递归算法
     84      * @param list
     85      * @param btn
     86      */
     87     public void inOrderRecursion(LinkedList list,BinTreeNode btn){
     88         if(btn == null){
     89             return;
     90         }
     91         inOrderRecursion(list, btn.getLChild());
     92         list.insertLast(btn);
     93         inOrderRecursion(list, btn.getRChild());
     94     }
     95     /**
     96      * 中序遍历的非递归算法
     97      * @param list
     98      * @param btn
     99      */
    100     public void inOrderTraverse(LinkedList list,BinTreeNode btn){
    101         if(btn == null){
    102             return;
    103         }
    104         Stack s = new StackLinked();
    105         BinTreeNode p = btn;
    106         while(p != null||!s.isEmpty()){//★当在第一次出栈时,叶子结点的右结点为null,所以这里用||
    107             while(p != null){
    108                 s.push(p);
    109                 p = p.getLChild();
    110             }
    111             if(!s.isEmpty()){
    112                 p=(BinTreeNode) s.pop();
    113                 list.insertLast(p);
    114                 p = p.getRChild();
    115                 
    116             }
    117         }
    118         
    119     }
    120     /**
    121      * 后序遍历
    122      * @return
    123      */
    124     public Iterator postOrder(BinTreeNode root){
    125         LinkedList list = new DLinkedList();
    126 //        postOrderRecursion(list, root);
    127         postOrderTraverse(list,root);
    128         return list.elements();
    129     }
    130     /**
    131      * 后序遍历的递归算法
    132      * @param list
    133      * @param btn
    134      */
    135     public void postOrderRecursion(LinkedList list,BinTreeNode btn){
    136         if(btn == null){
    137             return;
    138         }
    139         postOrderRecursion(list, btn.getLChild());
    140         postOrderRecursion(list, btn.getRChild());
    141         list.insertLast(btn);
    142     }
    143     /**
    144      * 后序遍历的非递归算法
    145      * @param list
    146      * @param btn
    147      */
    148     public void postOrderTraverse(LinkedList list,BinTreeNode btn){
    149         if(btn == null){
    150             return;
    151         }
    152         Stack s = new StackLinked();
    153         BinTreeNode p = btn;
    154         while(p != null||!s.isEmpty()){
    155             while(p != null){//先左后右不断深入
    156                 s.push(p);//将根节点入栈
    157                 if (p.hasLChild()){
    158                     p = p.getLChild();
    159                 }else{
    160                     p = p.getRChild();
    161                 }
    162             }
    163             if(!s.isEmpty()){
    164                 p = (BinTreeNode) s.pop();
    165                 list.insertLast(p);
    166             }
    167             //★满足条件时,说明栈顶根节点右子树已访问,应出栈访问之
    168             while(!s.isEmpty()&&((BinTreeNode)s.peek()).getRChild() == p){
    169                 p = (BinTreeNode) s.pop();
    170                 list.insertLast(p);
    171             }
    172             //★转向栈顶根结点的右子树继续后序遍历
    173             if(!s.isEmpty()){
    174                 p = ((BinTreeNode)s.peek()).getRChild();
    175             }else{
    176                 p = null;
    177             }
    178         }
    179     }
    180     /**
    181      * 层次遍历
    182      * @param root
    183      * @return
    184      */
    185     public Iterator levelOrder(BinTreeNode root){
    186         LinkedList list = new DLinkedList();
    187         levelOrderTraverse(list, root);
    188         return list.elements();
    189     }
    190     /**
    191      * 层次遍历的非递归算法
    192      * @param list
    193      * @param btn
    194      */
    195     public void levelOrderTraverse(LinkedList list,BinTreeNode btn){
    196         if(btn == null){
    197             return;
    198         }
    199         Queue q = new QueueArray();//使用队列完成层次遍历
    200         q.enqueue(btn);
    201         while(!q.isEmpty()){
    202             BinTreeNode p = (BinTreeNode) q.dequeue();//取出队首结点 p 并访问
    203             list.insertLast(p);
    204             if(p.hasLChild()){
    205                 q.enqueue(p.getLChild());//★先进先出
    206             }
    207             if(p.hasRChild()){
    208                 q.enqueue(p.getRChild());
    209             }
    210         }
    211     }
    212     /**
    213      * 遍历查找元素,返回树结点
    214      * @param root 树
    215      * @param obj 要查找的元素
    216      * @return
    217      */
    218     public BinTreeNode find(BinTreeNode root,Object obj){
    219         return searchBTN(root,obj);
    220     }
    221     /**
    222      * 递归查找元素
    223      * @param btn 
    224      * @param obj
    225      * @return
    226      */
    227     private BinTreeNode searchBTN(BinTreeNode btn, Object obj) {
    228         if(btn == null){
    229             return null;
    230         }
    231         if(((Integer)btn.getData()).equals((Integer)obj)){//先比较根节点元素
    232             return btn;
    233         }
    234         BinTreeNode p = searchBTN(btn.getLChild(), obj);//否则在左子树查找
    235         if(p == null){
    236             p = searchBTN(btn.getRChild(), obj);//没找到,在右子树查找
    237         }
    238         return p;
    239     }
    240     public static void main(String[] args) {
    241         TreeInteator ti = new TreeInteator();
    242         BinTreeNode root = creatTree();
    243         System.out.println("先序遍历:");
    244         Iterator pre = ti.preOrder(root);
    245         while(!pre.isDone()){
    246             System.out.print(((BinTreeNode)pre.currentItem()).getData()+" ");
    247             pre.next();
    248         }
    249         System.out.println("
    中序遍历:");
    250         Iterator in = ti.inOrder(root);
    251         while(!in.isDone()){
    252             System.out.print(((BinTreeNode)in.currentItem()).getData()+" ");
    253             in.next();
    254         }
    255         System.out.println("
    后序遍历:");
    256         Iterator post = ti.postOrder(root);
    257         while(!post.isDone()){
    258             System.out.print(((BinTreeNode)post.currentItem()).getData()+" ");
    259             post.next();
    260         }
    261         System.out.println("
    层次遍历:");
    262         Iterator level = ti.levelOrder(root);
    263         while(!level.isDone()){
    264             System.out.print(((BinTreeNode)level.currentItem()).getData()+" ");
    265             level.next();
    266         }
    267         System.out.println("
    查找元素:");
    268         BinTreeNode result = ti.find(root, 3);
    269         System.out.println("查找结果:元素"+result.getData()+",位于第"+(root.getHeight()-result.getHeight()+1)+"行");
    270     }
    271     //生成树
    272     public static BinTreeNode creatTree(){
    273         BinTreeNode leaf1 = new BinTreeNode(1, null, null, null);
    274         BinTreeNode leaf2 = new BinTreeNode(2, leaf1, null, null);
    275         BinTreeNode leaf3 = new BinTreeNode(3, leaf1, null, null);
    276         leaf1.setLChild(leaf2);
    277         leaf1.setRChild(leaf3);
    278         BinTreeNode leaf4 = new BinTreeNode(4, leaf2, null, null);
    279         BinTreeNode leaf5 = new BinTreeNode(5, leaf2, null, null);
    280         leaf2.setLChild(leaf4);
    281         leaf2.setRChild(leaf5);
    282         BinTreeNode leaf6 = new BinTreeNode(6, leaf3, null, null);
    283         BinTreeNode leaf7 = new BinTreeNode(7, leaf3, null, null);
    284         leaf3.setLChild(leaf6);
    285         leaf3.setRChild(leaf7);
    286         return leaf1;
    287     }
    288 }
    —————————————————————————————————————行走在人猿的并行线——Laughing_Lz
  • 相关阅读:
    css常见布局问题
    jsonp原理及同源策略
    执行webpack-dev-server时,提示端口被占用。
    PHP中的<<<运算符
    PHP中的字符串类型
    数据库系统的结构
    HDU 2516 取石子游戏
    常用MySql命令列选
    mysql简单语句
    微信小程序-循环
  • 原文地址:https://www.cnblogs.com/Laughing-Lz/p/5388783.html
Copyright © 2020-2023  润新知