二分插入、bisect

在一個有序序列(從小到大)中查找一個元素
每次將元素與序列中間位置的元素進行比較
若是大於中點,則在後半段。若是小於中點,則在前半段。以此類推
時間複雜度爲O(logn)html

有一個無序序列[37, 99, 73, 48, 47, 40, 40, 25, 99, 51],對其先排序輸出新列表。
分別插入20、40、4一、100到這個新序列中合適的位置,保證其有序。python

origin = [37, 99, 73, 48, 47, 40, 40, 25, 99, 51]

origin = sorted(origin)
# print(origin)
# [25, 37, 40, 40, 47, 48, 51, 73, 99, 99]

# 有重複時從左邊插入
def insert_sort(origin:list, num):
    low = 0
    high = len(origin)
    while low < high:
        mid = (low + high)//2
        # 若是大於中點,則在後半部分
        if num > origin[mid]:
            low = mid + 1
        # 不然在前半部分
        else:
            high = mid
    origin.insert(low, num)

for num in (20, 40, 41, 100):
    insert_sort(origin, num)

print(origin)
# [20, 25, 37, 40, 40, 40, 41, 47, 48, 51, 73, 99, 99, 100]
origin = [37, 99, 73, 48, 47, 40, 40, 25, 99, 51]

origin = sorted(origin)

# 有重複時從右邊插入
def insert_sort(origin:list, num):
    low = 0
    high = len(origin)
    while low < high:
        mid = (low + high)//2
        if num < origin[mid]:
            high = mid
        else:
            low = mid + 1
    origin.insert(low, num)

for num in (20, 40, 41, 100):
    insert_sort(origin, num)

print(origin)
# [20, 25, 37, 40, 40, 40, 41, 47, 48, 51, 73, 99, 99, 100]

bisect模塊

bisect包含兩個主要函數 bisect和insort,都是基於二分法實現算法

  • bisect: bisect_right的別名,返回插入點位置,有重複時返回右邊插入點
  • bisect_left: 返回插入點位置,有重複時返回左邊插入點
  • insort: insort_right的別名,默認有重複時從右邊插入
  • insort_left: 有重複時從左邊插入
import bisect

origin = [37, 99, 73, 48, 47, 40, 40, 25, 99, 51]
origin = sorted(origin)

for num in (20, 40, 41, 100):
    bisect.insort_left(origin, num)

print(origin)
# [20, 25, 37, 40, 40, 40, 41, 47, 48, 51, 73, 99, 99, 100]

判斷學生成績,成績等級A-E,其中,90分以上爲A,80~89爲B,70~79爲C,60~69爲D,50~59爲E函數

breakpoints = [60, 70, 80, 90]
grades = 'EDCBA'

index = bisect.bisect(breakpoints, 55)
print(grades[index])
# E

參考:
https://zh.wikipedia.org/wiki/二分搜索算法
https://docs.python.org/3/library/bisect.htmlcode

相關文章
相關標籤/搜索