归并排序(链表和数组)

归并排序就是将两个或者两个以上的有序表合并为一个有序表的过程。将两个有序表合并成

一个有序表的过程称为2-路归并,2-路归并是最为简单的和常用的。

归并排序算法的思想是:

假设初始序列含有n个记录,则可看成是n个有序的子序列,每个子序列的长度是1,然后两

两归并,得到[n/2]个长度为2或1的有序子序列;再两两归并,如此重复,直至得到一个长度

为n的有序序列为止。

链表归并排序 (leetcode–148. 排序链表) 代码如下:

/**
 * 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 == NULL || head -> next == NULL) {
                return head;
            }
            ListNode * mid = findmid(head);
            ListNode * left = head;
            ListNode * right = mid -> next;
            mid -> next = NULL;//把两个链表断开
            return Merge(sortList(left), sortList(right));
        }
        //寻找中间节点
        ListNode* findmid(ListNode*head) {
            if (head == NULL || head -> next == NULL) {
                return head;
            }
            ListNode * fast = head;
            ListNode * slow = head;
            while (fast -> next != NULL && fast -> next -> next != NULL) {
                slow = slow -> next;
                fast = fast -> next -> next;
            }
            return slow;
        }
        //合并两个有序链表
        ListNode* Merge(ListNode*L, ListNode*R) {
            if (L == NULL) {
                return R;
            }
            if (R == NULL) {
                return L;
            }
            ListNode * head = new ListNode(0);
            ListNode * tail = head;
            tail -> next = NULL;
            while (L != NULL && R != NULL) {
                if (L -> val > R -> val) {
                    tail -> next = R;
                    R = R -> next;
                } else {
                    tail -> next = L;
                    L = L -> next;
                }
                tail = tail -> next;
            }
            if (L == NULL) {
                tail -> next = R;
            }
            if (R == NULL) {
                tail -> next = L;
            }
            return head -> next;
        }
    };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值