2011-08-21 5 views
0

구현하려고하는 AVL 트리에서 몇 가지 컴파일 오류가 발생합니다. 뭔가가 전체 열거자를 끕니다. 헬퍼 클래스를 구현하려고 시도 할 때까지 컴파일 된 상태입니다. 나는 BTNode 자체가 개인 중첩 클래스가되는 것과 관련이 있다고 생각했지만 아무 일도 일어나지 않을 것이라는 것을 알기 위해 공개하려고했습니다.C#에서 일반 AVL 트리를 컴파일하는 데 도움이 (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

, 당신은 부모 클래스에서 형식 인수를 사용할 수 있습니다. 을 수행 할 때을 선언하면 새 형식 인수가 생성됩니다. 따라서 TKeyAVLEnumerator이고 TKeyAVLTree과 다릅니다.

귀하의 경우에는 중첩 된 클래스에서 형식 인수 (및 제약 조건)를 제거하면 문제가 해결 될 것이라고 생각합니다.

따라서, 예를 들어, AVLEnumerator의 시작과 같을 것이다 :

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

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

감사합니다, 내가 너무 무슨 일이 있었는지 알아 내려고 2 시간 동안 ... 물론 그 실현하지 않았다> . < –

관련 문제