单一排序链表 - 无限循环

时间:2012-09-12 04:16:35

标签: c++ linked-list runtime-error infinite-loop sortedlist

我正在使用单个链表,我想从整数的较低值到较高值进行排序。我虽然有了这个想法,但随后执行进入无限循环,我无法清楚地看到原因。这是我合作过的代码的一部分:

class Node {

    int data;
    Node* next;

public:

    Node() { };
    void SetData(int aData) { data = aData; };
    void SetNext(Node* aNext) { next = aNext; };
    int Data() { return data; };
    Node* Next() { return next; };
};

class List {

    Node *head;

public:

    List() { head = NULL; };
    void Print();
    void Append(int data);
    void Delete(int data);
};

void List::Append(int data) {

    // Create a new node
    Node* newNode = new Node();
    newNode->SetData(data);
    newNode->SetNext(NULL);

    // Create a temp pointer
    Node *tmp = head;

    if ( tmp != NULL ) {
        // Nodes already present in the list
        // Parse to end of list anytime the next data has lower value
        while ( tmp->Next() != NULL && tmp->Next()->Data() <= newNode->Data() ) {
            tmp = tmp->Next();
        }

        // Point the lower value node to the new node
        tmp->SetNext(newNode);
        newNode->SetNext(tmp->Next());
    }
    else {
        // First node in the list
        head = newNode;
    }
}

void List::Print() {

    // Temp pointer
    Node *tmp = head;

    // No nodes
    if ( tmp == NULL ) {
        cout << "EMPTY" << endl;
        return;
    }

    // One node in the list
    if ( tmp->Next() == NULL ) {
        cout << tmp->Data();
        cout << " --> ";
        cout << "NULL" << endl;
    }
    else {
        // Parse and print the list
        do {
            cout << tmp->Data();
            cout << " --> ";
            tmp = tmp->Next();
        }
        while ( tmp != NULL );

        cout << "NULL" << endl;
    }
}

如果列表无限增加或错误来自打印功能,我感到很困惑...... 对不起,也许是假的错误。 感谢。

3 个答案:

答案 0 :(得分:0)

// Point the lower value node to the new node
tmp->SetNext(newNode);
newNode->SetNext(tmp->Next());

由于您在第一次通话中覆盖了tmp->next,因此您的第二次通话实际上将newNode->next指向newNode本身,从而创建了一个周期。这会在调用Print; - )

时导致无限循环

解决方案是做如下的事情......

Node* _next = tmp->Next();
tmp->SetNext(newNode);
newNode->SetNext(_next);

话虽如此,您的代码仍然被破坏了。问题是你不检查是否需要在列表的头部之前放置;尝试做以下事情..

if ( tmp ) {
    // Check whether to become new head
    if ( tmp->Data() > newNode->Data() ) {
      newNode->SetNext(tmp);
      head = newNode;
    }
    else {
      // Nodes already present in the list
      // Parse to end of list anytime the next data has lower value
      while ( tmp->Next() && tmp->Next()->Data() <= newNode->Data() ) {
          tmp = tmp->Next();
      }

      // Point the lower value node to the new node
      Node* _next = tmp->Next();
      tmp->SetNext(newNode);
      newNode->SetNext(_next);
  }
}
else {
    // First node in the list
    head = newNode;
}

附注:您可以使用初始化列表重写代码,如...

List() : head(NULL) { };

此外,如果NULL相当于0,您可以将X == NULLX != NULL表单的条件简化为X和{{1}分别。


通过示例查看我的ideone paste更正版本。

!X

......产生

  

7 - &gt; 15 - &gt; 40 - &gt; NULL

答案 1 :(得分:0)

你的问题是这两行:

tmp->SetNext(newNode);
newNode->SetNext(tmp->Next());

你应该扭转它们。现在,您设置tmp.next = newNode,然后设置newNode.next = tmp.next(= newNode),因此newNode指向自身。然后遍历newNode会导致无限循环。

答案 2 :(得分:0)

您无法正确链接两个现有节点。看看代码的这个片段:

tmp->SetNext(newNode);
newNode->SetNext(tmp->Next());

例如,如果您有此列表:

头 - &gt; 5

并且您想插入一个编号为4的节点:

头 - &gt; 5&lt; - tmp newNode - &gt; 4

使用tmp-&gt; SetNext(newNode)

head(和tmp) - &gt; 5 - &gt; 4&lt; - newNode

使用newNode-&gt; SetNext(tmp-&gt; Next());

head(和tmp) - &gt; 5 - &gt; 4&lt; - newNode

因此,任何迭代遍历列表的尝试都将导致无限循环:

5 4 4 4 4 ......永远