利用归并算法对链表进行排序

发布于:2025-09-12 ⋅ 阅读:(22) ⋅ 点赞:(0)

/**
 * 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==nullptr||head->next==nullptr)return head;//对头指针进行判断
        //利用快慢指针找到中间值mid
        ListNode* slow=head;
        ListNode* fast=head->next;
        while(fast!=nullptr&&fast->next!=nullptr){
            slow=slow->next;
            fast=fast->next->next;
        }
            ListNode *mid=slow->next;
            slow->next=nullptr;
            //递归算法
            ListNode* left=sortList(head);
            ListNode* right=sortList(mid);
        //将mid左右的链表进行合并
        return merge(left,right);

    }
private:
    ListNode* merge(ListNode* l1,ListNode* l2){
        //创建一个哑节点
        ListNode dummy(0);//注意:此时dummy用的是栈上对象而不是堆上对象(即用ListNode而不是ListNode* dummy = new ListNode(0);)
        /*原因如下:
        栈上对象特点:

            1.自动内存管理:函数结束时自动销毁,不需要手动释放

            2.高效:栈分配比堆分配快得多

            3.安全:不会内存泄漏
        堆上对象特点:
        
            1.需要手动管理内存:必须用 delete 释放,否则内存泄漏

            2.较慢:堆分配比栈分配慢

            3.容易出错:忘记释放会导致内存泄漏
        */
        ListNode* tail=&dummy;//用tail接收
        while(l1!=nullptr&&l2!=nullptr){
            if(l1->val<l2->val){
                tail->next=l1;
                l1=l1->next;
            }
            else{
                tail->next=l2;
                l2=l2->next;
            }
            tail=tail->next;//尾指针后移
        }
        // 将剩余节点接到新链表尾部
        tail->next=(l1!=nullptr)?l1:l2;//将剩余链表部分接上
        return dummy.next;//返回头节点

    }
/*
递归过程:
sortList(4→2→1→3)

├─ 找到中点:slow在2,mid=1→3
├─ left = sortList(4→2) → 返回 2→4
│   │
│   ├─ sortList(4→2)
│   │   ├─ 找到中点:slow在4,mid=2
│   │   ├─ left = sortList(4) → 4
│   │   ├─ right = sortList(2) → 2
│   │   └─ merge(4,2) → 2→4
│   │
├─ right = sortList(1→3) → 返回 1→3
│   │
│   ├─ sortList(1→3)
│   │   ├─ 找到中点:slow在1,mid=3
│   │   ├─ left = sortList(1) → 1
│   │   ├─ right = sortList(3) → 3
│   │   └─ merge(1,3) → 1→3
│   │
└─ merge(2→4, 1→3) → 1→2→3→4
*/

};


网站公告

今日签到

点亮在社区的每一天
去签到