【问题标题】:Selection Sort (swapping pointers rather than data)选择排序(交换指针而不是数据)
【发布时间】:2021-06-30 10:20:02
【问题描述】:

我一直在尝试创建一个selection sort 函数来通过仅交换指针而不是nodes 的数据/内容来按升序对linked list 进行排序,因为我认为如果有很多数据在每个节点中,则需要大量的临时内存来交换数据。

问题是我无法弄清楚的交换逻辑有问题。我仍然有一些测试用例,在交换后,链表的节点丢失了,因为指针无法将它们连接在一起。

我的逻辑是应该有两种主要情况:
案例 1) 当两个节点相邻(彼此相邻)
情况2)当两个节点(不相邻)

我要处理第一个节点(头);因此,应该有4个案例 =(2个头部或非头部)x(2个相邻或远距离)

这是构建我的链表的两个类

template <class T>
class ListNode
{
public:
    T value;
    ListNode<T> *next;
    ListNode(T val)
    {
        value=val;
        next=nullptr;
    }
};
template <class T>
class Class_LinkedList
{
private:
    ListNode<T> *head;
public:
    /*****constructors + functions*****/
    void sort() {;}
}

这是我遇到问题的排序功能

    void sort()
    {
        /*******There are four cases for swapping********
         Case 1: First node (head) and Minimum Node are not adjacent
         Case 2: First node (head) and Minimum Node are adjacent
         (Case 3 and 4 are for non-head)
         Case 3: The two nodes are not adjacent
         Case 4: The two nodes are adjacent */

        if (head==nullptr)
            return;

        ListNode<T> * pre_startPtr = nullptr; //points to the node before the starting node (selection sort)
        ListNode<T> * pre_nodePtr = nullptr; //temporary pointer that points to the node before the temporary node for traversing
        ListNode<T> * pre_minNodePtr=nullptr; //points to the node before the minimum node
        //the prefix pre_ indicates these pointers point to previous nodes

        /********Dealing with head/the first node*********
         * Traverse once through the list to find the minimum node and swap it with the first node
        **********************************/

        pre_minNodePtr=head;
        pre_nodePtr=head;

        while (pre_nodePtr->next!=nullptr)
        {
            if (pre_minNodePtr->next->value > pre_nodePtr->next->value)
            {
                pre_minNodePtr=pre_nodePtr;
            }
            pre_nodePtr=pre_nodePtr->next;
        }
        if (pre_minNodePtr->next->value < head->value) //if there is a value less than head value, then swap
        {
            //Case 1: First node (head) and Minimum Node are not adjacent

            if (head!=pre_minNodePtr)
            {
                ListNode <T> * temp;
                temp=head;
                head=pre_minNodePtr->next;
                pre_minNodePtr->next=head;
                temp=head->next;
                head->next=pre_minNodePtr->next->next;
                pre_minNodePtr->next->next=temp;
            }
            //Case 2: First node (head) and Minimum Node are adjacent
            else //if (head==pre_minNodePtr)
            {
                head=pre_minNodePtr->next;
                pre_minNodePtr->next=head->next;
                head->next=pre_minNodePtr;
            }
        }

        /************Dealing with the list after the first node**************/

        pre_startPtr=head; //starting node = the second node (the node after head)

        while (pre_startPtr->next!=nullptr)
        {

            pre_minNodePtr=pre_startPtr;
            pre_nodePtr=pre_startPtr->next;

            while (pre_nodePtr->next!=nullptr)
            {
                if (pre_minNodePtr->next->value > pre_nodePtr->next->value)
                {
                    pre_minNodePtr=pre_nodePtr;
                }
                pre_nodePtr=pre_nodePtr->next;
            }
            //swap nodes if there is a value less than that of the starting node
            if (pre_minNodePtr->next->value < pre_startPtr->next->value)
            {
                //Case 3: The two nodes are not adjacent
                if (pre_startPtr->next!=pre_minNodePtr)
                {
                    ListNode<T> * temp;
                    temp = pre_startPtr->next;
                    pre_startPtr->next=pre_minNodePtr->next;
                    pre_minNodePtr->next=temp;
                    temp = pre_startPtr->next->next;
                    pre_startPtr->next->next = pre_minNodePtr->next->next;
                    pre_minNodePtr->next->next = temp;
                }
                //Case 4: The two nodes are adjacent
                else //if (pre_startPtr->next==pre_minNodePtr)
                {
                    pre_startPtr->next=pre_minNodePtr->next;
                    pre_minNodePtr->next=pre_startPtr->next->next;
                    pre_startPtr->next->next=pre_minNodePtr;
                }
            }
            //starting node = the next node
            pre_startPtr=pre_startPtr->next;
        }
    }

【问题讨论】:

  • 首先,最好交换指针而不是数据,因为这是进行选择排序的理想方式。其次,您是否尝试过使用调试器?如果没有,那么现在是学习如何使用调试器的好时机。
  • 另外,通常选择排序函数应该命名为selecSort或类似的名称,并且最好将链表作为参数。请更改您的命名约定(Class_LinkedList)在cpp领域真的不受欢迎:)
  • 谢谢。老实说,我不知道如何使用调试器。我将观看 youtube 视频以了解如何在 Eclipse 上使用它。

标签: c++ sorting pointers linked-list


【解决方案1】:

解决了。 我的代码中有一个我一开始没有注意到的错误。 正是在将 pre_minNodePtr->next 与 head 交换时,我将 pre_minNodePtr->next 分配为 head 而不是 temp(head 的临时值,因为 head 已经更改)。

错误的行:

pre_minNodePtr->next=head;

应该固定为

pre_minNodePtr->next=temp;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-10
    • 1970-01-01
    • 2012-02-17
    • 2013-10-31
    相关资源
    最近更新 更多