二分法排序-Python實現


有一個無序序列[37,99,73,48,47,40,40,25,99,51],先進行排序打印輸出,分別嘗試插入20/40/41 數值到序列中合適的位置,保證其有序。

1、for 循環實現

第一種實現,利用嵌套for循環,每次迭代出來的數值進行比較。如果比原表中的數值小,則插入到這個數左面。

 

 

 

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

for x in (20,40,41,100):
    i = 0
    for i,v in enumerate(lst):
        if v > x:
            break
    lst.insert(i,x)
print(lst)

2、利用二分法實現

排序后二分查找到適當位置插入數值。

排序使用sorted解決,假設升序輸出。

查找插入點,使用二分查找完成。

假設全長為n,首先在大致的中點元素開始和待插入的數進行比較,如果大則和右邊的區域的中點元素進行比較,如果小則和左邊的區域的中點進行比較,以此類推。

 

 

lst = [37, 99, 73, 48, 47, 40, 40, 25, 99, 51]
lst1 = sorted(lst)
def lst_insert(lst1,i):
    ret = lst1
    # print(ret)
    length = len(lst1)
    low = 0
    while low < length:
        mid = length // 2
        if ret[mid] < i:
            low = mid + 1       #說明i大,右邊,限制下限。
        else:
            length = mid      #說明i不大於,左邊,限制上限。
    ret.insert(low,i)
    print(ret)
for x in (40,20,21):
    lst_insert(lst1,x)

 

 

算法的核心就是折半至重合為止。

 

 

3、二分

1)二分的前提是有序,否則不允許。

2)二分的查找算法的時間復雜度是O(log n)

4、Bisect模塊

提供的函數有:

bisect.bisect_left(a,x,lo=0,hi=len(a)):

查找在有序列表a中插入x的index。Lo和hi用於指定列表的區間,默認是使用整個列表,如果x已經存在,在其左邊插入,返回值為index。

 

bisect.bisect_right(a,x,lo= 0,hi=len(a))或者bisect.bisect(a,x,lo= 0,hi=len(a))

和bisect_left類似,但如果x已經存在,則在其右邊插入。

 

bisect.insort_left(a,x,lo= 0,hi=len(a))

在有序列表a中插入x,等同於a.insert(bisect.bisect_left(a,x,lo,hi),x).

 

bisect.insort_right(a,x,lo= 0,hi=len(a))或者bisect.insort(a,x,lo= 0,hi=len(a))和insort_left函數類似,但是如果x如果已經存在,在其右邊插入。

 

 

函數可以分為兩類:

Bisect系,用於查找index。

Insort系,用於實際插入。

默認重復時候從右邊插入。

 

import bisect


lst = [37, 99, 73, 48, 47, 40, 40, 25, 99, 51]
lst1 = sorted(lst)
print(lst1)  #[25, 37, 40, 40, 47, 48, 51, 73, 99, 99]
print(20,bisect.bisect(lst1,20))    #20 0
print(30,bisect.bisect(lst1,30))    #30 1
print(40,bisect.bisect(lst1,40))    # 40 4
print(100,bisect.bisect(lst1,100))    #  100 10

print(20,bisect.bisect_left(lst1,20))   #20 0
print(30,bisect.bisect_left(lst1,30))   #30 1
print(40,bisect.bisect_left(lst1,40))   #40 2
print(100,bisect.bisect_left(lst1,100))   # 100 10

for x in (20,30,40,100):
    bisect.insort_left(lst1,x)
    print(lst1)
    # [20, 25, 37, 40, 40, 47, 48, 51, 73, 99, 99]
    # [20, 25, 30, 37, 40, 40, 47, 48, 51, 73, 99, 99]
    # [20, 25, 30, 37, 40, 40, 40, 47, 48, 51, 73, 99, 99]
    # [20, 25, 30, 37, 40, 40, 40, 47, 48, 51, 73, 99, 99, 100]

 

5、二分應用

判斷學習成績,成績等級A-E  。90分以上為A ,80 以上為B  ,70以上為C  60以上為D。60以下為D。

 


def insert_score(nums):
    lst = [60, 70, 80, 90]
    grades = "EDCBA"
    index = bisect.bisect(lst,nums)
    print(index)
    print(grades[index])
insert_score(70)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM