1. 程式人生 > >java實現二叉搜尋樹(BST)包含增刪和遍歷操作

java實現二叉搜尋樹(BST)包含增刪和遍歷操作

二叉搜尋樹基本知識可以看演算法導論第三版163頁,也可以百度搜索下,程式碼如下:

package com.ma.al.binaryTree;

/**
 * @author xiaoma
 *
 */
public class MyBinarySearchTree {
	public Node root; //記錄根節點
	public Node current;
	
	//===================================================================================
	//為了方便就不用get/set方法了
     class Node{  
        public Node left;  //左孩子
        public Node right; //右孩子 
        public int data;   //資料
        public Node(int data){  
            this.left = null;  
            this.right = null;  
            this.data = data;  
        }  
    }
     
     
     //=====================================================================================
     //增加節點
     public void addNode(int data){
    	 if(root == null){		//為空樹
    		 root =new Node(data);
    	 }
    	 else{
    		 current = root;
	    	 while(current != null){   //尋找葉子節點
	    		 if(data <= current.data){
	    			 if(current.left == null){
	    				 current.left = new Node(data);
	    				 break;
	    			 }
	    			 current = current.left;
	    			 
	    		 }
	    		 else{
	    			 if(current.right == null){
	    				 current.right = new Node(data);	    				 
	    				 break;
	    			 }
	    			 current = current.right;
	    		 }
    		 }
    	 }
     }
     //==========================================================================
     //刪除一個節點
     public void delete(int data){
    	 Node temp = root;
    	 Node parent = root;
    	 while(temp != null){	//尋找與data相等的項
    		 if(data < temp.data){
    			 if(temp.left == null){
    				 temp = null;
    				 System.out.println("不存在的");
    				 break;
    			 }
    			 parent = temp;
    			 temp = temp.left;
    			 
    		 }
    		 else if(data > temp.data){
    			 if(temp.right == null){
    				 temp = null;
    				 System.out.println("不存在的");	    				 
    				 break;
    			 }
    			 parent = temp;
    			 temp = temp.right;
    		 }
    		 else{
    			 break;
    		 }
		 }//此時temp記錄與data相等的項,parent記錄temp的父節點
    	 if(temp == null) return;//未能找到與data相等的項
    	 if(temp == parent){//此時要刪除root節點
    		 Node temp2 = temp.right;
			 Node parent2 = temp.right;
			 while(temp2.left != null){
				 parent2 = temp2;
				 temp2 = temp2.left;
			 }//此時temp2記錄與root的新項
			 if(temp2 != parent2){//root的右孩子有左孩子時
				 parent2.left = temp2.right;
				 temp2.left  = root.left;
				 temp2.right = root.right;
				 root = temp2;
				 
			 }
			 else{//root的右孩子無左孩子時
				 temp2.left  = root.left;
				 temp2.right = parent2.right;
				 root = temp2;
				 
			 }
    	 }
    	 else if(temp == parent.left){//要刪除的項是左節點,temp記錄要刪除的項
    		 if(temp.right == null && temp.left == null) parent.left = null;
    		 else if(temp.right == null) parent.left = temp.left;
    		 else if(temp.left == null)  parent.left = temp.right;
    		 else{
    			 Node temp2 = temp.right;
    			 Node parent2 = temp.right;
    			 while(temp2.left != null){
    				 parent2 = temp2;
    				 temp2 = temp2.left;
    			 }
    			 if(temp2 != parent2){
    				 parent2.left = temp2.right;
	    			 parent.left = temp2;
	    			 temp2.right = temp.right;
	    			 temp2.left = temp.left;
    			 }
    			 else{
    				 parent.left = temp2;
    				 temp2.left = temp.left;
    				 temp2.right = parent2.right;
    			 }
    		 }
    	 }
    	 else{//要刪除的項是右節點,temp記錄要刪除的項
    		 if(temp.right == null && temp.left == null) parent.right = null;
    		 else if(temp.right == null) parent.right = temp.left;
    		 else if(temp.left == null)  parent.right = temp.right;
    		 else{
    			 Node temp2 = temp.right;
    			 Node parent2 = temp.right;
    			 while(temp2.left != null){
    				 parent2 = temp2;
    				 temp2 = temp2.left;
    			 }
    			 if(temp2 != parent2){
    				 parent2.left = temp2.right;
	    			 parent.right = temp2;
	    			 temp2.right = temp.right;
	    			 temp2.left = temp.left;
    			 }
    			 else{
    				 parent.right = temp2;
    				 temp2.left = temp.left;
    				 temp2.right = parent2.right;
    			 }
    		 }
    		 
    		 
    	 }
    	 
     }
     
     //==========================================================================
     //中序遍歷數
     public void inOrderPrintTree(Node node){
    	 if(node != null){
	    	 inOrderPrintTree(node.left);
	    	 System.out.print(node.data+",");
	    	 inOrderPrintTree(node.right);
    	 }
     }
     //===========================================================================
     public static void main(String[] args) {
    	 MyBinarySearchTree my =new MyBinarySearchTree();
    	 //下列插入順序可以打亂 
    	   my.addNode(9);
    	   my.addNode(5);
    	   my.addNode(15);
    	   my.addNode(3);
    	   my.addNode(7);
    	   my.addNode(11);
    	   my.addNode(17);
    	   my.addNode(6);
    	   my.addNode(4);
    	   my.addNode(1);
    	   my.addNode(10);
    	   my.addNode(8);
    	   my.addNode(12);
    	   my.addNode(16);
    	   my.addNode(18);
    	   my.inOrderPrintTree(my.root);//中序遍歷樹
    	   System.out.println();
    	   
    	   my.delete(9);//刪除資料為9的節點
    	   my.inOrderPrintTree(my.root);
    	   //System.out.println(my.root.data);
    	
	}

     
}


main函式構造的樹如下: