查询二叉树的实现

来源:互联网 发布:剑三大叔捏脸数据 编辑:程序博客网 时间:2024/05/17 22:30
[java] view plaincopy
  1. 首先是Node 类的定义  
[java] view plaincopy
  1. package SearchTree;  
  2.   
  3. public class Node {  
  4.   
  5.     private Node left;  
  6.     private Node right;  
  7.     private Node Parrent;  
  8.       
  9.     int data;  
  10.   
  11.     public Node(Node left, Node right, Node parrent, int data) {  
  12.         super();  
  13.         this.left = left;  
  14.         this.right = right;  
  15.         Parrent = parrent;  
  16.         this.data = data;  
  17.     }  
  18.   
  19.       
  20.     public void setLeft(Node left) {  
  21.         this.left = left;  
  22.     }  
  23.   
  24.   
  25.     public void setRight(Node right) {  
  26.         this.right = right;  
  27.     }  
  28.   
  29.   
  30.     public void setParrent(Node parrent) {  
  31.         Parrent = parrent;  
  32.     }  
  33.   
  34.   
  35.     public void setData(int data) {  
  36.         this.data = data;  
  37.     }  
  38.   
  39.   
  40.     public Node getLeft() {  
  41.         return left;  
  42.     }  
  43.   
  44.     public Node getRight() {  
  45.         return right;  
  46.     }  
  47.   
  48.     public Node getParrent() {  
  49.         return Parrent;  
  50.     }  
  51.   
  52.     public int getData() {  
  53.         return data;  
  54.     }  
  55.       
  56. }  

接着是,Tree 类的定义(各种常用的操作)

[java] view plaincopy
  1. package SearchTree;  
  2.   
  3. public class Tree {  
  4.   
  5.     private Node boot=null;  // 二叉查找树的根节点  
  6.   
  7.     public Node getBoot() {  
  8.         return boot;  
  9.     }  
  10.   
  11.     public void setBoot(Node boot) {  
  12.         this.boot = boot;  
  13.     }  
  14.       
  15.     public void Tree_Insert(Node i_node)    // 在树中插入一个节点 i_node  
  16.     {  
  17.         Node y = null;  
  18.         Node x = boot;  
  19.           
  20.         while(x!=null)  
  21.         {  
  22.             y = x;  
  23.             if(i_node.getData() < x.getData())  
  24.                 x = x.getLeft();  
  25.             else x = x.getRight();  
  26.         }  
  27.           
  28.         i_node.setParrent(y);  // 设置插入节点的 父节点  
  29.           
  30.         if(y == null// This Tree is empty;  
  31.         {  
  32.             boot = i_node;  
  33.         }  
  34.         else if(y.getData() > i_node.getData())  
  35.             y.setLeft(i_node);  
  36.         else y.setRight(i_node);  
  37.     }  
  38.     public void InOrder_Tree_Walk()   // 中序遍历输出树  
  39.     {  
  40.         Traversal(boot);  
  41.     }  
  42.     private void Traversal(Node x)  
  43.     {  
  44.         if(x!=null)  
  45.         {  
  46.             Traversal(x.getLeft());  
  47.             System.out.println(x.getData());  
  48.             Traversal(x.getRight());  
  49.         }  
  50.     }  
  51.       
  52.     public Node Tree_Search(int data)  
  53.     {  
  54. //      Node find =RecursionSearch(boot, data);        // 递归的查找  
  55.         Node find = Non_RecursionSearch(boot, data);   // 非递归的查找  
  56.         if(find == null)  
  57.             System.out.println("Warning:The element that you are searching is not in the tree!");  
  58.         else System.out.println("find the element in the tree!");  
  59.         return find;  
  60.     }  
  61.       
  62.     private Node RecursionSearch(Node b,int data)  
  63.     {  
  64.         if(b==null || b.getData()==data)  // | 和 || 两者之间什么关系 ?  
  65.             return b;  
  66.           
  67.         if(b.getData() < data)  
  68.             return RecursionSearch(b.getRight(), data);  
  69.         else return RecursionSearch(b.getLeft(), data);  
  70.     }  
  71.       
  72.     private Node Non_RecursionSearch(Node b,int data) // 非递归的查找的实现  
  73.     {  
  74.         while(b!=null && b.getData()!=data)  
  75.         {  
  76.             if(b.getData() > data)  
  77.                 b = b.getLeft();  
  78.             else b = b.getRight();  
  79.         }  
  80.         return b;  
  81.     }  
  82.     /*** 
  83.      * 返回树中最小的元素 ,如果树为空的话,返回空的引用 
  84.      * @return 
  85.      */  
  86.     public Node Tree_Minmum()   
  87.     {  
  88.         if(boot==null)  
  89.             return null;  
  90.         Node find = minmum(boot);  
  91.         return find;  
  92.     }  
  93.     private Node minmum(Node x)  
  94.     {  
  95.         while(x.getLeft()!=null)  
  96.             x= x.getLeft();  
  97.         return x;  
  98.     }  
  99.     /** 
  100.      * 返回树中最大的元素,如果树为空的话,返回空的引用 
  101.      * @return 
  102.      */  
  103.     public  Node Tree_Maximum()  
  104.     {  
  105.         if(boot == null)  
  106.             return boot;  
  107.         Node find = Maximum(boot);  
  108.         return find;  
  109.     }  
  110.     private Node Maximum(Node x)  
  111.     {  
  112.         while(x.getRight()!=null)  
  113.             x = x.getRight();  
  114.         return x;  
  115.     }  
  116.     /** 
  117.      * 查找一个给定元素data的后继(如果该元素存在的话) 
  118.      * 存在两种情景:1:存在右孩子,则求右孩子的minmum即可 
  119.      *           2: 不存在右孩子,那么向上循环查找一个父节点,它的左孩子等于循环中的x,此时该点为其后继  
  120.      * @param data 
  121.      * @return 
  122.      * while 循环是本函数的核心代码(难点) 
  123.      */  
  124.     public Node Tree_Successor(int data)  
  125.     {  
  126.         Node x= Tree_Search(data); // 获得元素data 的节点引用。  
  127.         if(x==nullreturn null;  
  128.           
  129.         if(x.getRight()!=null)  
  130.             return minmum(x.getRight());  
  131.           
  132.         Node y = x.getParrent();  
  133.           
  134.         while(y!=null && x==y.getRight())  
  135.         {  
  136.             x=y;  
  137.             y= y.getParrent();  
  138.         }  
  139.           
  140.         return y;  
  141.     }  
  142.     /** 
  143.      * Funtion:查找一个给定元素的中序遍历的前驱节点,有两种情况: 
  144.      * 1:该节点存在左孩子,那么求左孩子的Maximum 
  145.      * 2:该节点没有左孩子,那么向上递归求(通过循环)一个存在右孩子的节点,即为所求节点的前驱节点 
  146.      * @param data 
  147.      * @return 
  148.      */  
  149.     public Node Tree_Predecessor(int data)  
  150.     {  
  151.         Node x = Tree_Search(data); // 获得元素data 的引用  
  152.         if(x==nullreturn null;  
  153.           
  154.         if(x.getLeft()!=null// 第一种情况,存在左孩子  
  155.             return Maximum(x.getLeft());  
  156.           
  157.         Node y = x.getParrent();  
  158.         while(y!=null && y.getLeft()==x)  
  159.         {  
  160.             x=y;  
  161.             y= y.getParrent();  
  162.         }  
  163.         return y;  
  164.     }  
  165.     /** 
  166.      * funtion:删除树中的元素data(如果存在的话),删除时存在三种情况: 
  167.      * 1:该节点没有孩子节点,则,直接删除 
  168.      * 2:该节点有一个孩子节点,那么删除节点之后,将该节点的父节点执行该节点的子节点 
  169.      * 3:存在两个子节点,那么将该节点的后继,覆盖带该节点即可,后继节点一定不会有两个子节点 
  170.      * @param data 
  171.      */  
  172.     public void Tree_Delete(int data)  
  173.     {  
  174.         Node z = Tree_Search(data);  
  175.         Node x,y;  
  176.         if(z==null)return;     // 不存在元素data  
  177.           
  178.         if((z.getLeft()==null)||(z.getRight()==null)) //如果是前两种情况  
  179.         {  
  180.             y = z;  
  181.         }  
  182.         else y = Tree_Successor(data);// 第三种情况  
  183.           
  184.         if(y.getLeft()!=null// 获得要删除节点的子节点  
  185.             x = y.getLeft();  
  186.         else x = y.getRight();  
  187.           
  188.         if(x!=null)  
  189.             x.setParrent(y.getParrent());  
  190.         if(y.getParrent()==null)  
  191.             boot = x;  
  192.         else if(y==y.getParrent().getLeft())  
  193.             y.getParrent().setLeft(x);  
  194.         else y.getParrent().setRight(x);  
  195.           
  196.         if(y!=z)  //删除节点不是指定节点,那么是第三种情况  
  197.         {  
  198.             z.setData(y.getData()); //修改删除节点的data 域为它的后继节点的data域 ,相对于写该引用简单很多  
  199.         }  
  200.           
  201.     }  
  202. }  

MainClass ,调试的主类:

[java] view plaincopy
  1. package SearchTree;  
  2.   
  3. public class MainClass {  
  4.   
  5.     /** 
  6.      * @param args 
  7.      */  
  8.     public static void main(String[] args) {  
  9.         // TODO Auto-generated method stub  
  10.   
  11.         Tree T =new Tree();  
  12.           
  13.         int[] a = {4 ,3 ,5,2,6,7,1};  
  14.           
  15.         for(int i=0;i < a.length; i++)  
  16.         {  
  17.             T.Tree_Insert(new Node(nullnullnull, a[i]));  
  18.         }  
  19.           
  20.         T.InOrder_Tree_Walk();  
  21.         System.out.println("The minmum element is :" +T.Tree_Minmum().getData());  
  22.         System.out.println("The Maximum element is :" + T.Tree_Maximum().getData());  
  23.         System.out.println("The element 6's successor is:" + T.Tree_Successor(6).getData());  
  24.         System.out.println("The element 6's predecessor is:" + T.Tree_Predecessor(6).getData());  
  25.         T.Tree_Delete(5);  
  26.         T.InOrder_Tree_Walk();  
  27.     }  
  28. }  

0 0