你的代码尝试对一个单链表进行排序,但是存在一些错误和不优化的地方。以下是修正后的代码,并且我会解释每个部分。
修正后的代码
#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; // 返回结果链表的头结点(跳过虚拟头结点)
}
};
修改与解释:
- 遍历和插入: 在使用
for(auto& temp mymap)
时应改为for (auto& pair : mymap)
。这样才能正确遍历std::map
中的元素。 - 清空链接: 当你将节点添加到新的结果链表时,应确保在最后一项后面设置
result->next
为nullptr
,以避免意外链接回原始链表。 - 性能问题: 此方法效率较低,因为它使用了
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助手提供,问题来源于学员提问