【问题标题】:Merge Sort in Linked list链接列表中的合并排序
【发布时间】:2022-01-10 08:34:36
【问题描述】:

在这段代码中,我试图在链接列表中实现合并排序。我的样本输入 1 23 5 6 8 5 48 5 8 65 -1。 但是程序完成后,它既不显示任何输出,也不显示排序链表的地址,也不显示整个链表。我认为我的列表在 mergeSort 函数中丢失了。但我不知道在哪里。 对不起,我的问题提问格式,我是这里的新蜜蜂。

class Node{
    public:
    int data;
    Node *next;
    Node(int data){
        this->data = data ;
        this->next = NULL ;
    }
};

Node* takeInput(){
        int data ;
        cin >> data;
        Node *head = NULL ;
        Node *tail = NULL ;
        while ( data != -1 ) {
            Node* newNode = new Node(data);
            if(head == NULL) head = newNode , tail = newNode ;
            else {
                tail->next = newNode;
                tail = newNode;
            }
            cin >> data ;
        }
        return head ;
    }    

//print data of Linked List.
void print(Node *head ){
        Node *temp = head ;
        while( temp!= NULL ){
            cout << temp->data << "  " ;
            temp = temp->next ;

        }

    }

Node* MidNode(Node* head){
    Node *fast = head->next ;
    Node *slow  = head ;
    while(fast->next != NULL || fast != NULL){
        slow = slow->next;
        fast = fast->next;
        fast = fast->next;
    }
    return slow;
}
Node* mergeLL(Node *h1 , Node *h2){
    Node *head = NULL , *tail = NULL;
    if(h1->data < h2->data) {
        head = h1 ;
        tail = h1;
        h1 = h1->next;
    }
    else {
        head = h2 ;
        tail = h2 ;
        h2 = h2->next;
    }
    while (h1 != NULL and h2 != NULL){
        if(h1->data > h2->data){
            tail->next = h2;
            tail = tail->next;
            h2 = h2->next;
        }
        else {
            tail->next = h1 ;
            tail = tail->next ;
            h1 = h1->next;
        }
        
    }
        while( h2 != NULL){
            tail->next = h2 ;
            tail = tail->next;
            h2 = h2->next;
        }
        while( h1 != NULL ){
            tail->next = h1 ;
            tail = tail->next;
            h1 = h1->next;
        }
        return head ;
}


Node* mergeSort(Node *head ){
    if(head == NULL || head->next == NULL) return head  ;
    Node *mid = MidNode(head);
    Node *leftList = head;
    Node *rightList = mid->next ;
    mid->next = NULL ;
    leftList = mergeSort(leftList);
    rightList = mergeSort(rightList);
    return mergeLL(leftList , rightList);
    
}



int main(){
    Node* head2 = takeInput();
    
    Node* ans = mergeSort(head2 );    
    cout << ans <<endl;
    print(ans);
    return 0 ;
}

【问题讨论】:

  • 什么是样本输入?
  • 让自己更容易调试。不要接受用户的输入;为了进行测试,您的takeInput() 函数应该是一系列语句,例如insert(23);,其中insert() 是一个新函数(代码从当前takeInput() 中提取),仅负责将一个值插入到您的列表中。 (让一个函数负责收集输入并将该数据插入到列表中是一个糟糕的设计决定。)另外,如果 2 个甚至 1 个节点足以重现问题,则不要处理 10 个节点。这应该足够简单,可以在调试器中单步执行。
  • @JaMiT ,它是在不使用输入功能的情况下一一输入后工作的。但我想知道导致 mergeSort 函数现在工作的输入函数有什么问题。
  • @Amitkhurrana 这表明您的错误在于输入函数而不是排序,但可能症状不会立即显现。因此,您应该构建一个不使用输入函数的列表和一个使用输入函数的列表(每种情况下的数据相同),并仔细比较两者以查看它们的不同之处。

标签: c++ linked-list c++17 mergesort undefined-behavior


【解决方案1】:

MidNode 函数中你有:

while(fast->next != NULL || fast != NULL){
    //...
}

如果fast 为空怎么办?您取消引用 NULL 指针并进入 UB 领域。

您的意思可能是:while(fast != NULL &amp;&amp; fast-&gt;next != NULL)。请注意,您的代码中的偶数操作不正确。

接下来,在这个循环中:

        slow = slow->next;
        fast = fast->next;
        fast = fast->next;

出于同样的原因,您有机会再次获得 UB。您需要添加支票:

        slow = slow->next;
        fast = fast->next;
        if (fast != NULL)
            fast = fast->next;

我还没有检查其余代码,所以可能还有更多问题。

【讨论】:

  • 我试过你的代码,但还是不行
  • 好吧,这个问题到此结束,因为我做了同样的事情并且效果很好。
  • @Amitkhurrana,您的代码中还有更多问题,但这不是“解决家庭作业的免费服务”。具体点,提出具体问题,祝调试顺利。
猜你喜欢
  • 2010-09-05
  • 2012-10-31
  • 2014-08-31
  • 2020-05-24
  • 1970-01-01
  • 2020-09-25
相关资源
最近更新 更多