Search code examples
c++doubly-linked-listselection-sort

Sorting a linked list using selection sort in C++


I'm running into some sort of runtime error when trying to test my sort method. With my implementation, I attempt to find the smallest node in a linked list... Following that I test if the smallest node is first node, last node, or just in the middle. After testing for these cases, I then attempt to add the smallest value into a new linked list. I do this into all the values are sorted, then point head(private variable in my class) to the newly sorted list... If I need to include my header file or anything else, please just let me know. Any help is appreciated.

To be clear, there’s no actual error message, the program just gets terminated when I call my sort function.

void Linkedlist::sort()
{
    Node * current = head;
    Node * smallest = head;
    Node * newHead = NULL;
    Node * newTail = NULL;

    while(head != NULL)
    {
        current = head;
        while(current != NULL)
        {
            if(current->elem < smallest->elem)
            {
                smallest = current;
            }
            current = current->next; 
        }

        //smallest is first node
        if(smallest->prev == NULL)
        {
            head = head->next;
            head->prev = NULL;
        }

        //smallest is last node
        else if(smallest->next == NULL)
        {
            tail = tail->prev;
            tail->next = NULL;
        }

        else
        {
            smallest->prev->next = smallest->next;
            smallest->next->prev = smallest->prev;
        }

        //adding smallest to a new linked list
        if(newHead == NULL)
        {
            smallest->prev = NULL;
            smallest->next = NULL;
            newHead = smallest;
        }
        else
        {
            smallest->prev = newTail;
            smallest->next = NULL;
            newTail->next = smallest;
            newTail = smallest;
        }
    }
    //point head to new linked list
    head = newHead;

}

Solution

  • after adding

    newTail = smallest
    

    when putting the smallest element into the first node, and adding

    smallest = head
    

    to the top of my outer while loop, I still was running into an infinite loop. I figured out that for one, I needed to point tail to the newTail at the end by saying

    tail = newTail
    

    After that, my function still caused a segfault. This segfault was due to me trying to access the prev member of a NULL.

    head = head->next //head is now NULL
    head->prev = NULL //segfault
    

    This situation occurred when there was only one node was left in the unsorted list. I fixed this issue by adding an if statement inside of the if statement that checks if the smallest is the first node. The if statement inside checked if it was also the final node(aka the last node remaining)

    //smallest is first node
            if(smallest->prev == NULL)
            {
                //check if smallest is the ONLY node left
                //if it is only node left, head = head->next makes head NULL 
                //                         so then head->prev = NULL causes segfault
                if(smallest->next == NULL)
                {
                    //break leaves while loops 
                    //which is why you have to add the final node 
                    //outside of the while loops
                    break;
                }
    
                else
                {
                    head = head->next;
                    head->prev = NULL;
    
                }
            }
    

    When there is one node remaining, it will hit the break, and exit both while loops. This means the final node was never added to the sorted list. To fix this I just used the following code before pointing head and tail to their new list.

    smallest->prev = newTail;
    smallest->next = NULL;
    newTail->next = smallest;
    newTail = smallest;