2015-10-17 167 views
3

我有以下用於在二叉搜索樹中插入和刪除的java代碼。但這是我第一次嘗試使用java,並且想在某些事情上尋求幫助,然後才能Google瞭解這些概念。是需要初始化靜態變量的構造函數嗎?

public class BinarySearchTree { 
    public static Node root; 
    public BinarySearchTree(){ 
     this.root = null; 
    } 

    public boolean find(int id){ 
     Node current = root; 
     while(current!=null){ 
      if(current.data==id){ 
       return true; 
      }else if(current.data>id){ 
       current = current.left; 
      }else{ 
       current = current.right; 
      } 
     } 
     return false; 
    } 

    public boolean delete(int id){ 
     Node parent = root; 
     Node current = root; 
     boolean isLeftChild = false; 
     while(current.data!=id){ 
      parent = current; 
      if(current.data>id){ 
       isLeftChild = true; 
       current = current.left; 
      }else{ 
       isLeftChild = false; 
       current = current.right; 
      } 
      if(current ==null){ 
       return false; 
      } 
     } 
     //if i am here that means we have found the node 
     //Case 1: if node to be deleted has no children 
     if(current.left==null && current.right==null){ 
      if(current==root){ 
       root = null; 
      } 
      if(isLeftChild ==true){ 
       parent.left = null; 
      }else{ 
       parent.right = null; 
      } 
     } 
     //Case 2 : if node to be deleted has only one child 
     else if(current.right==null){ 
      if(current==root){ 
       root = current.left; 
      }else if(isLeftChild){ 
       parent.left = current.left; 
      }else{ 
       parent.right = current.left; 
      } 
     } 
     else if(current.left==null){ 
      if(current==root){ 
       root = current.right; 
      }else if(isLeftChild){ 
       parent.left = current.right; 
      }else{ 
       parent.right = current.right; 
      } 
     }else if(current.left!=null && current.right!=null){ 

      //now we have found the minimum element in the right sub tree 
      Node successor = getSuccessor(current); 
      if(current==root){ 
       root = successor; 
      }else if(isLeftChild){ 
       parent.left = successor; 
      }else{ 
       parent.right = successor; 
      }   
      successor.left = current.left; 
     }  
     return true;   
    } 

    public Node getSuccessor(Node deleleNode){ 
     Node successsor =null; 
     Node successsorParent =null; 
     Node current = deleleNode.right; 
     while(current!=null){ 
      successsorParent = successsor; 
      successsor = current; 
      current = current.left; 
     } 
     //check if successor has the right child, it cannot have left child for sure 
     // if it does have the right child, add it to the left of successorParent. 
//  successsorParent 
     if(successsor!=deleleNode.right){ 
      successsorParent.left = successsor.right; 
      successsor.right = deleleNode.right; 
     } 
     return successsor; 
    } 

    public void insert(int id){ 
     Node newNode = new Node(id); 
     if(root==null){ 
      root = newNode; 
      return; 
     } 
     Node current = root; 
     Node parent = null; 
     while(true){ 
      parent = current; 
      if(id<current.data){     
       current = current.left; 
       if(current==null){ 
        parent.left = newNode; 
        return; 
       } 
      }else{ 
       current = current.right; 
       if(current==null){ 
        parent.right = newNode; 
        return; 
       } 
      } 
     } 
    } 

    public void display(Node root){ 
     if(root!=null){ 
      display(root.left); 
      System.out.print(" " + root.data); 
      display(root.right); 
     } 
    } 

    public static void main(String arg[]){ 
     BinarySearchTree b = new BinarySearchTree(); 
     b.insert(3);b.insert(8); 
     b.insert(1);b.insert(4);b.insert(6);b.insert(2);b.insert(10);b.insert(9); 
     b.insert(20);b.insert(25);b.insert(15);b.insert(16); 
     System.out.println("Original Tree : "); 
     b.display(b.root);  
     System.out.println(""); 
     System.out.println("Check whether Node with value 4 exists : " + b.find(4)); 
     System.out.println("Delete Node with no children (2) : " + b.delete(2));   
     b.display(root); 
     System.out.println("\n Delete Node with one child (4) : " + b.delete(4));  
     b.display(root); 
     System.out.println("\n Delete Node with Two children (10) : " + b.delete(10));  
     b.display(root); 
    } 
} 

class Node{ 
    int data; 
    Node left; 
    Node right; 
    public Node(int data){ 
     this.data = data; 
     left = null; 
     right = null; 
    } 
} 

我有兩個問題如下

  1. 是否有意義有根,(這是一個靜態變量) 初始化爲空的構造函數中?這樣思考,因爲, 無論有多少對象被創建(因爲根 是靜態的),只有根,因此,爲什麼需要在構造函數 內聲明,每次創建新對象時都會調用它。
  2. 爲什麼構造函數是必需的?在創建的時候我們不能聲明/初始化 所有變量,像下面


public class BinarySearchTree { 
    public static Node root = null; 
    ... 
} 
+3

'root'根本不應該是靜態的。每個樹實例都有它自己的根。 – Eran

+0

我不確定但是...不。用'null'值初始化它。 –

回答

9

有一個static成員變量意味着它屬於類本身,而不是特定會員。換句話說,它是在所有實例之間共享的。現在我們明白了,很明顯爲什麼有一個static根成員是一個值得懷疑的設計 - 它不允許你有兩個斷開連接的樹,因爲它們都共享相同的根節點。

如果這確實是您的本意,root絕對應該初始化內聯(private static Node root = null;),而不是在構造函數中。在構造器中擁有這個邏輯意味着每次創建新樹全部現有的樹將失去其根。

3
  1. 使用靜態成員必須認真考慮的,因爲當你正確地指出,總有一款適合您創建的BinarySearchTree的所有實例相同的實例。因此,在您的代碼中,每次創建新實例時,root都會重置爲空。因此,不要這樣做。

  2. 您實際上可以初始化您定義它的root,就像您建議的那樣。

但是這將是一個更好的做法,通過移除static關鍵字,使rootBinarySearchTree的成員,或樹的數據結構和搜索算法分開。然後,您可以將root元素作爲參數傳遞給方法。

從數據的角度思考整個事情 - 您想要搜索的樹,由其根節點表示 - 以及對數據進行操作的服務。服務不應該緊密地綁定到數據上:您應該能夠使用相同的服務來處理不同的輸入數據集。

相關問題