排序 6 歸併排序

2021-08-09 03:55:49 字數 1933 閱讀 6838

參考:

排序 0 - 前言

將序列分為若干個子串行(子串行均有序),兩兩子串行進行歸併操作,得到乙個新的有序列表,最終歸併所有子串行,得到乙個遞增或遞減的序列

從左到右逐個比較兩個子串行中的元素大小,比如進行遞增排序,將較小的元素加入結果序列中,其下標加1,繼續和另乙個序列元素進行比較,直到某乙個序列元素已經全部遍歷為止,將另乙個序列的剩餘元素加入到結果序列中,操作完成

對於無序列表,無法確切得知哪個子串行是有序的,可以將單個元素設為乙個子串行,從而兩兩進行歸併操作

歸併排序通常採用遞迴演算法,每次都將序列均分為兩個子串行,直到序列數為1,將兩個子串行進行歸併操作後返回

# -*- coding: utf-8 -*-

"""歸併排序

"""import random

__author__ = 'zj'

def create_data(leng, min, max):

"""建立待排序序列

:param leng: 序列長度

:param min: 最小值

:param max: 最大值

:return: 列表

"""li = range(min, max)

return random.sample(li, leng)

def merge_sort(li, reverse=false):

"""歸併排序實現

:param li: 待排序列表

:param reverse: 是否從大到小排序,預設為false

:return: 已排序列表

"""if len(li) == 1:

return li

m = len(li) // 2

l = merge_sort(li[:m], reverse)

r = merge_sort(li[m:], reverse)

return merge_operation(l, r, reverse)

def merge_operation(llist, rlist, reverse=false):

"""歸併操作實現

:param llist: 左側已排序序列

:param rlist: 右側已排序序列

:param reverse: 是否從大到小排序,預設為false

:return: 乙個已排序序列

"""llen = len(llist)

rlen = len(rlist)

i = j = 0

res =

while i < llen and j < rlen:

if llist[i] <= rlist[j]:

if reverse:

j += 1

else:

i += 1

else:

if reverse:

i += 1

else:

j += 1

res.extend(llist[i:])

res.extend(rlist[j:])

return res

if __name__ == '__main__':

da = create_data(10, 30, 60)

print da

res = merge_sort(da, true)

print res

歸併排序是穩定排序演算法

其歸併操作是發生在相鄰兩個子串行中,遇到相同大小的元素時,也是左側的元素先加入結果序列中

最好,最壞,平均時間複雜度均為o(nlogn)

每次歸併操作均需要使用n個大小的輔助空間,所以空間複雜度為o(n)

6 歸併排序

歸併排序是歸併兩個有序的序列,這兩個有序序列需要頭尾兩個指標,遍歷這兩個序列,按照排序規則儲存在乙個可以容納這兩個序列的序列中,當遍歷結束,則新的序列為有序序列。當我們需要對某一串行排序時,可以把該序列分成兩半,分別對這兩半進行排序,然後歸併這兩個有序序列。而這兩半又可以遞迴地分半,類似二分法。in...

6 歸併排序

歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法 divide and conquer 的乙個非常典型的應用。nlogn 由於需要兩兩比較 因此也是穩定的!首先考慮下如何將將二個有序數列合併。這個非常簡單,只要從比較二個數列的第乙個數,誰小就先取誰,取了後就在對應數列中刪除這個...

排序演算法6 歸併排序

1.什麼是歸併排序 歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法 divide and conquer 的乙個非常典型的應用。將已有序的子 序列合併,得到完全有序的序列 即先使每個子串行有序,再使子串行段間有序。若將兩個有序表合併成乙個有序表,稱為2 路歸併。2.演算法步驟...