简体   繁体   中英

Infinite Loop with Linked List

So I'm working with a linked list and trying to sort it. I put random numbers into the linked list. First I find the lowest value and put it as the head and every following number builds a chain off the head The functions at the top were for debugging purposes and I think I narrowed it down to somewhere in:

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());
}

The full code is

#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;
}

When I run the program I get

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...

So it gives me my five random numbers if I put 5 as n , it sorts for the first 3, then it starts repeating the 2nd and 3rd lowest forever.

Any help with this would be appreciated. I've been staring at the code and I'm not getting any further at this point.

At the first iteration of the loop:

  • The list is 384 -> 886 -> 777 -> 915 -> 793
  • marker is NULL
  • The minimum node is found to be 384
  • beforeMin is NULL

At the second iteration of the loop:

  • The list is 384 -> 886 -> 777 -> 915 -> 793
  • marker is pointing to the 384 node
  • The minimum node min , starting from the node after marker , is found to be 777
  • beforeMin points to 886

We then trigger the following line of code:

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

Given what we know from above, this means setting the link from the min node 777 to point to the node directly after the marker node 384 , which is the 886 node.

However, the link from the 886 node is still pointing to the 777 node, so at this point you have a loop: 384 -> 886 -> 777 -> 886 -> 777 -> ...

Your surface-level problem is that you're not removing nodes from one point of the list (eg 777 after 886 ) before you're inserting them at another ( 777 after 384 ).

The best way to resolve this would be to organize your code a little better -- you've gotten good advice in the comments. Each distinct action should correspond to one function or method, rather than the entire process being one big chunk of code. This makes it a lot easier to check the code for correctness, because each small piece of code can be evaluated locally:

  • Is it doing what it says it's doing (ie in the function name)?
  • Is what it says it's doing in fact the right thing to do?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM