2011-08-21 66 views
0

我正在尝试实现AVL树中的几个编译错误。 有些东西是抛出整个枚举。它编译得很好,直到我试图实现一个辅助类。我认为这与BTNode本身就是一个私人嵌套类有关,但试图公开只是为了看看会发生什么,而没有用。帮助获取通用AVL树在C编译(IEnumerator问题)#

我对这一个有点难住,不应该有任何转换正在进行。

任何帮助将不胜感激。

这里是源代码,我已经注意到了编译错误的地方,并且为了便于阅读而打破了不同的嵌套类。

class AVLTree<TKey, TValue> : IEnumerable<TKey> where TKey : IComparable<TKey> 
{ 

#region nested classes 

节点分类 -

#region BTNode class 
    private class BTNode<TKey, TValue> where TKey : IComparable<TKey> 
    { 
    #region class variables 
     public TValue data; 
     public TKey key; 
     public int height; 
     public int balFactor; 
     public BTNode<TKey, TValue> up; 
     public BTNode<TKey, TValue> left; 
     public BTNode<TKey, TValue> right; 
    #endregion 

    #region con/destructors 
     //Key and value, constructor for very first node. 
     public BTNode(TKey new_key, TValue new_data) 
     { 
      key = new_key; 
      data = new_data; 
      height = 1; 
      balFactor = 0; 
     } 

     //Normal use constructor after initial 
     //has been made. 
     public BTNode(TKey new_key, TValue new_data, BTNode<TKey, TValue> new_up) 
     { 
      key = new_key; 
      data = new_data; 
      up = new_up; 
      height = 1; 
      balFactor = 0; 
     } 
    #endregion 
    } 
#endregion 

枚举辅助类 -

#region Enumerator class 

    private class AVLEnumerator<TKey,TValue> : IEnumerator<TKey> where TKey : IComparable<TKey> 
    { 
    #region class variables 

     private AVLTree<TKey, TValue> AVLTreeEnum; 
     private BTNode<TKey, TValue> current; 
    #endregion 

    #region con/destructors 

     public AVLEnumerator(AVLTree<TKey, TValue> toEnumerate) 
     { 
      AVLTreeEnum = toEnumerate; 
      current = null; 
     } 
    #endregion 

    #region interface methods 

     //interface method to move to the next 
     //node. 
     public bool MoveNext() 
     { 
      BTNode<TKey, TValue> sendMe; 
      //If current is null, it's at start of tree, 
      //set current to leftmost node in left subtree of root. 
      if (current == null) 
      { 
       /* error below on 'sendMe =' line-- 
        * Cannot implicitly convert type 
        * 'BSTs.AVLTree<TKey,TValue>.BTNode<TKey,TValue> ' to 
        * 'BSTs.AVLTree<TKey,TValue>.BTNode<TKey,TValue> ' 
        */ 
       sendMe = AVLTreeEnum.root; 

       /* two errors on 'current =' line-- 
       * The best overloaded method match for 
       * 'BSTs.AVLTree<TKey,TValue>.GetLeftMost 
       * (BSTs.AVLTree<TKey,TValue>.BTNode<TKey,TValue>)' 
       * has some invalid arguments 
       * 
       * and 
       * 
       * Argument 1: cannot convert from 
       * 'BSTs.AVLTree<TKey,TValue>.BTNode<TKey,TValue>' to 
       * 'BSTs.AVLTree<TKey,TValue>.BTNode<TKey,TValue>' 
       */ 
       current = AVLTreeEnum.GetLeftMost(sendMe); 
      } 
      else 
      { 
       //If we can go right from current, get leftmost node 
       //of current.rights left subtree. 
       if (current.right != null) 
       { 

        sendMe = current.right; 
        /* two errors on 'current =' -- 
        * The best overloaded method match for 
        * 'BSTs.AVLTree<TKey,TValue>.GetLeftMost 
        * (BSTs.AVLTree<TKey,TValue>.AVLNode<TKey,TValue>)' 
        * has some invalid arguments 
        * 
        * and 
        * 
        * Argument 1: cannot convert from 
        * 'BSTs.AVLTree<TKey,TValue>.AVLNode<TKey,TValue>' 
        * to 'BSTs.AVLTree<TKey,TValue>.AVLNode<TKey,TValue>' 
        */ 
        current = AVLTreeEnum.GetLeftMost(sendMe); 
       } 
       else 
       { 
        //Move up until we find a value larger than current. 
        TKey currentValue = current.key; 

        while (current != null) 
        { 
         current = current.up; 

         if (current != null) 
         { 
          if (current.key.CompareTo(currentValue) >= 0) 
          { 
           break; 
          } 
         } 
        } 
       } 
      } 

      return (current != null); 
     } 

     //Interface method to reset enumeration 
     public void Reset() 
     { 
      current = null; 
     } 

     //Interface property to return current key 
     public TKey Current 
     { 
      get 
      { 
       if (current == null) 
       { 
        throw new InvalidOperationException(
         "Enumerator got a null"); 
       } 
       return current.key; 
      } 
     } 

     //interface non-generic method 
     Object System.Collections.IEnumerator.Current 
     { 
      get { return this.Current; } 
     } 

     //interface method, must have a dispose. 
     public void Dispose() 
     { } 
    #endregion 
    } 
#endregion 
#endregion 

-

#region class variables 
    private BTNode<TKey, TValue> root; 
    private int size; 
#endregion 

#region properties 
    public int Size 
    { get { return size; } } 
#endregion 

#region con/destructors 
    public AVLTree() 
    { size = 0; } 

    ~AVLTree() 
    { 
     root = null; 
    } 
#endregion 

-

#region interface implementation 

    //Interface for IEnumerable<T> 
    public IEnumerator<TKey> GetEnumerator() 
    { 
     return new AVLEnumerator<TKey,TValue>(this); 
    } 

    //Interface for IEnumerable. Must be included w/ Ienumerable<T> 
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 
     return this.GetEnumerator(); 
    } 
#endregion 

annnd ...

//This method will get the leftmost node of it's left subtree. 
    //used by the Enumeration class. 
    private BTNode<TKey, TValue> GetLeftMost(BTNode<TKey, TValue> currentNode) 
    { 
     while (currentNode.left != null) 
     { 
      currentNode = currentNode.left; 
     } 

     return currentNode; 
    } 

回答

0

当你嵌套泛型类里面的类,你可以从父类中使用类型参数。当你声明它们时,你正在创建新的类型参数。因此,TKey中的AVLEnumerator与的AVLTree不同。

在你的情况,我认为只是从嵌套类中删除类型参数(和约束)应该解决这个问题。

因此,例如,AVLEnumerator开头是这样的:

private class AVLEnumerator : IEnumerator<TKey> 
{ 
#region class variables 

    private AVLTree<TKey, TValue> AVLTreeEnum; 
    private BTNode<TKey, TValue> current; 
#endregion 
+0

感谢,并没有意识到......当然,我花了2个小时,试图弄清楚发生了什么事情太> 。< –