2015-04-23 103 views
1

我想知道這是否正確有效地檢查BST。確定BST的高效算法

我的代碼是確定,如果樹是二叉搜索樹。請隨時糾正,但它必須是下面的方法,並被要求檢查樹中的每個節點一次。

需要使用這種方法叫:public static boolean isBST(BinaryTree<String> tree)

下面是我的算法和代碼:

public static boolean isBST(BinaryTree<String> tree) 
{ 
    return isBST(tree.root); 
} 

private static boolean isBST(BinaryNode<String> root) { 

    if(root==null) 
     return true; 
    else{ 
     if(root.getLeftChild().getData().compareTo(root.getData())<0&&root.getRightChild().getData().compareTo(root.getData())>0) 
      return true; 
     else 
      return false; 
    } 
} 

我拿着仿製藥,也是一個靜態方法工作的這種做法的原因。

+2

您需要檢查leftChild和rightChild是否都是BST。這在代碼中仍然缺失。換句話說,你需要一個遞歸 – gefei

+1

不。這種方法是錯誤的。我建議你閱讀這篇文章 - http://www.geeksforgeeks.org/a-program-to-check-if-a-binary-tree-is-bst-or-not/ – Bhoot

+0

你的算法是錯誤的,看看'{left:{value:5,left:null,right:null},right:{value 7,left:{value:10,left:null,right:null},right:null}' –

回答

2

你剛剛發佈的代碼檢查根節點的直接子節點是否遵循BST屬性。但是,您需要爲整個左右子樹執行此操作。一種實現方法如下:

public static boolean isBST(BinaryTree<String> tree) { 
    return isBSTChecker(tree.root, MIN, MAX); 
} 

public static boolean isBSTChecker(BinaryNode<String> node, T min, T max) { 
    if(node == null) return true; 
    else if(node.getData().compareTo(min) < 0 || node.getData().compareTo(min) > 0) return false; 
    else return isBSTChecker(node.getLeftChild(), min, node.getData()) && isBSTChecker(node.getRightChild(), node.getData(), max); 
} 

在這種方法中,您需要爲泛型定義MIN和MAX值。一種做同樣的方法是遍歷整個樹並找到最小值和最大值。這種方法的時間複雜度是O(n),它使用不變的額外空間。

中,你可以實現你的檢查的另一種方法如下:

ArrayList<BinaryNode> list = new ArrayList<>(); 

public static boolean isBST(BinaryTree<String> tree) { 
    inOrder(tree.root); 
    return isBSTChecker(list); 
} 

public static boolean isBSTChecker(ArrayList<BinaryNode> inorder) { 
    boolean isBST = true; 
    BinaryNode prev = inorder.get(0); 
    for(int i=1; i<inorder.size(); i++) { 
     BinaryNode curr = inorder.get(i); 
     if(curr.getData().compareTo(prev.getData()) < 0) { 
      isBST = false; 
      break; 
     } 
     prev = curr; 
    } 
    return isBST; 
} 

public static void inOrder(BinaryNode<String> node) { 
    if(node == null) return; 
    inOrder(node.getLeftChild()); 
    list.add(node); 
    inOrder(node.getRightChild()); 
} 

在這種方法中,我們首先做一個序遍歷過樹,然後檢查是否該遍歷的結果按升序進行排序訂購。這種方法的時間和空間複雜度都是O(n)。通過在遍歷中跟蹤先前訪問的節點並檢查當前節點的數據是否大於先前設置的節點,可以消除線性空間複雜性。

來源:http://www.geeksforgeeks.org/a-program-to-check-if-a-binary-tree-is-bst-or-not/

+0

非常感謝。這有幫助。另外我想知道我們如何定義泛型的最小值和最大值。我們是否只是創建另一種方法來確定最小值和最大值。既然我們知道min將在左邊的子樹上並且max在右邊的子樹上。我還必須使數組列表靜態 –

+0

@JenniferFitzgerald遺憾的是,MIN和MAX值沒有標準的通用定義。您必須從您的數據(這是線性時間操作)計算它們,或者您可以確定泛型將被轉換到的數據類型,並使用這些數據類型的最小值和最大值。 – Bhoot

+0

除非樹是線程化的,否則序列遍歷不需要恆定的額外空間。如果樹是平衡的,則遍歷需要O(log n)個額外的空間用於堆棧幀。如果樹不平衡,則可能需要O(n)額外的空間。 –