2012/4/9----二叉查找树(二叉排序树)的各种操作

不知不觉都快5天没更新内容了,倒不是自己坚持不下来。一方面是因为二叉树这一块难度也比开始增大了,所以学习进度也就相对来说慢了一点。但更重要的是在学算法的同时也还有其他东西需要学习,在算法上面不能花太多时间。

今天写的是和二叉查找树相关的java代码,包括了二叉查找树的创建,中序遍历,查询(分为递归和非递归两种),查找最小节点,查找最大节点,插入节点,删除节点,查找节点的前驱,查找节点的后继,查找节点的父亲节点。差不多有10种操作吧。

在贴代码之前,先介绍一下什么是二叉查找树(来自百度百科):

二叉排序树(Binary Sort Tree)又称二叉查找树。 它或者是一棵空树;或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值; (2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值; (3)左、右子树也分别为二叉排序树;

至于具体的操作我就不说了,在我代码里面都有详细的注释说明,运行结果我也会贴出来。

ps:代码比较多,如果发现问题还望留言指正。

 

Java代码    收藏代码
  1. /* 
  2.  * 二叉查找树的java实现,包涵构造二叉查找树和对二叉查找树的一系列操作 
  3.  * @version 1.0 2012/4/9 
  4.  * @author akon 
  5.  */  
  6. package com.akon405.www;  
  7.   
  8. public class BSTree {  
  9.     BSTreeNode rootNode;//创建根节点  
  10.     //创建二叉查找树  
  11.     public void createBSTree(int[] A){  
  12.         rootNode=new BSTreeNode(A[0],null,null);//初始化根节点  
  13.           
  14.         for(int i=1;i<A.length;i++){//逐个取出数组A中的元素用来构造二叉查找树  
  15.             BSTreeNode tmpNode=rootNode;  
  16.             while(true){  
  17.                 if(tmpNode.data>=A[i]){//小于等于根节点  
  18.                     if(tmpNode.left==null){//如果左孩子为空,这把当前数组元素插入到左孩子节点的位置  
  19.                         tmpNode.left=new BSTreeNode(A[i],null,null);  
  20.                         break;  
  21.                     }  
  22.                     tmpNode=tmpNode.left;//如果不为空的话,则把左孩子节点用来和当前数组元素作比较  
  23.                 }else{//大于根节点  
  24.                     if(tmpNode.right==null){//如果右孩子为空,这把当前数组元素插入到左孩子节点的位置  
  25.                         tmpNode.right=new BSTreeNode(A[i],null,null);  
  26.                         break;  
  27.                     }  
  28.                     tmpNode=tmpNode.right;//如果不为空的话,则把右孩子节点用来和当前数组元素作比较  
  29.                 }  
  30.                 }  
  31.             }  
  32.           
  33.     }  
  34.     //中序遍历二叉查找树(中序遍历之后便可以排序成功)  
  35.     public void inOrderBSTree(BSTreeNode x){  
  36.         if(x!=null){  
  37.             inOrderBSTree(x.left);//先遍历左子树  
  38.             System.out.print(x.data+",");//打印中间节点  
  39.             inOrderBSTree(x.right);//最后遍历右子树  
  40.         }  
  41.     }  
  42.     //查询二叉排序树--递归算法  
  43.     public BSTreeNode searchBSTree1(BSTreeNode x,BSTreeNode k){  
  44.         if(x==null||k.data==x.data){  
  45.             return x;//返回查询到的节点  
  46.         }  
  47.         if(k.data<x.data){//如果k小于当前节点的数据域  
  48.             return searchBSTree1(x.left,k);//从左孩子节点继续遍历  
  49.         }else{//如果k大于当前节点的数据域  
  50.             return searchBSTree1(x.right,k);//从右孩子节点继续遍历  
  51.         }  
  52.     }  
  53.     //查询二叉排序树--非递归算法  
  54.     public BSTreeNode searchBSTree2(BSTreeNode x,BSTreeNode k){  
  55.         while(x!=null&&k.data!=x.data){  
  56.             if(x.data>k.data){  
  57.                 x=x.left;//从左孩子节点继续遍历  
  58.             }else{  
  59.                 x=x.right;//从右孩子节点继续遍历  
  60.             }  
  61.         }  
  62.         return x;  
  63.     }  
  64.     //查找二叉查找树的最小节点  
  65.     public BSTreeNode searchMinNode(BSTreeNode x){  
  66.         while(x.left!=null){  
  67.             x=x.left;  
  68.         }  
  69.         return x;  
  70.     }  
  71.     //查找二叉查找树的最大节点  
  72.     public BSTreeNode searchMaxNode(BSTreeNode x){  
  73.         while(x.right!=null){  
  74.             x=x.right;  
  75.         }  
  76.         return x;  
  77.     }  
  78.     //插入节点进入二叉查找树  
  79.     public void insert(BSTreeNode k){  
  80.         BSTreeNode r=rootNode;  
  81.         BSTreeNode p,q=null;  
  82.         p=r;  
  83.         while(p!=null){//while语句可以找到k节点所要插入的位置的父亲节点q  
  84.             q=p;  
  85.             if(p.data>k.data){  
  86.                 p=p.left;  
  87.             }else{  
  88.                 p=p.right;  
  89.             }  
  90.         }  
  91.         if(q==null){//二叉查找树为空树的情况下,直接插入到根节点,这里的q为已知的k的父亲节点  
  92.             r.data=k.data;  
  93.         }else if(q.data>k.data){//插入到父亲节点q的左边  
  94.             q.left=k;  
  95.         }else{//插入到父亲节点q的右边  
  96.             q.right=k;  
  97.         }  
  98.     }  
  99.     //删除二叉查找树中指定的节点  
  100.     public void delete(BSTreeNode k){//分三种情况删除  
  101.         if(k.left==null&&k.right==null){//第一种情况--没有子节点的情况下  
  102.             BSTreeNode p=parent(k);  
  103.             if(p.left==k){//其为父亲节点的左孩子  
  104.                 p.left=null;  
  105.             }else if(p.right==k){//其为父亲节点的右孩子  
  106.                 p.right=null;  
  107.             }  
  108.         }else if(k.left!=null&&k.right!=null){//第二种情况--有两个孩子节点的情况下  
  109.             BSTreeNode s=successor(k);//k的后继节点  
  110.             delete(s);  
  111.             k.data=s.data;  
  112.         }else{//第三种情况--只有一个孩子节点的情况下  
  113.             BSTreeNode p=parent(k);  
  114.             if(p.left==k){  
  115.                 if(k.left!=null){  
  116.                     p.left=k.left;  
  117.                 }else{  
  118.                     p.left=k.right;  
  119.                 }  
  120.             }else if(p.right==k){  
  121.                 if(k.left!=null){  
  122.                     p.right=k.left;  
  123.                 }else{  
  124.                     p.right=k.right;  
  125.                 }  
  126.             }  
  127.               
  128.         }  
  129.     }  
  130.     //查找节点的前驱节点  
  131.     public BSTreeNode predecessor(BSTreeNode k){  
  132.         if(k.left!=null){  
  133.             return searchMaxNode(k.left);//左子树的最大值  
  134.         }  
  135.         BSTreeNode y=parent(k);  
  136.         while(y!=null&&k==y.left){//向上找到最近的一个节点,其父亲节点的右子树包涵了当前节点或者其父亲节点为空  
  137.             k=y;  
  138.             y=parent(y);  
  139.         }  
  140.         return y;  
  141.     }  
  142.     //查找节点的后继节点  
  143.     public BSTreeNode successor(BSTreeNode k){  
  144.         if(k.right!=null){  
  145.             return searchMinNode(k.right);//右子树的最小值  
  146.         }  
  147.         BSTreeNode y=parent(k);  
  148.         while(y!=null&&k==y.right){//向上找到最近的一个节点,其父亲节点的左子树包涵了当前节点或者其父亲节点为空  
  149.             k=y;  
  150.             y=parent(y);  
  151.         }  
  152.         return y;  
  153.     }  
  154.     //求出父亲节点,在定义节点类BSTreeNode的时候,没有申明父亲节点,所以这里专门用parent用来输出父亲节点(主要是不想修改代码了,就在这里加一个parent函数吧)  
  155.     public BSTreeNode parent(BSTreeNode k){  
  156.         BSTreeNode p=rootNode;  
  157.         BSTreeNode tmp=null;  
  158.         while(p!=null&&p.data!=k.data){//最后的p为p。data等于k.data的节点,tmp为p的父亲节点  
  159.             if(p.data>k.data){  
  160.                 tmp=p;//临时存放父亲节点  
  161.                 p=p.left;  
  162.             }else{  
  163.                 tmp=p;//临时存放父亲节点  
  164.                 p=p.right;  
  165.             }  
  166.         }  
  167.         return tmp;  
  168.     }  
  169.     /** 
  170.      * @param args 
  171.      */  
  172.     public static void main(String[] args) {  
  173.         // TODO Auto-generated method stub  
  174.         int[] A={23,12,43,2,87,54};  
  175.         BSTreeNode searchNode1=null;//递归查找到的结果  
  176.         BSTreeNode searchNode2=null;//非递归查找到的结果  
  177.         BSTreeNode searchMinNode=null;//最小节点  
  178.         BSTreeNode searchMaxNode=null;//最大节点  
  179.         BSTreeNode k=null,l=null,p=null,q=null,m=null,n=null;//申明6个节点k,l,p,q,m,n  
  180.           
  181.         System.out.print("打印出数组A中的元素");  
  182.         for(int i=0;i<A.length;i++)  
  183.         System.out.print(A[i]+",");  
  184.           
  185.         BSTree bs=new BSTree();  
  186.           
  187.         bs.createBSTree(A);//创建二叉查找树  
  188.           
  189.         System.out.println();  
  190.         System.out.print("中序遍历构造的二叉查找树:");  
  191.         bs.inOrderBSTree(bs.rootNode);//中序遍历二叉查找树  
  192.           
  193.         k=new BSTreeNode(23,null,null);//初始化一节点k,其data为null,左右孩子为null  
  194.         l=new BSTreeNode(17,null,null);//初始化一节点l,其data为null,左右孩子为null  
  195.         q=new BSTreeNode(12,null,null);//初始化一节点q,其data为null,左右孩子为null  
  196.         m=bs.searchBSTree2(bs.rootNode, k);//从二叉查找树里面查找一个节点,其m.data为k.data(这个m节点在后面用来测试程序)  
  197.         searchNode1=bs.searchBSTree1(bs.rootNode,k);//查询二叉查找树----递归算法  
  198.         searchNode2=bs.searchBSTree2(bs.rootNode,k);//查询二叉查找树----递归算法  
  199.           
  200.         System.out.println("");  
  201.         System.out.println("递归算法--查找节点域:"+searchNode1.data+"左孩子:"+searchNode1.left.data+"右孩子:"+"查找节点域:"+searchNode1.right.data);//这里的左孩子或者右孩子节点可能打印为空,会出现null异常  
  202.         System.out.println("非递归算法--查找节点域:"+searchNode2.data+"左孩子:"+searchNode2.left.data+"右孩子:"+"查找节点域:"+searchNode2.right.data);//这里的左孩子或者右孩子节点可能打印为空,会出现null异常  
  203.           
  204.         searchMinNode=bs.searchMinNode(bs.rootNode);//找到最小节点  
  205.         searchMaxNode=bs.searchMaxNode(bs.rootNode);//找到最大节点  
  206.           
  207.         System.out.println("最小节点:"+searchMinNode.data);  
  208.         System.out.println("最大节点:"+searchMaxNode.data);  
  209.           
  210.         bs.insert(l);//把l节点插入到二叉查找树中  
  211.           
  212.         System.out.print("插入l节点(l的data为17)之后的二叉查找树的中序遍历结果:");  
  213.         bs.inOrderBSTree(bs.rootNode);//中序遍历二叉查找树  
  214.                   
  215.         p=bs.parent(q);//取q节点的父亲节点  
  216.           
  217.         System.out.println("");  
  218.         System.out.println("q的父亲节点(q的data为12):"+p.data+"左孩子:"+p.left.data+"右孩子:"+"查找节点域:"+p.right.data);//这里的左孩子或者右孩子节点可能打印为空,会出现null异常  
  219.           
  220.         bs.delete(l);  
  221.         System.out.print("删除l节点(l的data为17)之后的二叉查找树的中序遍历结果:");  
  222.         bs.inOrderBSTree(bs.rootNode);//中序遍历二叉查找树  
  223.           
  224.         n=bs.successor(m);  
  225.         System.out.println("");  
  226.         System.out.println("K的后继节点(k的data为23):"+n.data);  
  227.           
  228.         n=bs.predecessor(m);  
  229.         System.out.println("K的前驱节点(k的data为23):"+n.data);  
  230.     }  
  231.   
  232. }  
  233.   
  234. //二叉查找树的节点类  
  235. class BSTreeNode{  
  236.     int data;//数据域  
  237.     BSTreeNode right;//左孩子  
  238.     BSTreeNode left;//右孩子  
  239.     //构造二叉查找树的节点  
  240.     public  BSTreeNode(int data,BSTreeNode right,BSTreeNode left){  
  241.         this.data=data;  
  242.         this.right=right;  
  243.         this.left=left;  
  244.     }  
  245.   
  246. }  
 

运行结果如下:

 

Java代码    收藏代码
  1. 打印出数组A中的元素23,12,43,2,87,54,  
  2. 中序遍历构造的二叉查找树:2,12,23,43,54,87,  
  3. 递归算法--查找节点域:23左孩子:12右孩子:查找节点域:43  
  4. 非递归算法--查找节点域:23左孩子:12右孩子:查找节点域:43  
  5. 最小节点:2  
  6. 最大节点:87  
  7. 插入l节点(l的data为17)之后的二叉查找树的中序遍历结果:2,12,17,23,43,54,87,  
  8. q的父亲节点(q的data为12):23左孩子:12右孩子:查找节点域:43  
  9. 删除l节点(l的data为17)之后的二叉查找树的中序遍历结果:2,12,23,43,54,87,  
  10. K的后继节点(k的data为23):43  
  11. K的前驱节点(k的data为23):12  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值