ZBLOG

/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), n...

你的代码尝试对一个单链表进行排序,但是存在一些错误和不优化的地方。以下是修正后的代码,并且我会解释每个部分。

修正后的代码

#include <map>
using namespace std;

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* sortList(ListNode* head) {
        // 如果链表为空或只有一个节点,直接返回头指针
        if (!head || !head->next) return head;

        map<int, ListNode*> mymap;
        ListNode* tempnode = head;

        // 将链表中的节点存入map中,以值为键,节点指针为值
        while (tempnode) {
            mymap[tempnode->val] = tempnode;
            tempnode = tempnode->next;
        }

        // 创建一个新的虚拟头结点用于构建结果链表
        ListNode* result = new ListNode();
        ListNode* result1 = result;

        // 遍历 map,将按顺序排列的节点连接到结果链表中
        for (auto& pair : mymap) {  // 注意这里使用 auto& pair,而不是 auto& temp mymap
            result->next = pair.second;  // 使用 second 获取节点指针
            result = result->next;
            result->next = nullptr;  // 确保新链表的尾部不再指向旧链表的其他部分
        }

        return result1->next;  // 返回结果链表的头结点(跳过虚拟头结点)
    }
};

修改与解释:

  1. 遍历和插入: 在使用 for(auto& temp mymap) 时应改为 for (auto& pair : mymap)。这样才能正确遍历 std::map 中的元素。
  2. 清空链接: 当你将节点添加到新的结果链表时,应确保在最后一项后面设置 result->nextnullptr,以避免意外链接回原始链表。
  3. 性能问题: 此方法效率较低,因为它使用了 std::map(红黑树),导致插入操作是 O(log n)。对于单链表排序,通常更好的选择是归并排序,它可以实现 O(n log n) 的时间复杂度。

优化建议:

考虑使用归并排序来实现更高效的单链表排序。归并排序特别适合于链表,因为它可以通过改变指针来重排元素而无需额外空间。以下是归并排序的简单实现:

class Solution {
public:
    ListNode* merge(ListNode* l1, ListNode* l2) {
        if (!l1) return l2;
        if (!l2) return l1;

        if (l1->val < l2->val) {
            l1->next = merge(l1->next, l2);
            return l1;
        } else {
            l2->next = merge(l1, l2->next);
            return l2;
        }
    }

    ListNode* findMiddle(ListNode* head) {
        if (!head || !head->next)
            return head;

        ListNode* slow = head;
        ListNode* fast = head->next;

        while (fast && fast->next) {
            slow = slow->next;
            fast = fast->next->next;
        }
        
        return slow;
    }

    ListNode* sortList(ListNode* head) {
       if (!head || !head->next)
           return head;

       // Split the list into two halves
       ListNode* mid = findMiddle(head);
       ListNode* leftHalf = head;
       ListNode* rightHalf = mid->next;
       mid->next = nullptr; 

       leftHalf = sortList(leftHalf);
       rightHalf = sortList(rightHalf);

       return merge(leftHalf, rightHalf);
   }
};

以上方法利用递归分割与合并,有效地对单链表进行排序。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=22549

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?