使用指针对单向链表进行排序

Sorting a Singly Linked List With Pointers

本文关键字:链表 排序 指针      更新时间:2023-10-16

我正在尝试通过仅操作指针而不操作键来使用气泡排序对单向链表进行排序。

以下内容卡在 for 循环中并无限循环。我不明白这是为什么。谁能向我解释为什么找不到列表的末尾?

Node* sort_list(Node* head)
{
    Node * temp;
    Node * curr;
    for(bool didSwap = true; didSwap; ) {
            didSwap = false;
            for(curr = head; curr->next != NULL; curr = curr->next) {
                    if(curr->key > curr->next->key) {
                            temp = curr;
                            curr = curr->next;
                            curr->next = temp;
                            didSwap = true;
                    }
                    cout << curr->next->key << endl;
            }
    }
    return head;

}

如果我更改代码以便交换键(数据),则该函数可以正常工作,但由于某种原因,我无法通过仅操作指针来使其工作。

逻辑错误,您正在使用以下代码创建一个无限循环 -

temp = curr;
curr = curr->next;
curr->next = temp;

I,e next_of_current指向当前,因此 curr->next 将始终为 curr,永远不会为 NULL;

接下来,您应该使用上一个指针来修复您的列表,因为您的列表可以在一个方向上遍历。所以,想想——如果 A->B->C->空;并且您使 C 和 B 交换,然后新列表仍将指向 A->B,下一次迭代将是错误的......因为你没有修改你之前的下一个。

所以,另一种实现可能是——

Node* sort_list(Node* head) {
    Node * curr;
    Node * prev;
    for(bool didSwap = true; didSwap; ) {
        didSwap = false;
        prev = head;
        for(curr = head; curr->next != NULL; curr = curr->next) {
                if(curr->key > curr->next->key) {
                        if (head == curr) {
                            head = curr->next;      
                            curr->next = head->next; 
                            head->next = curr; 
                            prev = head;
                        } else {
                            prev->next = curr->next;
                            curr->next = prev->next->next;
                            prev->next->next = curr
                        }
                        didSwap = true;
                } else if (head != curr) {
                    prev = prev->next;
                } 
                //cout << curr->next->key << endl; // <- this may cause crash if curr->next now points to NULL; (i,e last element)
            }
    }
    return head;
}

希望这有帮助,问候。

您有以下问题:

让您列出三个成员:ptr1->ptr2->ptr3 。在交换之前,您设置了以下指针:curr=ptr1; curr->next=ptr2; curr->next->next=ptr3 。执行交换时,您会收到curr=ptr2; curr->next=ptr1; curr->next->next=ptr2

例如,您丢失了 ptr3。您需要通过以下方式更改内部循环的代码:

temp = curr;
temp->next = curr->next->next;    // Save ptr3
curr = curr->next;
curr->next = temp;
didSwap = true;

您要交换的字段是value。但是,如果您交换nodenext字段将更改,问题变得有点复杂,您需要保持next字段正确。总之,改变value是一种简单而好的方法。

node *sorted_list(node *head) {
    node *index1,*index2;
    for(index1=head;index1->next!=NULL;index1=index1->next) {
        for(index2=index1->next;index2!=NULL;index2=index2->next) {
            if(index1->data>index2->data) {
                int temp=index1->data;
                index1->data=index2->data;
                index2->data=temp;
            }
        }
    }
    return head;
}