日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

归并排序的实现及其优化(递归法)

發布時間:2025/10/17 编程问答 9 豆豆
生活随笔 收集整理的這篇文章主要介紹了 归并排序的实现及其优化(递归法) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

歸并排序

一、思路(遞歸)

list = [a,b,c,d]

1、 遞歸過程

1、數組一分為2,list1 = [a,b] list2 = [c,d]

2、先確立遞歸項:分別對list1/list2做歸并排序,此時可以假設左右子數組已經有序。

3、執行merge子過程,將list1/list2合并并使之有序。

3、在程序首部添加基準條件:當前候選數組長度為1,直接return,停止向下遞歸。

  • 約定

經典的歸并排序,目標數組采用閉區間來標記,即[left,right],各標記定義如下:

數組長度 n=7index 0 1 2 3 4 5 6 value 3 2 5 | 7 1 3 6 標記 left mid right注:n = 7left = 0right = n -1mid = right // 2

2、merge子過程

  • 思路

1、函數傳入整個數組,要merge的子數組區間范圍[left,mid],[mid+1,right]

2、做完整數組的切片 a=list[left,right+1]

3、設定內部指針i遍歷子數組1,j遍歷子數組2
指針k遍歷賦值給完整數組

二、實現

from sort_helper import test_sort,random_arraydef __merge(array, left, mid, right):temp = array[left:right+1]#新數組temp的左中右標記,充當常量n = len(temp)l = 0r = n-1m = l + (r -l) // 2#左數組標記i,右數組標記j,賦值外部循環標記ki = 0j = m + 1#遍歷【0,n)即整個數組長度,每次確定一個下標應該賦值的元素并完成賦值操作k = 0 while k < n:#2、定義判斷條件,防越界;循環的次數是由n確定的,不存在i,j同時越界的情況if i > m:array[k + left] = temp[j]j += 1elif j > r:array[k + left] = temp[i]i += 1#1、判斷兩個子數組當前位置的值,并賦值給原數組array的對應位置,此處可能涉及到越界問題,所以循環主體開始之前要判斷一下elif temp[i] < temp[j]:array[k + left] = temp[i]i += 1else:array[k + left] = temp[j]j += 1k += 1#錯誤示范 def __merge1(array, left, mid, right):#錯誤1,開辟數組空間只針對一部分元素,而非整個數組temp = array[:]#錯誤2,left應該最后賦值為0,否則后兩部相當于減0,無作用#錯誤3:內部端點就應該重新定義為l、r、mid;一旦否則array[k+left]無效果,因為left已變..left = 0mid = mid - leftright = right - leftn = right - left + 1i = 0j = mid + 1k = 0 while k < n:if i > mid:array[k + left] = temp[j]j += 1elif j > right:array[k + left] = temp[i]i += 1elif temp[i] < temp[j]:array[k + left] = temp[i]i += 1else:array[k + left] = temp[j]j += 1k += 1print(array)#該私有函數需要左右下標 def __merge_sort(array, left, right):#3、添加基準條件,左右區間短點,相差1即可,即子數組長度為1if right -left <= 0:return#1、一分為二mid = left + (right -left) // 2 #2、左右分別歸并排序,應該考慮到要添加基準條件了,否則無限遞歸__merge_sort(array, left, mid)__merge_sort(array, mid+1, right)#4、此時,array兩個子數組都已有序,但整個數組卻還無序,需要合并__merge(array, left, mid, right)def merge_sort(array):#作為帶外暴露的歸并排序函數,不需要左右下標__merge_sort(array, 0, len(array)-1)if __name__ == '__main__':array = random_array()test_sort('merge_sort', merge_sort, array)

三、優化

1、提前終止不必要的merge操作
def __merge_sort1(array, left, right):#3、添加基準條件,左右區間短點,相差1即可,即子數組長度為1if right -left <= 0:return#1、一分為二mid = left + (right -left) // 2 #2、左右分別歸并排序,應該考慮到要添加基準條件了,否則無限遞歸__merge_sort1(array, left, mid)__merge_sort1(array, mid+1, right)#4、此時,array兩個子數組都已有序,但整個數組卻還無序,需要合并if array[mid] > array[mid+1]:__merge(array, left, mid, right)def merge_sort1(array):#作為帶外暴露的歸并排序函數,不需要左右下標__merge_sort1(array, 0, len(array)-1)
2、使用插入排序優化
def __merge_sort2(array, left, right):if right -left <= 50:insert_sort(array, left, right)#必須要有return,否則無限遞歸returnmid = left + (right -left) // 2 __merge_sort2(array, left, mid)__merge_sort2(array, mid+1, right)if array[mid] > array[mid+1]:__merge(array, left, mid, right)def merge_sort2(array):__merge_sort2(array, 0, len(array)-1)
3、測試用例
if __name__ == '__main__':array = random_array()array1 = array[:]array2 = array[:]array3 = nearly_ordered_array(10000, 1)array4 = array3[:]array5 = array3[:]test_sort('merge_sort random_array', merge_sort, array)test_sort('merge_sort1 random_array', merge_sort1, array1)test_sort('merge_sort2 random_array', merge_sort2, array2)test_sort('merge_sort nearly_ordered_array', merge_sort, array3)test_sort('merge_sort1 nearly_ordered_array', merge_sort1, array4)test_sort('merge_sort2 nearly_ordered_array', merge_sort2, array5)

優化效果在有序性較強的情況下比較明顯

總結

以上是生活随笔為你收集整理的归并排序的实现及其优化(递归法)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。