链表归并排序

//Definition for singly-linked list.
struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x = 0) : val(x), next(NULL) {}
};
class Solution {
public:
    ListNode *sortList(ListNode *head) {
        return merge_sort(head);
    }
    //典型归并,先分割,后归并
    ListNode *merge_sort(ListNode *head) {
        if (head == NULL || (head != NULL && head->next == NULL))
            return head;
        ListNode *first = NULL;
        ListNode *second = NULL;
        first = seperate_list(head);
        second = head;
        first = merge_sort(first);
        second = merge_sort(second);
        return merge(first, second);
    }

    //从中间位置分割链表
    ListNode *seperate_list(ListNode *head) {
        int iNum = 0; //节点的数目
        ListNode *pTemp = head;
        // 统计个数
        while(pTemp != NULL) {
            ++iNum;
            pTemp = pTemp->next;
        }

        int iMiddle = iNum / 2;//中间位置
        ListNode *pMiddle = head;
        pTemp = pMiddle;
        for (int i = 1; i <= iMiddle; ++i)
        {
            pTemp = pMiddle;
            pMiddle = pMiddle->next;
        }
        pTemp->next = NULL;
        return pMiddle;
        /**
        这个地方还可以根据快慢指针来找中间位置
        p指针一次性走2个位置,mid一次走一个位置
        这种方法也可以用来判断一个链表中有没有环(如果有环,一次一个位置和一次两个位置最终会相遇)
        while (p != NULL && p->next != NULL) {
            p = p->next->next;
            midl = mid;
            mid = mid->next;
        }
        */
    }

    // 两个有序链表的合并
    ListNode *merge(ListNode *first, ListNode *second) {
        ListNode *head = new ListNode(0);//增加一个表头,便于连接
        ListNode *index = head;
        while(first != NULL && second != NULL) {
            if (first->val < second->val) {
                head->next = first;
                first = first->next;
            }
            else {
                head->next = second;
                second = second->next;
            }
            head = head->next;
            head->next = NULL;
            if (first == NULL)
            {
                head->next = second;
            }
            if (second == NULL)
            {
                head->next = first;
            }
        }
        head = index->next;
        delete index;
        index = NULL;
        return head;
    }
};


你可能感兴趣的:(链表归并排序)