力扣练习——3 排序链表
1.问题描述
在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。
示例 1:
输入: 4->2->1->3
输出: 1->2->3->4
示例 2:
输入: -1->5->3->4->0
输出: -1->0->3->4->5
可使用以下代码,完成其中的sortList函数,其中形参head指向无头结点单链表。
#include<iostream>
using namespace std;
struct ListNode
{
int val;
ListNode *next;
ListNode() : val(0), next(NULL) {}
ListNode(int x) : val(x), next(NULL) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
class Solution {
public:
ListNode* sortList(ListNode* head)
{
//填充本函数完成功能
}
};
ListNode *createByTail()
{
ListNode *head;
ListNode *p1,*p2;
int n=0,num;
int len;
cin>>len;
head=NULL;
while(n<len && cin>>num)
{
p1=new ListNode(num);
n=n+1;
if(n==1)
head=p1;
else
p2->next=p1;
p2=p1;
}
return head;
}
void displayLink(ListNode *head)
{
ListNode *p;
p=head;
cout<<"head-->";
while(p!= NULL)
{
cout<<p->val<<"-->";
p=p->next;
}
cout<<"tail\n";
}
int main()
{
ListNode* head = createByTail();
head=Solution().sortList(head);
displayLink(head);
return 0;
}
2.输入说明
首先输入链表长度len,然后输入len个整数,以空格分隔。
3.输出说明
输出格式见范例
4.范例
输入
5
-1 5 3 4 0
输出
head-->-1-->0-->3-->4-->5-->tail
5.代码
#include<iostream> using namespace std; struct ListNode { int val; ListNode *next; ListNode() : val(0), next(NULL) {} ListNode(int x) : val(x), next(NULL) {} ListNode(int x, ListNode *next) : val(x), next(next) {} }; class Solution { public: //合并两个不带头结点的单链表 ListNode *mergeList(ListNode *L1, ListNode *L2) { ListNode* head = (ListNode *)malloc(sizeof(ListNode)); ListNode* p1 = L1; //扫描指针p1指向第一个链表 ListNode* p2 = L2; //扫描指针p2指向第二个链表 ListNode* pre = head; //记录前驱结点 while (p1 != NULL && p2 != NULL) { if (p1->val <= p2->val) { //按降序进行连接 pre->next = p1; p1 = p1->next; } else { pre->next = p2; p2 = p2->next; } pre = pre->next; } pre->next = p1 == NULL ? p2 : p1; return head->next;//注意这里必须为head->next,不是head } //采用归并排序【递归】进行排序,head指向无头结点单链表。 ListNode* sortList(ListNode* head) { //1.特殊情形,空链表或者只有一个结点时,直接返回 if (head == NULL || head->next == NULL) { return head; } //2.采用快慢指针法寻找链表的中间结点,将链表划分为左右两部分 ListNode *slow = head; ListNode *fast = head->next;//注意这里为head->next while (fast != NULL && fast->next != NULL) { slow = slow->next;//slow指向中间结点 fast = fast->next->next; } ListNode *tmp = slow->next;//tmp指向右边链表的开头 slow->next = NULL; //注意这里要将左边链表的尾结点后继设置为空 //3.对左右链表分别进行归并操作 ListNode *left = sortList(head); //head是前一个链表的起点,left为排序完的起点 ListNode *right = sortList(tmp); //tmp是后一个链表的起点,right为排序完的起点 //4.将各自归并后的左右链表进行归并 struct ListNode *p=mergeList(left, right); return p; } }; ListNode *createByTail() { ListNode *head; ListNode *p1, *p2=NULL; int n = 0, num; int len; cin >> len; head = NULL; while (n<len && cin >> num) { p1 = new ListNode(num); n = n + 1; if (n == 1) head = p1; else p2->next = p1; p2 = p1; } return head; } void displayLink(ListNode *head) { ListNode *p; p = head; cout << "head-->"; while (p != NULL) { cout << p->val << "-->"; p = p->next; } cout << "tail\n"; } int main() { ListNode* head = createByTail(); head = Solution().sortList(head); displayLink(head); return 0; }

浙公网安备 33010602011771号