zoukankan      html  css  js  c++  java
  • 二叉排序树BST

    今天没花20分钟,就把BST的代码写出来了。毕竟寒假学了一遍,脑子里有影响,也很好理解。

    只是出现了两个问题:

      1.我在编写while循环的时候,就想到了新建叶子节点之后就break。但是,我又“机智”的想到,while(parent!=null)语句就可以检测循环的结束了,不关有没有新建叶子节点,都可以直接写parent=parent.child语句,进入下一个循环。因为如果没有新建叶子节点,parent就会变成null,从而跳出循环。

      但是我想错了。如果找到了并新建叶子节点,再执行parent=parent.child语句就会使parent变成新建的那个节点,从而无线循环下去。(我按了F5等着出结果呢,结果风扇沙沙吹,CPU快烧坏了)

      解决方法:加入break语句。

      总结:算法结构不能想当然。以及懂的调试。

      2.我调用以前写的 toString 函数进行打印。结果出现空指针错误。经查是一个老bug,浪费了很多时间。

      

    BST的Java代码:

     1 class SearchBST extends BTtree{//二叉查找树
     2     SearchBST(int[] nums){//由二维数组构造
     3         root.data=String.valueOf(nums[0]);//构造根节点
     4         for(int i=1;i<nums.length;i++){//对其他元素进行构造
     5             BTNode node=new BTNode();
     6             node.data=String.valueOf(nums[i]);//构造叶子节点
     7             BTNode parent=root;
     8             int nodeV=nums[i];
     9             while(parent!=null){
    10                 int parentV=Integer.valueOf(parent.data).intValue();//当前根节点的值
    11                 if(nodeV<parentV){//左叶子
    12                     if(parent.lChild==null){//当前根节点的左叶子非空
    13                         parent.lChild=node;//挂入节点
    14                         break;                //如果这里没有加【break】,就会死循环。待解决☆☆☆
    15                     }
    16                     parent=parent.lChild;//如果这里空了,跳出循环
    17                 }else{
    18                     if(parent.rChild==null){
    19                         parent.rChild=node;//挂入节点
    20                         break;                //☆☆☆
    21                     }
    22                     parent=parent.rChild;//如果这里空了,跳出循环                    
    23                 }
    24             }
    25         }
    26     }
    27     SearchBST(){}
    28 }

    打印输出:(*代表空)

    补充一个递归算法:

        void AVLinsert(BTNode node,BTNode parent,boolean isLeft,String data){
            int dataV=Integer.valueOf(data).intValue();
            int nodeV=0;
            if(node!=null) nodeV=Integer.valueOf(node.data).intValue();
            BTNode newNode=new BTNode();
            newNode.data=data;
            if(node==null){
                if(isLeft) parent.lChild=newNode;
                else        parent.rChild=newNode;
            }
            else if(dataV<nodeV){//向左插入
                AVLinsert(node.lChild,node,true,data);
            }else{
                AVLinsert(node.rChild,node,false,data);
            }
        }

    完整代码:

      1 import java.util.*;
      2 
      3 public class demo {
      4     public static void main(String args[]){
      5         BTtree tree=new BTtree(3);
      6         tree.InOrderTraversal();
      7         System.out.print(tree);
      8         BThrTree thrTree=new BThrTree(tree);
      9         thrTree.InOrderTraversal();
     10         thrTree.InThreadingFabric();
     11         thrTree.InOrderTraversal_Thr();
     12         int []nums={45,12,53,3,37,24,100,61,90,78};
     13         SearchBST bst=new SearchBST(nums);
     14         bst.PreOrderTraversal();
     15         System.out.println(bst);
     16     //    thrTree.InOrderTraversal_Thr();
     17     }
     18 }
     19 
     20 class BTtree{//二叉树类
     21     class BTNode{//节点类
     22         String data=new String("0");;
     23         BTNode lChild=null;
     24         BTNode rChild=null;
     25         boolean LTag=false;//=0 : 指向左孩子。 =1 : 指向前驱
     26         boolean RTag=false;//=0 : 指向右孩子。 =1 : 指向后继
     27     }
     28     protected BTNode root=new BTNode();
     29     BTtree(){
     30     }
     31     BTtree(int layer){
     32         //用队列的方式构造n层树
     33         List<BTNode> queue=new ArrayList<BTNode>();
     34         int front=0;
     35         int rear=0;//队尾插入
     36         queue.add(root);//初始化入队
     37         rear++;
     38         int i , k=0 , j;
     39         for(j=0;j<layer;j++){
     40             int nowRear=rear;
     41             for(i=front;i<nowRear;i++){
     42                 //出队,生两个孩子
     43                 BTNode parent=queue.get(front++);
     44                 BTNode lChild=new BTNode();
     45                 lChild.data=Integer.toString(++k);
     46                 BTNode rChild=new BTNode();
     47                 rChild.data=Integer.toString(++k);
     48                 parent.lChild=lChild;
     49                 parent.rChild=rChild;
     50                 queue.add(lChild);
     51                 rear++;
     52                 queue.add(rChild);
     53                 rear++;
     54             }
     55         }
     56     }
     57     BTtree(String express){//通过中缀表达式进行构造
     58         //1.对表达式进行括号补全。
     59         
     60         
     61     }
     62     public String toString(){//重写打印函数
     63         List<BTNode> queue=new ArrayList<BTNode>();
     64         List<String[]> PrintList=new ArrayList<String[]>();
     65         int front=0;
     66         int rear=0;//队尾插入
     67         queue.add(root);//初始化入队
     68         rear++;
     69         int i , k=0 , j;
     70         
     71         String emptySignal=new String("");//空信号
     72         
     73         String str[]=new String[1];
     74         str[0]=root.data;
     75         PrintList.add(str);//打印数据结构初始化
     76         int layer=1;//下一层字符串的数目是2^1=2。
     77         int pos=0;
     78         
     79         boolean flag=true;
     80         ok:
     81         while(flag){
     82             pos=0;//pos初始化
     83             String tmp[]=new String[(int)Math.pow((int)2, (int)(layer++))];//length=2^layer
     84             flag=false;        //循环标志初始化
     85             int nowRear=rear;
     86             int nowFront=front;
     87             for(i=front;i<nowRear;i++){
     88                 String nowStr=new String();
     89                 BTNode parent=queue.get(front++);
     90                 if(parent==null) break ok;    //跳出两重循环
     91                 if(parent.data.equals(emptySignal)){//如果是空的,派生出两个空孩子
     92                     for(int t=0;t<2;t++){
     93                         tmp[pos++]="*";
     94                         BTNode empty=new BTNode();
     95                         empty.data=emptySignal;
     96                         queue.add(empty);rear++;
     97                     }
     98                 }else{
     99                     if(parent.lChild!=null){
    100                         flag=true;                    //只要这一层存在孩子,就可以继续循环下去。
    101                         queue.add(parent.lChild);
    102                         tmp[pos++]=parent.lChild.data;
    103                         rear++;
    104                     }else{
    105                         tmp[pos++]="*";
    106                         BTNode empty=new BTNode();
    107                         empty.data=emptySignal;
    108                         queue.add(empty);
    109                         rear++;
    110                     }
    111                     if(parent.rChild!=null){
    112                         flag=true;
    113                         queue.add(parent.rChild);
    114                         tmp[pos++]=parent.rChild.data;
    115                         rear++;
    116                     }else{
    117                         tmp[pos++]="*";
    118                         BTNode empty=new BTNode();
    119                         empty.data=emptySignal;
    120                         queue.add(empty);
    121                         rear++;
    122                     }
    123                 }
    124             }                // end of for
    125             PrintList.add(tmp);
    126         }                    // end of while
    127         /*
    128         for(i=0;i<PrintList.size();i++){
    129             for(j=0;j<PrintList.get(i).length;j++) System.out.print(PrintList.get(i)[j]+" ");
    130             System.out.println();
    131         }*/
    132         //后处理
    133         String[] PrintListLine=new String[PrintList.size()-1];
    134         for(i=PrintListLine.length-1;i>=0;i--){//循环构造
    135             //首先进行构造
    136             String tmp=new String();
    137             for(j=0;j<PrintList.get(i).length;j++){
    138                 tmp+=PrintList.get(i)[j];
    139                 if(j!=PrintList.get(i).length-1) tmp+=" ";
    140             }
    141             PrintListLine[i]=tmp;
    142         }
    143         for(i=PrintListLine.length-2;i>=0;i--){//居中操作
    144             int spaceNum=(PrintListLine[i+1].length()-PrintListLine[i].length())/2;
    145             String space=new String();
    146             for(int t=0;t<spaceNum;t++) space+=" ";
    147             PrintListLine[i]=space+PrintListLine[i]+space;
    148         }    
    149         String outStr=new String();
    150         for(i=0;i<PrintListLine.length;i++){//最后构造一个字符串
    151             outStr+=PrintListLine[i]+"
    ";
    152         }
    153         return outStr;
    154     }
    155     void PreOrderTraversal(){
    156         PreOrder(root);
    157         System.out.println();
    158     }
    159     void PreOrder(BTNode obj){
    160         if(obj!=null){
    161             System.out.print(obj.data+",");
    162             PreOrder(obj.lChild);
    163             PreOrder(obj.rChild);
    164         }
    165     }
    166     void InOrderTraversal(){
    167         InOrder(root);
    168         System.out.println();
    169     }
    170     void InOrder(BTNode obj){    
    171         if(obj!=null){
    172             InOrder(obj.lChild);
    173             System.out.print(obj.data+",");
    174             InOrder(obj.rChild);
    175         }
    176     }
    177 }
    178 
    179 
    180 
    181 //线索二叉树
    182 class BThrTree extends BTtree{
    183     BThrTree(BTtree obj){//由父类构造而来
    184         //首先拷贝根节点
    185         BTNode tmp=new BTNode();
    186         tmp.data=obj.root.data;
    187         copy(root,obj.root);
    188     }
    189     void copy(BTNode node1,BTNode node2){
    190         if(node2.lChild!=null){//左树递归
    191             BTNode l=new BTNode();
    192             l.data=node2.lChild.data;//拷贝左树    
    193             node1.lChild=l;//左树赋值            
    194             copy(node1.lChild,node2.lChild);
    195         }
    196         if(node2.rChild!=null){//右树递归
    197             BTNode r=new BTNode();
    198             r.data=node2.rChild.data;//拷贝右树
    199             node1.rChild=r;//右树赋值
    200             copy(node1.rChild,node2.rChild);
    201         }    
    202     }
    203     public void InThreadingFabric(){//中序线索化构造
    204         BTNode now=root;
    205         InThreading(now); 
    206         pre.RTag=true;//【最后一个后继为null】
    207         pre.rChild=null;
    208     }
    209     private BTNode pre=null;//前驱指针
    210     private void InThreading(BTNode node){//中序线索化递归
    211         if(node!=null){//保证节点非空
    212             InThreading(node.lChild);//左子树线索化
    213             if(node.lChild==null){//如果左子树不存在
    214                 node.LTag=true;//线索化
    215                 node.lChild=pre;//前驱    【第一个前驱为null】
    216             }
    217             if(pre!=null && pre.rChild==null){//后继
    218                 pre.RTag=true;
    219                 pre.rChild=node;
    220             }
    221             pre=node;//保持pre指向node的前驱。
    222             InThreading(node.rChild);//左子树线索化
    223         }
    224     }
    225     void InOrderTraversal_Thr(){//线索化遍历
    226         BTNode now=root;
    227         //遍历前驱
    228         while(now.lChild!=null){//要么有左子树。
    229             now=now.lChild;
    230         }
    231         while(now!=null){//要么有左子树。
    232             System.out.print(now.data+",");
    233             if(now.RTag){now=now.rChild;}//如果是后继,就继续后继。
    234             else{
    235                 now=now.rChild;//如果不是,则令右子树的最左节点为后继
    236                 while(!now.LTag) now=now.lChild;
    237             }
    238         }
    239         System.out.println();
    240     }
    241 }
    242 
    243 
    244 class SearchBST extends BTtree{//二叉查找树
    245     SearchBST(int[] nums){//由二维数组构造
    246         root.data=String.valueOf(nums[0]);//构造根节点
    247         for(int i=1;i<nums.length;i++){//对其他元素进行构造
    248             BTNode node=new BTNode();
    249             node.data=String.valueOf(nums[i]);//构造叶子节点
    250             BTNode parent=root;
    251             int nodeV=nums[i];
    252             while(parent!=null){
    253                 int parentV=Integer.valueOf(parent.data).intValue();//当前根节点的值
    254                 if(nodeV<parentV){//左叶子
    255                     if(parent.lChild==null){//当前根节点的左叶子非空
    256                         parent.lChild=node;//挂入节点
    257                         break;                //如果这里没有加【break】,就会死循环。待解决☆☆☆
    258                     }
    259                     parent=parent.lChild;//如果这里空了,跳出循环
    260                 }else{
    261                     if(parent.rChild==null){
    262                         parent.rChild=node;//挂入节点
    263                         break;                //☆☆☆
    264                     }
    265                     parent=parent.rChild;//如果这里空了,跳出循环                    
    266                 }
    267             }
    268         }
    269     }
    270     SearchBST(){}
    271 }
  • 相关阅读:
    python如何打开一个大文件?
    python中的多进程与多线程(二)
    python中的多进程与多线程(一)
    python中的深拷贝与浅拷贝
    2018 pycharm最近激活码
    python中的新式类与旧式类
    用python优雅打开文件及上下文管理协议
    解决Mac上安装mysqlclient的错误
    用python实现一个简单的服务器
    高阶函数
  • 原文地址:https://www.cnblogs.com/TQCAI/p/7630041.html
Copyright © 2011-2022 走看看