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
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;
}