Home > other >  Selection sort in single linked list without using swap
Selection sort in single linked list without using swap

Time:10-24

I have been trying to solve the selection sort in single linked list without using swap nodes. Using a temp list to store nodes and assign the current list with a new one

//my addlastnode function
void AddLastNODE(LIST &mylist, NODE *p)
{
//Check the list is empty or not
    if(isEmpty(mylist))
        mylist.pHead = mylist.pTail = p;
    else
        mylist.pTail->pNext = p;
        mylist.pTail = p;
}

void selectionSort(LIST &mylist)
{
//Initialize a temp list to store nodes 
    LIST mylisttemp;
    IntList(mylisttemp);
//Create node
    NODE *p;
    NODE *i;
//Create min node
    NODE *min;
//Check if list is empty or has one node
    if(mylist.pHead == mylist.pTail)
        return;
//Traverse the list till the last node
    for(p=mylist.pHead; p->pNext!=NULL && p!=NULL; p = p->pNext)
        {
            min=p;
                for(i=p->pNext; i!=NULL;i=i->pNext)
                {
////Find the smallest data in list
                    if(i->data < min->data)
                        min=i;
                }
////Add the smallest to a new list
                AddLastNODE(mylisttemp, min);
        }
//Fill the current list to the new list
    if(!isEmpty(mylisttemp))
    mylist = mylisttemp;
}

CodePudding user response:

Your code does not reduce the list you are selecting nodes from: the selected node should be removed from it. To make that happen, you need a reference to the node before the selected node, so that you can rewire the list to exclude that selected node.

There is also a small issue in your AddLastNODE function: it does not force the tail node to have a null as pNext pointer. This may be a cause of errors when the function is called with a node that still has a non-null pNext pointer. Secondly, the indentation is off around the else block. It does not lead to a bug in this case, but still it is better to avoid the confusion:

void AddLastNODE(LIST &mylist, NODE *p)
{
    if(isEmpty(mylist))
        mylist.pHead = p;
    else
        mylist.pTail->pNext = p;
    mylist.pTail = p; // indentation!
    p->pNext = nullptr; // <--- better safe than sorry!
}

Then to the main algorithm. It is quite tedious to work with a previous node reference when looking for the node with the minimum value. It helps a bit when you temporarily make the input list cyclic:

void selectionSort(LIST &mylist) {
    if (mylist.pHead == mylist.pTail) return;
    // Make list temporarily cyclic
    mylist.pTail->pNext = mylist.pHead;

    LIST mytemplist;
    IntList(mytemplist);

    while (mylist.pHead != mylist.pTail) {
        // Select node:
        NODE * beforemin = mylist.pTail;
        for (NODE * prev = mylist.pHead; prev != mylist.pTail; prev = prev->pNext) {
            if (prev->pNext->data < beforemin->pNext->data) {
                beforemin = prev;
            }
        }
        NODE * min = beforemin->pNext;
        // Extract selected node:
        if (min == mylist.pTail) mylist.pTail = beforemin;
        if (min == mylist.pHead) mylist.pHead = min->pNext;
        beforemin->pNext = min->pNext;
        // And insert it:
        AddLastNODE(mytemplist, min);
    }
    // Move last remaining node
    AddLastNODE(mytemplist, mylist.pHead);
    // Copy back
    mylist = mytemplist;
}

As a side note: You might even want to always keep your list cyclic. This will mean some changes in other functions you may have, as there will be no pNext pointers that are null then.

  • Related