简体   繁体   English

单链表中的选择排序不使用交换

[英]Selection sort in single linked list without using swap

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

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.您的AddLastNODE函数中还有一个小问题:它不会强制尾节点将空值作为pNext指针。 This may be a cause of errors when the function is called with a node that still has a non-null pNext pointer.当使用仍具有非空pNext指针的节点调用该函数时,这可能是导致错误的原因。 Secondly, the indentation is off around the else block.其次,在else块周围的缩进是关闭的。 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.这将意味着您可能拥有的其他函数中的一些更改,因为那时将没有pNext指针为空。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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