力扣练习——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;

}

 

posted @ 2022-07-02 22:33  努力奋斗的小企鹅  阅读(58)  评论(0)    收藏  举报