带有链表的无限循环

时间:2013-11-18 10:42:25

标签: list debugging loops linked-list infinite-loop

所以我正在使用链表并尝试对其进行排序。我把随机数放入链表中。首先,我找到最低值并将其作为头部,并且每个后面的数字构建一个链头。顶部的函数用于调试目的,我想我将其缩小到以下某处:

if (beforeMin != NULL) 
    beforeMin->set_link(min->link());
d(4);
if (marker == NULL) {
    if (min != head) {
        min->set_link(head);
        head = min;
    }
} 
else {
    min->set_link(marker->link());
}

完整的代码是

#include "node1.h"
#include <cstdlib>
#include <iostream>

using namespace std;

using namespace main_savitch_5;

void d(int val) 
{
    cout << val << endl;
}

void print(node* head) 
{
    node* current = head;
    int count = 0;

    while (current != NULL)
    {
        cout << current->data() << " ";
        current = current->link();

        if (count++ > 10) break;
    }
    cout << endl;
}

int main()
{
    size_t n;
    cout << "Please enter the number of values you want in the linked list: ";
    cin >> n;

    node* head = NULL;
    node* current = NULL;

    node* marker = NULL;
    node* beforeMin = NULL;
    node* min = NULL;

    node* previous = NULL;

    node* temp = NULL;

    //srand(time(NULL));
    if (n == 0) 
    { 
        cout << "Invalid" << endl; 
    }
    else 
    {
        list_head_insert(head, rand() % 1000 + 1);
        current = head;

        while (n-- > 1) 
        {
            list_insert(current, rand() % 1000);
            current = current->link();
        }

        current = head;
        while (current != NULL)
        {
            cout << current->data() << " ";
            current = current->link();
        }
        cout << endl;

        while ( (marker == NULL || marker->link() != NULL) 
                && head->link() != NULL)
        {
            d(1);
            current = (marker != NULL) ? marker->link() : head;
            min = current;
            d(2);
            print(head);
            current = current->link();
            while (current->link() != NULL) 
            {
                if (min->data() > current->data()) 
                {
                    min = current;
                    beforeMin = previous;
                }
                previous = current;
                current = current->link();
            }
            d(3);
            if (beforeMin != NULL) 
            {
                beforeMin->set_link(min->link()); 
            }
            d(4);
            if (marker == NULL) 
            {
                if (min != head) 
                {
                    min->set_link(head);
                    head = min;
                }
            } 
            else 
            {
                min->set_link(marker->link());
            }
            d(5);
            if (marker != NULL) { marker->set_link(min); }
            marker = min;
            d(6);
        }

        current = head;
        while (current != NULL)
        {
            cout << current->data() << " ";
            current = current->link();
        }
        cout << endl;
    }
    return 0;
}

当我运行程序时,我得到了

Please enter the number of values you want in the linked list: 5
384 886 777 915 793 
1
2
384 886 777 915 793 
3
4
5
6
1
2
384 886 777 915 793 
3
4
5
6
1
2
384 777 886 777 886 777 886 777 886 777 886 777...

所以它给了我五个随机数,如果我把5作为n,它对前三个进行排序,然后它开始重复第二个和第三个最低点。

任何有关此的帮助将不胜感激。我一直在盯着代码,我现在还没有进一步。

1 个答案:

答案 0 :(得分:0)

在循环的第一次迭代中:

  • 列表为384 -> 886 -> 777 -> 915 -> 793
  • markerNULL
  • 发现最小节点为384
  • beforeMinNULL

在循环的第二次迭代中:

  • 列表为384 -> 886 -> 777 -> 915 -> 793
  • marker指向384节点
  • min之后的节点开始,最小节点marker被发现为777
  • beforeMin指向886

然后我们触发以下代码行:

min->set_link(marker->link());

根据我们从上面所知,这意味着将链接从最小节点777设置为直接指向标记节点384之后的节点,即886节点。

但是,886节点的链接仍指向777节点,因此此时您有一个循环:384 -> 886 -> 777 -> 886 -> 777 -> ...

您的表面级问题是,您不是要从列表的某个点移除节点(例如777之后的886),然后再将它们插入另一个点(777384)之后。

解决此问题的最佳方法是更好地组织代码 - 您在评论中得到了很好的建议。每个不同的动作应该对应于一个函数或方法,而不是整个过程是一大块代码。这使得检查代码的正确性变得容易得多,因为每一小段代码都可以在本地进行评估:

  • 它正在做它正在做的事情(即在函数名称中)吗?
  • 它说它实际上做的事情是正确的吗?