Python資料結構與演算法_第6節_排序 & 搜尋
Python資料結構與演算法_第6節_排序
排序(sorting algorithm)
歸併排序(merge sorting)
- 歸併排序(merge sorting):是採用分治法的一個非常典型的應用。先遞迴分解陣列,再合併陣列。
- 歸併排序演算法的思路:
- 將陣列分解最小。
- 合併兩個有序陣列,基本思路是比較兩個陣列的最前面的數,誰小就先取誰。
- 取了後相應的指標就往後移一位。然後再比較,直至一個陣列為空,最後把另一個陣列的剩餘部分複製過來即可。
- 重複這個步驟直至合併出來原序列長度的新序列。
歸併排序的分析
用遞迴分解序列至singleton。然後將每對相鄰singleton中大的元素放到合併出來的序列(長度為2)第一位。設定left和right遊標。
把遊標所指的元素中更小的那個放到新合併的序列(長度為4)的第一位。然後把更小的那個元素的遊標(此處為right)往後移動一位。
比較遊標新指向元素的大小,然後把更小的那個放到新合併序列(長度為4)的第二位,重複這個步驟至新序列排列好。
用同樣的方式合成新的序列(長度為8)。
歸併排序的實現
# coding:utf-8
def merge_sort(alist):
"""歸併排序"""
# 先拆分序列
n = len(alist)
# 如果序列拆分至singleton則停止recursion
if n <= 1:
return alist
mid = n // 2
# left採用歸併排序後形成的有序的新的序列
left_li = merge_sort(alist[:mid])
# right採用歸併排序後形成的有序的新的序列
right_li = merge_sort(alist[mid:])
# 將兩個有序的子序列合併為一個新的整體
# merge(left_li, right_li)
left_pointer, right_pointer = 0, 0
result = []
# 每次構建新合併的序列時,把上層序列跑完
while left_pointer < len(left_li) and right_pointer < len(right_li) :
# 小於等於,以此來使該排序演算法穩定(同大小元素,原列表左邊的排在sorted列表的左邊)
if left_li[left_pointer] <= right_li[right_pointer]:
result.append(left_li[left_pointer])
left_pointer += 1
else:
result.append(right_li[right_pointer])
right_pointer += 1
# 把上層序列中剩餘的最後一個元素放到新合併序列中的最後
result += left_li[left_pointer:]
result += right_li[right_pointer:]
return result
時間複雜度
- 最優時間複雜度: O ( n ∗ log n ) O(n*\log n) O(n∗logn)
- 最壞時間複雜度: O ( n ∗ log n ) O(n*\log n) O(n∗logn)
- 穩定性:穩定
常見排序演算法效率比較
- 必須掌握快速排序
- 面試的是時候可能會問列幾個熟知的排序演算法,並且寫出來他們。
搜尋
- 搜尋是在一個專案集合中找到一個特定專案的演算法過程。搜尋通常的答案是真的或假的,因為該專案是否存在。
- 搜尋的幾種常見方法:順序查詢、二分法查詢、二叉樹查詢、雜湊查詢。
二分法查詢(binary searching)
- 二分查詢/折半查詢(binary search):適用於不經常變動而查詢頻繁的有序列表。
- 優點:優點是比較次數少,查詢速度快,平均效能好
- 缺點:要求待查表為有序順序表(不能是連結串列),且插入刪除困難
- 二分法查詢演算法的思路:
- 假設表中元素是按升序排列,將表中間位置記錄的關鍵字與查詢關鍵字比較,如果兩者相等,則查詢成功.
- 否則利用中間位置記錄將表分成前、後兩個子表,如果中間位置記錄的關鍵字大於查詢關鍵字,則進一步查詢前一子表,否則進一步查詢後一子表。
- 重複以上過程,直到找到滿足條件的記錄,使查詢成功,或直到子表不存在為止,此時查詢不成功。
二分查詢實現
# coding:utf-8
def binary_search_recursion(alist, item):
"""二分查詢,遞迴版本"""
n = len(alist)
# 遞迴的終止條件
if n > 0:
mid = n // 2
if alist[mid] == item:
return True
elif item < alist[mid]:
binary_search_recursion(alist[:mid], item)
else:
binary_search_recursion(alist[mid+1:, item])
return False
def binary_search_non_recursion(alist, item):
"""二分查詢,非遞迴版本"""
n = len(alist)
first = 0
last = n-1
while first <= last:
mid = (first + last) //2
if alist[mid] == item:
return True
elif item < alist[mid]:
last = mid - 1
else:
first = mid + 1
return False
時間複雜度
- 最優時間複雜度: O ( 1 ) O(1) O(1)
- 最壞時間複雜度: O ( log n ) O(\log n) O(logn)
相關文章
- 資料結構與演算法 排序與搜尋資料結構演算法排序
- Python資料結構與演算法_第1節_引入概念Python資料結構演算法
- 前端學習 資料結構與演算法 快速入門 系列 —— 排序和搜尋演算法前端資料結構演算法排序
- 搜尋中常見資料結構與演算法探究(二)資料結構演算法
- python演算法與資料結構-快速排序(36)Python演算法資料結構排序
- 演算法與資料結構之二分搜尋樹演算法資料結構
- 資料結構與演算法——排序資料結構演算法排序
- python演算法與資料結構-希爾排序(35)Python演算法資料結構排序
- python演算法與資料結構-氣泡排序(32)Python演算法資料結構排序
- python演算法與資料結構-插入排序(34)Python演算法資料結構排序
- 【資料結構】搜尋樹資料結構
- 資料結構與演算法(八):排序資料結構演算法排序
- 資料結構與演算法之排序資料結構演算法排序
- 資料結構與演算法:堆排序資料結構演算法排序
- 【資料結構與演算法】堆排序資料結構演算法排序
- 資料結構與演算法——堆排序資料結構演算法排序
- 資料結構與演算法----# 一、排序資料結構演算法排序
- [資料結構與演算法] 排序演算法資料結構演算法排序
- 資料結構與演算法——排序演算法-歸併排序資料結構演算法排序
- 資料結構與演算法——排序演算法-基數排序資料結構演算法排序
- 資料結構與演算法——排序演算法-氣泡排序資料結構演算法排序
- 資料結構與演算法——排序演算法-選擇排序資料結構演算法排序
- 《JavaScript資料結構與演算法》筆記——第6章 集合JavaScript資料結構演算法筆記
- 演算法與資料結構——AVL樹(平衡二叉搜尋樹)演算法資料結構
- 資料結構與演算法 基礎排序資料結構演算法排序
- 資料結構與演算法 進階排序資料結構演算法排序
- Java資料結構與排序演算法 (三)Java資料結構排序演算法
- Java資料結構與排序演算法 (一)Java資料結構排序演算法
- Java資料結構與排序演算法 (二)Java資料結構排序演算法
- 資料結構與演算法-反轉排序資料結構演算法排序
- 【資料結構與演算法】歸併排序資料結構演算法排序
- 資料結構與演算法之快速排序資料結構演算法排序
- 資料結構第10章 排序資料結構排序
- 資料結構與演算法整理總結---排序 2資料結構演算法排序
- 資料結構與排序資料結構排序
- python資料結構與演算法Python資料結構演算法
- 資料結構與演算法——十個排序演算法資料結構演算法排序
- 【演算法與資料結構】經典排序演算法總結演算法資料結構排序