1. 程式人生 > >二叉查詢樹(Binary Search Tree)

二叉查詢樹(Binary Search Tree)

private void mirror(Node rootNode) {
    if (rootNode != null) {
         // do the sub-trees
         mirror(rootNode.leftChild);
         mirror(rootNode.rightChild);
         // swap the left/right pointers
         Node temp = rootNode.leftChild;
         rootNode.leftChild = rootNode.rightChild;
         rootNode.rightChild = temp;
   }
}
10. check balanced (isBalanced) To check a binary tree is balanced or not, we can simply convert this question into comparing the maximum depth and minimum depth of the BT, if the diffrence between the maximum depth and minimum depth is larger than 1, the tree is not balanced, otherwise, it is balanced.
int maxDepth(Node rootNode) {
      if (rootNode == null) {
          return 0;
      }

      return 1 + max(maxDepth(rootNode.leftChild), maxDepth(rootNode.rightChild));
}

int minDepth(Node rootNode) {
      if (rootNode == null) {
          return 0;
      }

      return 1 + min(minDepth(rootNode.leftChild), minDepth(rootNode.rightChild));
}

bool isBalanced(Node rootNode) {
      return maxDepth(rootNode) -  minDepth(rootNode) <= 1;
}

11. First common ancestor 查詢兩個node的最早的公共祖先,分三種情況: 1. 如果兩個node在root的兩邊,那麼最早的公共祖先就是root。 2. 如果兩個node在root的左邊,那麼把root.leftChild作為root,再遞迴。 3. 如果兩個node在root的右邊,那麼把root.rightChild作為root,再遞迴。
     /*
     * get the first common ancestor of node p and node q
     */
    public static Node commonAncestor(Node rootNode, Node p, Node q) {
    	if (covers(rootNode.leftChild, p) && covers(rootNode.leftChild, q))
    		return commonAncestor(rootNode.leftChild, p, q);
    	if (covers(rootNode.rightChild, p) && covers(rootNode.rightChild, q))
    		return commonAncestor(rootNode.rightChild, p, q);
    	return rootNode;
    	
    }
    
    /*
     * check whether the node n is in the tree
     */
    private static boolean covers(Node rootNode, Node n) {
    	if(rootNode == null) return false;
    	if(rootNode == n) return true;
    	return covers(rootNode.leftChild, n) || covers(rootNode.rightChild, n);
    }
如果這個Binary Tree 是 BST的話,可以利用左子樹的值小於根節點的值,右子樹的值大於根節點的值進行判斷兩個節點(p, q)的位置,這樣更簡單。
public Node LCA(Node root, Node p, Node q) {
  if (root == null || p == null || q == null ) return NULL;	
  if (max(p.data, q.data) < root.data)
    return LCA(root.left, p, q);
  else if (min(p.data, q.data) > root.data)
    return LCA(root.right, p, q);
  else
    return root;
}


這個演算法的複雜度是O(h)。
12. ISBST() Given a plain binary tree, examine the tree to determine if it meets the requirement to be a binary search tree. To be a binary search tree, for every node, all of the nodes in its left tree must be <= the node, and all of the nodes in its right subtree must be > the node.
private boolean isBST(Node node) {
      if (node==null) return(true);
      if (node.left!=null && maxValue(node.left) > node.data)  return(false);
      if (node.right!=null && minValue(node.right) <= node.data)  return(false);
       // check that the subtrees themselves are ok
      return( isBST(node.left) && isBST(node.right) );
}
However, the approach given above is very expensive (O(n*h)), because the maxValue(Node node) function will be called n times, and the complexity of the maxValue(Node node) is h (the height of the tree).  Because of the properity of BST, we can simply pass down the minvalue and maxvalue after narrowing the range of the minvalue and maxvalue, and the complexity of this algorithm is O(n).  The code below shows the algorithm.
bool isBSTHelper(Node p, int low, int high) {
  if (p == null) return true;
  if (low < p.data && p.data < high)
    return isBSTHelper(p.leftChild, low, p.data) &&
           isBSTHelper(p.rightChild, p.data, high);
  else
    return false;
}
 
bool isBST(Node root) {
  return isBSTHelper(root, INT_MIN, INT_MAX);
}



參考:http://cslibrary.stanford.edu/110/BinaryTrees.html