每日一道算法題--leetcode 148--鏈表排序(歸併排序)--python

【題目描述】算法

【代碼思路】

對鏈表進行排序,方法不少,因爲要求時間複雜度是O(nlogn)空間複雜度是常量級別,因此咱們須要在衆多排序中作選擇,知足這個時間複雜度的排序算法有快速排序,堆排序,希爾排序和歸併排序。因爲快排在最壞狀況下的時間複雜度是O(n*n)因此不知足,考慮到是鏈表,不能用數字來指示位置了,所以咱們選擇歸併排序。bash

歸併排序就是不斷找到當前鏈表的中點,把他拆分紅兩部分,再對這兩部分不斷拆分,直至每段只剩下兩個值爲止,對這兩個值進行排序,而後不斷返回上層排序。說白了就是先兩個兩個比,而後四個四個比,而後8個8個比,最後把整個鏈表排序完畢。函數

先寫一個鏈表找中點的函數,用快慢指針的辦法,快指針和慢指針都從頭部開始,慢指針一次走一步,快指針一次走兩步,當快指針走到他的next的next是空,就停下,此時慢指針走到的位置就是中間部位。返回值是中間指針。ui

def getmid(self,head):#鏈表快慢指針找中點
       slow=fast=head
       if head is None :return slow
       while fast.next and fast.next.next:
           slow=slow.next
           fast=fast.next.next
       return slow
複製代碼

再寫一個排序函數,對兩個鏈表進行排序,以後再返回排序以後的頭指針spa

def merge(self,l,r):
       a=ListNode(0)
       q=a
       while l and r:
           if l.val>r.val:
               q.next=r
               r=r.next
           else:
               q.next=l
               l=l.next
           q=q.next
       if l:
           q.next=l
       if r:
           q.next=r
       return a.next
複製代碼

在主函數中,遞歸調用自身,主函數執行的邏輯是找中間指針,而後將這個鏈表短成兩段,並用l表示前一段的頭指針,r表示後一段的頭指針,指針

def sortList(self, head):
       """ :type head: ListNode :rtype: ListNode """
       if head is None or head.next is None:return head
       mid=self.getmid(head)
       l=head
       r=mid.next
       mid.next=None
       return self.merge(self.sortList(l),self.sortList(r))
複製代碼

【源代碼】 歸併排序code

# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None

class Solution(object):
    def sortList(self, head):
        """ :type head: ListNode :rtype: ListNode """
        if head is None or head.next is None:return head
        mid=self.getmid(head)
        l=head
        r=mid.next
        mid.next=None
        return self.merge(self.sortList(l),self.sortList(r))
    def getmid(self,head):#鏈表快慢指針找中點
        slow=fast=head
        if head is None :return slow
        while fast.next and fast.next.next:
            slow=slow.next
            fast=fast.next.next
        return slow
    def merge(self,l,r):
        a=ListNode(0)
        q=a
        while l and r:
            if l.val>r.val:
                q.next=r
                r=r.next
            else:
                q.next=l
                l=l.next
            q=q.next
        if l:
            q.next=l
        if r:
            q.next=r
        return a.next
複製代碼
相關文章
相關標籤/搜索