2014-02-25 50 views
0

好的,教授希望我爲我的TreeSet類實現get方法。他給我的算法爲指針,實現get方法:指導實施TreeSet的get方法。 (作業)

GET(K)

從樹根開始,令M是節點的左子樹 的數量。

(1)如果M等於k-1,那麼根就是你要找的節點。 (2)如果M小於k,那麼你正在尋找的節點必須在 右子樹中。當我們移動到右側子樹時,我們必須從 減去M + 1。現在右子樹成爲新的根,並且你重複這個過程。

(3)如果M大於k,則必須檢查左邊 子樹中的節點。

我試着用遞歸和迭代的方式實現這個方法(我不知道如何拼寫它)。這裏是低於整個類代碼:

import java.util.ArrayList; 
import java.util.Collection; 
import java.util.Iterator; 
import java.util.LinkedList; 
import java.util.TreeSet; 
import sun.misc.Queue; 

/** 
* Binary Search Tree that inherits from the TreeSet class 
* The class is based on Weiss's non-generic implementation of BinarySearchTree 
* 
* @author Daniel 
* @param <T> 
*/ 
public class BinarySearchTree<T extends Comparable<T>> extends TreeSet<T> implements Iterable<T> 
{ 
    /** 
    * Construct the tree. 
    */ 
    public BinarySearchTree() 
    { 
     root = null; 
    } 

    @Override 
    public boolean add(T e) 
    { 
     insert(e); 
     return true; 
    } 



    /** 
    * Insert into the tree; duplicates are ignored. 
    * @param x the item to insert. 
    */ 
    public void insert(Comparable x) 
    {   
     { 

      root = insert(x, root); 

     } 

    } 

    /** 
    * Remove from the tree. Nothing is done if x is not found. 
    * @param x the item to remove. 
    */ 
    public void remove(Comparable<T> x) 
    { 

     root = remove(x, root); 


    } 

    /** 
    * Find the smallest item in the tree. 
    * @return smallest item or null if empty. 
    */ 
    public Comparable findMin() 
    { 
     return elementAt(findMin(root)); 
    } 

    /** 
    * Find the largest item in the tree. 
    * @return the largest item of null if empty. 
    */ 
    public Comparable findMax() 
    { 
     return elementAt(findMax(root)); 
    } 

    /** 
    * Find an item in the tree. 
    * @param x the item to search for. 
    * @return the matching item or null if not found. 
    */ 
    public Comparable find(Comparable x) 
    { 
     return elementAt(find(x, root)); 
    } 

    /** 
    * Make the tree logically empty. 
    */ 
    public void makeEmpty() 
    { 
     root = null; 
    } 

    /** 
    * Test if the tree is logically empty. 
    * @return true if empty, false otherwise. 
    */ 
    public boolean isEmpty() 
    { 
     return root == null; 
    } 

    /** 
    * Print the tree contents in sorted order. 
    */ 
    public void printTree() 
    { 
     if(isEmpty()) 
      System.out.println("Empty tree"); 
     else 
      printTree(root); 
    } 

    /** 
    * Internal method to get element field. 
    * @param t the node. 
    * @return the element field or null if t is null. 
    */ 
    private Comparable elementAt(BinaryNode t) 
    { 
     return t == null ? null : t.element; 
    } 

    /** 
    * Internal method to insert into a subtree. 
    * @param x the item to insert. 
    * @param t the node that roots the tree. 
    * @return the new root. 
    */ 
    private BinaryNode insert(Comparable<T> x, BinaryNode<T> t) 
    { 
/* 1*/  if(t == null) 
      { 
/* 2*/   t = new BinaryNode(x, null, null); 

       t.parent = null; 
       if (t.left != null) 
        t.left.parent = t; 
       if (t.right != null) 
        t.right.parent = t; 
      } 
/* 3*/  else if(x.compareTo((T)t.element) < 0) 
      { 
/* 4*/   t.left = insert(x, t.left); 
       t.left_count++; 
       t.left.parent = t; 

      } 
/* 5*/  else if(x.compareTo((T) t.element) > 0) 
      { 
/* 6*/   t.right = insert(x, t.right); 
       t.right.parent = t; 

      } 
/* 7*/  else 
/* 8*/   ; // Duplicate; do nothing 
/* 9*/  return t; 
    } 

    /** 
    * Internal method to remove from a subtree. 
    * @param x the item to remove. 
    * @param t the node that roots the tree. 
    * @return the new root. 
    */ 
    private BinaryNode remove(Comparable<T> x, BinaryNode<T> t) 
    { 
     if(t == null) 
      return t; // Item not found; do nothing 
     if(x.compareTo((T)t.element) < 0) 
     { 
      t.left = remove(x, t.left); 

     } 
     else if(x.compareTo((T)t.element) > 0) 
     { 
      t.right = remove(x, t.right); 


     } 
     else if(t.left != null && t.right != null) // Two children 
     { 
      t.element = findMin(t.right).element; 
      t.right = remove(t.element, t.right); 


     } 
     else 
      t = (t.left != null) ? t.left : t.right; 
     if (t != null) 
     { 
      if (t.left != null) 
       t.left.parent = t; 
      if (t.right != null) 
       t.right.parent = t; 
     } 
     return t; 
    } 

    /** 
    * Internal method to find the smallest item in a subtree. 
    * @param t the node that roots the tree. 
    * @return node containing the smallest item. 
    */ 
    private BinaryNode<T> findMin(BinaryNode<T> t) 
    { 
     if(t == null) 
      return null; 
     else if(t.left == null) 
      return t; 
     return findMin(t.left); 
    } 

    /** 
    * Internal method to find the largest item in a subtree. 
    * @param t the node that roots the tree. 
    * @return node containing the largest item. 
    */ 
    private BinaryNode<T> findMax(BinaryNode<T> t) 
    { 
     if(t != null) 
      while(t.right != null) 
       t = t.right; 

     return t; 
    } 

    /** 
    * Internal method to find an item in a subtree. 
    * @param x is item to search for. 
    * @param t the node that roots the tree. 
    * @return node containing the matched item. 
    */ 
    private BinaryNode find(Comparable<T> x, BinaryNode<T> t) 
    { 
     if(t == null) 
      return null; 
     if(x.compareTo((T)t.element) < 0) 
      return find(x, t.left); 
     else if(x.compareTo((T)t.element) > 0) 
      return find(x, t.right); 
     else 
      return t; // Match 
    } 

    /** 
    * Internal method to print a subtree in sorted order. 
    * @param t the node that roots the tree. 
    */ 
    private void printTree(BinaryNode<T> t) 
    { 
     if(t != null) 
     { 
      printTree(t.left); 
      System.out.println(t.element); 
      printTree(t.right); 
     } 
    } 


    @Deprecated 
//Updates nodes current parent 
// Unfortunaetly to expensive as it is O(N) algorithm. 
// Therefore it sadly didn't make the final cut and is a deprecated method can be removed in the near future. 
private void update(BinaryNode<T> t) 
{ 
    if (t != null) 
    { 
     if (t.left != null) 
      t.left.parent = t; 
     if (t.right != null) 
      t.right.parent = t; 
     update(t.left); 
     update(t.right); 
    } 
} 


/** 
* Returns an iterator pointing just before the 
* item in the tree with the lowest value. 
* 
**/ 

public Iterator<T> iterator() 
{ 
    return new MyIterator(); 
} 


/** 
* Returns the element at a given index position. 
* Throws an IndexOutOfBoundsException if the item is not found. 
* Runs in average O(log N) time. 
*/ 
public T get(int index) 
{ 
     return get(root, index); 
} 

private T get(BinaryNode<T> root, int index) 
{ 
    if (root == null) return null; 
    if (root.left_count == index-1) return (T)root.element; 
    if (root.left_count < index) return get(root.right, index - (root.left_count + 1)); 
    else 
    { 
     return get(root.left, index); 
    } 
} 


/** 
* Returns all elements falling within a range of indexes. 
* The range is inclusive 
*/ 

public Collection<T> getRange(int first, int last) 
{ 
    ArrayList<T> list = new ArrayList<>(); 
    for(int i = first; i <= last; i++) 
    { 
     list.add(get(i)); 
    } 
    return list; 
} 

/** 
* Prints the tree in level-order, which means the root is printed, 
* then all nodes at level 2, then nodes at level 3, and so on. 
*/ 
public void printLevelOrder() throws InterruptedException 
{ 
    Queue Q = new Queue(); 
    Q.enqueue(root); 
    while(!Q.isEmpty()) 
    { 
     BinaryNode<T> node = (BinaryNode<T>)Q.dequeue(); 
     System.out.print(node.element + ","); 
     if (node.left != null) 
      Q.enqueue(node.left); 
     if (node.right != null) 
      Q.enqueue(node.right); 
    } 
    System.out.println(); 
} 






private class MyIterator implements Iterator<T> 
{ 

     private BinaryNode<T> nextNode = null; 
     private boolean firstCall; 
     public MyIterator() 
     { 
      nextNode = BinarySearchTree.this.findMin(root); 
      firstCall = true; 
     } 
     @Override 
     public boolean hasNext() 
     { 
      return !nextNode.equals(BinarySearchTree.this.findMax(root)); 
     } 

     @Override 
     public T next() 
     { 
      if (firstCall) 
      { 
       firstCall = false; 
       return (T)nextNode.element; 
      } 
      if (!hasNext()) 
        throw new IndexOutOfBoundsException("Cannot manke another next() call!!!!?!"); 
      BinaryNode<T> node = successor(nextNode); 
      nextNode = node; 
      return (T)node.element; 
     } 

     @Override 
     public void remove() 
     { 
      BinarySearchTree.this.remove(nextNode.element); 
     } 

     /** 
     * Returns the next value in the sequence, starting at the 
     * node pointed to by the input parameter. This method 
     * is used by the iterator. 
     */ 
     private BinaryNode<T> successor(BinaryNode<T> p) 
     { 
       BinaryNode<T> n = p.right; 
       if (n != null) 
       { 
        return BinarySearchTree.this.findMin(n); 
       } 
       else 
       { 
       n = p.parent; 
       while(n != null && p == n.right) 
       { 
        p = n; 
        n = n.parent; 
       } 
       return n; 
       } 
     } 


} 



     /** The tree root. */ 
    private BinaryNode<T> root; 



    public static void main(String[] arguments) throws InterruptedException 
    { 

     BinarySearchTree<String> t = new BinarySearchTree<>(); 
     String[] array = { "Harry","Maria","Bob","Dan","Sue","Ann","Jose" }; 

     for(int i = 0; i < array.length; i++) 
       t.insert(array[i]); 
     print(t); 

     System.out.print("Level order: "); 
     t.printLevelOrder(); 
     System.out.println("\n"); 

     System.out.printf("The value at index %d is %s\n", 0, t.get(0)); 
     System.out.printf("The value at index %d is %s\n", 2, t.get(2)); 
     System.out.printf("The value at index %d is %s\n", 6, t.get(6)); 

     System.out.print("\nRemoving "); 
     for(int i = 1; i < array.length; i+= 2) { 
       System.out.print(array[i] + ", "); 
       t.remove(array[i]); 
     } 
     System.out.println(); 

     System.out.println("\nTree contents after removing elements:"); 
     print(t); 

     // verify that the get method still works 
     System.out.printf("The value at index %d is %s\n", 0, t.get(0)); 
     System.out.printf("The value at index %d is %s\n", 2, t.get(2)); 
     System.out.printf("The value at index %d is %s\n", 3, t.get(3)); 


    } 

    public static void print(BinarySearchTree<? extends Comparable<?>> t) 
    { 

     for(Object x : t) 
     System.out.print(x + ", "); 
     System.out.println("\n"); 
    } 

private static void test1() throws InterruptedException 
{ 
     BinarySearchTree<Integer> t = new BinarySearchTree<>(); 
     int[] array = { 20, 10, 11, 30, 2, 29, 33, 28, 17, 4 }; 
     for(int i = 0; i < array.length; i++) 
      t.add(array[i]); 

     print(t); // demonstrate the iterator 

     System.out.println("Level order"); 
     t.printLevelOrder(); 

     System.out.printf("The value at index %d is %d\n", 0, t.get(0)); 
     System.out.printf("The value at index %d is %d\n", 1, t.get(1)); 
     System.out.printf("The value at index %d is %d\n", 2, t.get(2)); 
     System.out.printf("The value at index %d is %d\n", 3, t.get(3)); 
     System.out.printf("The value at index %d is %d\n", 8, t.get(8)); 
     System.out.printf("The value at index %d is %d\n", 9, t.get(9)); 

     System.out.print("\nRemoving "); 
     for(int i = 1; i < array.length; i+= 2) { 
     System.out.print(array[i] + ", "); 
     t.remove(array[i]); 
     } 
     System.out.println(); 

     System.out.println("\nTree contents after removing elements:"); 
     print(t); 

     // verify that the get method still works 
     System.out.printf("The value at index %d is %d\n", 0, t.get(0)); 
     System.out.printf("The value at index %d is %d\n", 1, t.get(1)); 
     System.out.printf("The value at index %d is %d\n", 2, t.get(2)); 
     System.out.printf("The value at index %d is %d\n", 3, t.get(3)); 
     } 




} 

這裏是get方法的代碼:

/** 
* Returns the element at a given index position. 
* Throws an IndexOutOfBoundsException if the item is not found. 
* Runs in average O(log N) time. 
*/ 
public T get(int index) 
{ 
     return get(root, index); 
} 

private T get(BinaryNode<T> root, int index) 
{ 
    if (root == null) return null; 
    if (root.left_count == index-1) return (T)root.element; 
    if (root.left_count < index) return get(root.right, index - (root.left_count + 1)); 
    else 
    { 
     return get(root.left, index); 
    } 
} 

這裏是不正確的輸出:

安,鮑勃,丹皮,哈里,Jose,Maria,Sue,

級別:Harry,Bob,Maria,Ann,Dan,Jose,Sue,

值在索引0處爲空 在索引2的值是Bob 在索引6的值是瑪利亞

卸下超羣,丹,安,

移除元素之後

樹內容:鮑勃,哈利,聖何塞,蘇,

索引爲0的值是零,在指數2的值是鮑勃 指數3爲空

正如你可以看到指數值有一堆空的,並在有效的元素。其他一切正確輸出。所以得到是100%失敗,因爲我已經寫了最初使用一種天真的方法。但教授希望它是O(log(N))。

由於這是一項家庭作業,對於我的數據結構課程,請避免給出完整的工作代碼。我想要的只是一些指導,我知道這是錯誤的(從輸出中判斷),但我不明白爲什麼。我也還沒有完全理解算法,這使得我更難調試代碼。我假設node.left_count是正確的(但可能是錯誤的),所以我相信這個錯誤在get方法中。因爲我可能會誤解某些算法。

更新

如果我改變這一點,如果(root.left_count ==索引-1)返回(T)根。元件;到這個 if(root.left_count == index)return(T)root.element;

我得到這樣的輸出:

Ann, Bob, Dan, Harry, Jose, Maria, Sue, 

Level order: Harry,Bob,Maria,Ann,Dan,Jose,Sue, 


The value at index 0 is Ann 
The value at index 2 is Dan 
The value at index 6 is Sue 

Removing Maria, Dan, Ann, 

Tree contents after removing elements: 
Bob, Harry, Jose, Sue, 

The value at index 0 is null 
The value at index 2 is null 
The value at index 3 is Harry 
+1

你貼絕望太多的代碼。請將其縮小爲[最小,完整,測試和可讀示例](http://stackoverflow.com/help/mcve)。 – Dukeling

+0

@Dukeling它已經過測試,它如何可能無法讀取?有很多有用的評論。相信我,我不是新來的,因爲你可以從我的個人資料中看到,所以不要以爲我是新人。我甚至給出了最有可能解決問題的方法。包括輸出並指出我最可能的問題是什麼。那麼爲什麼你打算關閉它?問題不是模糊的,我的解釋也不是。如果你想要我添加一些東西,請更具體。但只是說你張貼到很多代碼是你的一部分含糊不清。 –

+1

你怎麼說你發佈了太多的代碼含糊不清?你有500多行代碼。在我的書中,這太無望了(好吧,高於50-200的任何東西,除外)。我並不認爲你是新人,但事實是你不關心我。我真的不打算通過你的所有代碼,並指出哪些事情與你的問題無關,你可以用什麼代替它們,因爲,那樣就會打破這個觀點,即 - 我不想在一個問題中處理(或查看)500多行代碼,並且我認爲使用這麼多代碼的問題對於該網站來說不是好事。 – Dukeling

回答

0
if (root.left_count == index-1) return (T)root.element; 

應該

if (root.left_count == index) return (T)root.element; 

正如你會馬上看到。 0留下的物品,指數0,3個左項目,指標3 這是假設開始的索引約定從0

提示:永遠不要相信規範。

+0

我同意提示,我很懷疑,但仍然是。但我堅持教授送給同學的東西。順便說一下,我得到錯誤的輸出。是的,我確實嘗試過。我會發布更新。 –