2014-03-07 4 views
0

주어진 노드를 제거해야하는 이중 연결 목록 및 I 방법이 있습니다. 그것은 원래 코드를 개발했을 때 원래 3 개의 테스트 노드와 함께 작동했지만 처음에는 Doubly Linked List에 더 많은 노드를 추가했을 때 작동을 멈추었습니다. 이제는 NullReferenceException이 발생합니다 : "객체 참조가 객체의 인스턴스로 설정되지 않았습니다." 나는 단지 일반적인 연결리스트를 사용할 수 있었지만, 나는 이중 연결리스트가 어떻게 작동 하는지를 배우려고 노력하고있다.이중 연결 목록에서 노드를 제거하는 데 문제가 있습니다.

줄 시작 부분에 "**"가 포함 된 코드를 두 번 표시합니다 (이 코드는 이중 링크 목록 클래스의 RemoveNode 메서드에 있음). 여기

내 코드입니다 :

이중 연결리스트 클래스 :

class DoublyLinkedList 
{ 
    public Node head, current; 

    public void AddNode(object n) // add a new node 
    { 
     if (head == null) 
     { 
      head = new Node(n); //head is pointed to the 1st node in list 
      current = head; 
     } 
     else 
     { 
      while (current.next != null) 
      { 
       current = current.next; 
      } 

      current.next = new Node(n, current); //current is pointed to the newly added node 
     } 
    } 

    public Node FindNode(object n) //Find a given node in the DLL 
    { 
     current = head; 
     while ((current != null) && (current.data != n)) 
      current = current.next; 

     if (current == null) 
      return null; 
     else 
      return current;      
    } 


    public string RemoveNode(object n)//remove nodes 
    { 
     String Output = ""; 

     if (head == null) 
     { 
      Output += "\r\nLink list is empty"; 
     } 
     else 
     { 
      current = FindNode(n); 

      if (current == null) 
      { 
       Output += "Node not found in Doubly Linked List\r\n"; 
      } 
      else 
      {     
       ****current.next.prev = current.prev;**   
       current.prev.next = current.next; 
       current.prev = null; 
       current.next = null; 
       Output += "Node removed from Doubly Linked List\r\n"; 
      } 
     } 
     return Output; 
    } 

    public String PrintNode() // print nodes 
    { 
     String Output = ""; 

     Node printNode = head; 
     if (printNode != null) 
     { 
      while (printNode != null) 
      { 
       Output += printNode.data.ToString() + "\r\n"; 
       printNode = printNode.next; 
      } 
     } 
     else 
     { 
      Output += "No items in Doubly Linked List"; 
     } 
     return Output; 
    } 

} 

노드 클래스 :

class Node 
{ 
    public Node prev, next; // to store the links 
    public object data; // to store the data in a node 

    public Node() 
    { 
     this.prev = null; 
     this.next = null; 
    } 

    public Node(object data) 
    { 
     this.data = data; 
     this.prev = null; 
     this.next = null; 
    } 

    public Node(object data, Node prev) 
    { 
     this.data = data; 
     this.prev = prev; 
     this.next = null; 
    } 

    public Node(object data, Node prev, Node next) 
    { 
     this.data = data; 
     this.prev = prev; 
     this.next = next; 
    } 

} 
+0

'current'는 회원님의 목록에 포함되어서는 안됩니다. 적절한 메소드의 로컬 변수 여야합니다. –

+0

'current.next'와 같이 보이는 것은 null이어야합니다. 이 예외가 발생하면 목록의 마지막 항목을 제거 하시겠습니까? – Blorgbeard

+0

질문 제목에 사용 된 언어에 대한 정보가 없으면 이해하기 어려운 경우가 아니라면 질문 제목에 사용 된 언어에 대한 정보는 포함하지 마십시오. 태그는 이러한 용도로 사용됩니다. –

답변

2

를 내가 작업을 얻었다. 나는 당신에게 약간의 논리를 바꿨지만. current 필드를 사용하여 꼬리를 표시하고 검색하는 데 별도의 변수를 사용합니다. 지금, 나는 정수 값을 테스트하고 어떤 문제가 발생하는 것은 당신이 당신이 얻을 수있는 값

(current.data != n) 

비교 선이었다 (10) (10)! = 그 값은 박스 및 참조가 다릅니다 때문이다. 대신 current.data.Equals(n)을 사용하십시오. Equals()은 실제 개체로 거품을내어 참조가 아닌 데이터를 비교하는 가상 메서드입니다.

또한 제거 논리는 더 복잡해야합니다. if/else 문을 모두 제거하여 더 쉽게 읽을 수 있습니다.

public void AddNode(object n) // add a new node 
{ 
    if (head == null) 
    { 
     head = new Node(n); //head is pointed to the 1st node in list 
     current = head; 
    } 
    else 
    { 
     var newNode = new Node(n, current); 
     current.next = newNode; 
     current = newNode; //current is pointed to the newly added node 
    } 
} 

public Node FindNode(object n) //Find a given node in the DLL 
{ 
    var index = head; 
    while (index != null) 
    { 
     if (index.data.Equals(n)) 
      break; 

     index = index.next; 
    } 

    return index ?? null; 
} 

public string RemoveNode(object n) //remove node 
{ 
    if (head == null) 
     return "\r\nLink list is empty"; 

    var node = FindNode(n); 

    if (node == null) 
     return "Node not found in Doubly Linked List\r\n";   

    if (node != head) 
     node.prev.next = node.next; 

    if (node.next != null) 
     node.next.prev = node.prev; 

    return "Node removed from Doubly Linked List\r\n"; 
} 
+0

대단히 감사합니다! – Maattt

0

당신은 하나의 요소 (함께 목록에서 개체를 삭제하려고합니까 = head)? 거기에 오류가있어 삭제 루틴을 확인하십시오. FindNode을 사용하여 요소를 수신하면 머리 노드가 반환됩니다. 이후에 current.prev.next = current.next;이라고 부르면 헤드 노드에 previous 또는 next 노드가 없으므로 실패합니다.

나는 당신의 제거 기능이 비슷해야 가정 것 :

public string RemoveNode(object n)//remove nodes 
{ 
    String Output = ""; 

    if (head == null) 
    { 
     Output += "\r\nLink list is empty"; 
    } 
    else 
    { 
     var toRemove = FindNode(n); 

     if (toRemove == null) 
     { 
      Output += "Node not found in Doubly Linked List\r\n"; 
     } 
     else 
     {     
      if(toRemove.prev != null) 
       toRemove.prev.next = toRemove.next != null ? toRemove.Next : null; 
      if(toRemove.next != null) 
       toRemove.next.prev = toRemove.prev != null ? toRemove.prev : null; 

      Output += "Node removed from Doubly Linked List\r\n"; 
     } 
    } 
    return Output; 
} 
관련 문제