算法基礎——列表查找


what's the 算法

  算法(Algorithm)是指解題方案的准確而完整的描述,是一系列解決問題的清晰指令,算法代表着用系統的方法描述解決問題的策略機制。也就是說,能夠對一定規范的輸入,在有限時間內獲得所要求的輸出。如果一個算法有缺陷,或不適合於某個問題,執行這個算法將不會解決這個問題。不同的算法可能用不同的時間、空間或效率來完成同樣的任務。一個算法的優劣可以用 空間復雜度時間復雜度來衡量。
  算法中的指令描述的是一個計算,當其運行時能從一個初始狀態和(可能為空的)初始輸入開始,經過一系列有限而清晰定義的狀態,最終產生輸出並停止於一個終態。一個狀態到另一個狀態的轉移不一定是確定的。隨機化算法在內的一些算法,包含了一些隨機輸入。

 

時間復雜度

  時間復雜度用於評估算法運行效率。

  在計算機科學中,算法的時間復雜度是一個函數,它定性描述了該算法的運行時間。這是一個關於代表算法輸入值的字符串的長度的函數。時間復雜度常用大O符號表述,不包括這個函數的低階項和首項系數。通常寫法為O(n)

舉例說明:

print('Hello World')               #O(1)  只執行一次


for i in range(n):    
    print('Hello World')           #O(n)   執行了n次
 
for i in range(n):    
    for j in range(n):        
        print('Hello World')       #O(n**2)   執行了n*n次
    
for i in range(n):    
    for j in range(n):        
        for k in range(n):            
            print('Hello World')   #O(n**3)   執行了n*n*n次

while n > 1:    
    print(n)    
        n = n // 2
"""
n=64時輸出:

64
32
16
8
4
2   所以我們發現這個執行的次數是2的冪次方,O(log2 n)簡寫為O(logn)
"""

注意:時間復雜度沒有O(3)、O(1/2n)、O(n^2+n)的說法,因為時間復雜度只是一個用於衡量的估算值,所以上述改寫為O(1)、O(n)、O(n^2)即可

  一般來說,時間復雜度高的算法比時間復雜度低的算法效率要慢,常見的時間復雜度按效率排序為

O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^2*logn) < O(n^3)

  當然還有一些不常用的時間復雜度——O(n!) O(2^n) O(n^n) …這些都不重要

 

空間復雜度 

  空間復雜度(Space Complexity)用來評估算法內存占用大小的一個式子。

  空間復雜度是對一個算法在運行過程中臨時占用存儲空間大小的量度,記做S(n)=O(f(n))。比如直接插入排序的時間復雜度是O(n^2),空間復雜度是O(1) 。而一般的遞歸算法就要有O(n)的空間復雜度了,因為每次遞歸都要存儲返回信息。一個算法的優劣主要從算法的執行時間和所需要占用的存儲空間兩個方面衡量。

   一般小程序的情況下,我們通常會稍微犧牲點內存來加快效率,即我們會用空間換時間,所以我們會適當提高空間復雜度以減少時間復雜度。

 

列表查找

算法最基本的應用就是對列表的查找與排序,這里我們說一下列表查找。

列表查找就是針對一個列表中待查找的元素,輸出該元素的索引值index,如果該列表中不含有目標值則輸出None

列表查找的方式有兩種——順序查找二分查找

    • 順序查找:從列表第一個元素開始,順序進行搜索,直到找到為止。
    • 二分查找:從有序列表的候選區data[0:n]開始,通過對待查找的值與候選區中間值的比較,可以使候選區減少一半。

li=[1,2,3,4,5,6,7,8,9,10]

#順序查找
def linear_search(data_set, value):
    for i in data_set:
        if data_set[i] == value:
            return i
    return

the_index=linear_search(li,3)
print(the_index)#2     O(n)

#二分查找
def bin_search(data_set, value):
    low = 0
    high = len(data_set) - 1
    while low <= high:
        mid = (low+high)//2
        if data_set[mid] == value:
            return mid
        elif data_set[mid] > value:
            high = mid - 1
        else:
            low = mid + 1

bin_index=bin_search(li,3)
print(bin_index)#2    O(logn)       可以發現二分查找比順序查找要更快

二分法可使用遞歸完善:

def bin_search_rec(data_set,value,low,high):
    if low <= high:
        mid=(low+high) // 2
        if data_set[mid] == value:
            return mid
        elif data_set[mid] > value:
            return bin_search_rec(data_set,value,low,mid-1)
        else:
            return bin_search_rec(data_set,value,mid+1,high)
    else:return None

li=[1,2,3,4,5,6,7,8,9,10]
a=bin_search_rec(li,3,1,10)
print(a)#2
使用遞歸的二分法

 


 

列表查找小練習:

  現有一個學員信息列表(按id增序排列),格式為:

    [ {id:1001, name:"張三", age:20}, {id:1002, name:"李四", age:25}, {id:1004, name:"王五", age:23}, {id:1007, name:"趙六", age:33} ]

  修改二分查找代碼,輸入學生id,輸出該學生在列表中的下標,並輸出完整學生信息。

 

列表排序

列表排序即將無需列表變為有序,Python的內置函數為sort()。應用的場景主要有:各種榜單、各種表格、給二分查找用、 其他算法用等等。

有關列表排序的算法有很多,主要分為:

  • low B三人組: 冒泡排序、 選擇排序、 插入排序
  • NB三人組: 快速排序、 堆排序、 歸並排序

  • 其他排序算法: 基數排序、 希爾排序、 桶排序

有關列表排序算法博客鏈接地址:http://www.cnblogs.com/zhuminghui/p/8401129.html

 

 

 

                                    

 


免責聲明!

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



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