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...

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

修正后的代码

  1. #include <map>
  2. using namespace std;
  3. /**
  4. * Definition for singly-linked list.
  5. * struct ListNode {
  6. * int val;
  7. * ListNode *next;
  8. * ListNode() : val(0), next(nullptr) {}
  9. * ListNode(int x) : val(x), next(nullptr) {}
  10. * ListNode(int x, ListNode *next) : val(x), next(next) {}
  11. * };
  12. */
  13. class Solution {
  14. public:
  15. ListNode* sortList(ListNode* head) {
  16. // 如果链表为空或只有一个节点,直接返回头指针
  17. if (!head || !head->next) return head;
  18. map<int, ListNode*> mymap;
  19. ListNode* tempnode = head;
  20. // 将链表中的节点存入map中,以值为键,节点指针为值
  21. while (tempnode) {
  22. mymap[tempnode->val] = tempnode;
  23. tempnode = tempnode->next;
  24. }
  25. // 创建一个新的虚拟头结点用于构建结果链表
  26. ListNode* result = new ListNode();
  27. ListNode* result1 = result;
  28. // 遍历 map,将按顺序排列的节点连接到结果链表中
  29. for (auto& pair : mymap) { // 注意这里使用 auto& pair,而不是 auto& temp mymap
  30. result->next = pair.second; // 使用 second 获取节点指针
  31. result = result->next;
  32. result->next = nullptr; // 确保新链表的尾部不再指向旧链表的其他部分
  33. }
  34. return result1->next; // 返回结果链表的头结点(跳过虚拟头结点)
  35. }
  36. };

修改与解释:

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

优化建议:

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

  1. class Solution {
  2. public:
  3. ListNode* merge(ListNode* l1, ListNode* l2) {
  4. if (!l1) return l2;
  5. if (!l2) return l1;
  6. if (l1->val < l2->val) {
  7. l1->next = merge(l1->next, l2);
  8. return l1;
  9. } else {
  10. l2->next = merge(l1, l2->next);
  11. return l2;
  12. }
  13. }
  14. ListNode* findMiddle(ListNode* head) {
  15. if (!head || !head->next)
  16. return head;
  17. ListNode* slow = head;
  18. ListNode* fast = head->next;
  19. while (fast && fast->next) {
  20. slow = slow->next;
  21. fast = fast->next->next;
  22. }
  23. return slow;
  24. }
  25. ListNode* sortList(ListNode* head) {
  26. if (!head || !head->next)
  27. return head;
  28. // Split the list into two halves
  29. ListNode* mid = findMiddle(head);
  30. ListNode* leftHalf = head;
  31. ListNode* rightHalf = mid->next;
  32. mid->next = nullptr;
  33. leftHalf = sortList(leftHalf);
  34. rightHalf = sortList(rightHalf);
  35. return merge(leftHalf, rightHalf);
  36. }
  37. };

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


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

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

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

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

联系我们

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

微信号:3007537140

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

关注我们
x

注册

已经有帐号?