算法基礎:定義-時間複雜度-列表查找

1.算法定義 

 

算法(Algorithm)是指解題方案的準確而完整的描述,是一系列解決問題的清晰指令,算法表明着用系統的方法描述解決問題的策略機制。也就是說,可以對必定規範的輸入,在有限時間內得到所要求的輸出。若是一個算法有缺陷,或不適合於某個問題,執行這個算法將不會解決這個問題。不一樣的算法可能用不一樣的時間、空間或效率來完成一樣的任務。一個算法的優劣能夠用空間複雜度與時間複雜度來衡量。python

一個算法應該具備如下七個重要的特徵:算法

①有窮性(Finiteness):算法的有窮性是指算法必須能在執行有限個步驟以後終止;app

②確切性(Definiteness):算法的每一步驟必須有確切的定義;dom

③輸入項(Input):一個算法有0個或多個輸入,以刻畫運算對象的初始狀況,所謂0個輸     入是指算法自己定出了初始條件;函數

④輸出項(Output):一個算法有一個或多個輸出,以反映對輸入數據加工後的結果。沒       有輸出的算法是毫無心義的;測試

⑤可行性(Effectiveness):算法中執行的任何計算步驟都是能夠被分解爲基本的可執行       的操做步,即每一個計算步均可以在有限時間內完成(也稱之爲有效性);spa

⑥高效性(High efficiency):執行速度快,佔用資源少;code

⑦健壯性(Robustness):對數據響應正確。對象

二、複習遞歸

看下面四個函數,那個是正常的遞歸

def func1(x):
    print(x)
    func1(x-1)

沒有結束,會跑死 def func2(x): if x > 0: print(x) func2(x+1)
遞歸是愈來愈小,而這個是愈來愈大,也會跑死
def func3(x): if x > 0: print(x) func3(x-1)

第三個能夠 def func4(x): if x > 0: func4(x - 1) print(x)

第四個也能夠

函數3和函數4的區別

def func4(x):
    if x > 0:
        func4(x - 1)
        print(x)
func4(5)

"D:\Program Files\Python35\python3.exe" D:/python13/day32/1.py
1
2
3
4
5

Process finished with exit code 0

def func3(x):
    if x > 0:
        print(x)
        func3(x-1)
func3(5)

"D:\Program Files\Python35\python3.exe" D:/python13/day32/1.py
5
4
3
2
1

Process finished with exit code 0

3. 時間複雜度

計算機科學中,算法的時間複雜度是一個函數,它定量描述了該算法的運行時間,時間複雜度經常使用大O符號(大O符號(Big O notation)是用於描述函數漸進行爲的數學符號。更確切地說,它是用另外一個(一般更簡單的)函數來描述一個函數數量級的漸近上界。在數學中,它通常用來刻畫被截斷的無窮級數尤爲是漸近級數的剩餘項;在計算機科學中,它在分析算法複雜性的方面很是有用。)表述,使用這種方式時,時間複雜度可被稱爲是漸近的,它考察當輸入值大小趨近無窮時的狀況。blog

大O,簡而言之能夠認爲它的含義是「order of」(大約是)

無窮大漸近
大O符號在分析算法效率的時候很是有用。舉個例子,解決一個規模爲 n 的問題所花費的時間(或者所需步驟的數目)能夠被求得:T(n) = 4n^2 - 2n + 2。
當 n 增大時,n^2; 項將開始占主導地位,而其餘各項能夠被忽略——舉例說明:當 n = 500,4n^2; 項是 2n 項的1000倍大,所以在大多數場合下,省略後者對錶達式的值的影響將是能夠忽略不計的。

計算方法:

1.一個算法執行所耗費的時間:


從理論上是不能算出來的,必須上機運行測試才能知道。但咱們不可能也沒有必要對每一個算法都上機測試,只需知道哪一個算法花費的時間多,哪一個算法花費的時間少就能夠了。而且一個算法花費的時間與算法中語句的執行次數成正比例,哪一個算法中語句執行次數多,它花費時間就多。

一個算法中的語句執行次數稱爲語句頻度或時間頻度。記爲T(n)。

2.通常狀況下:


算法的基本操做重複執行的次數是模塊n的某一個函數f(n),所以,算法的時間複雜度記作:T(n)=O(f(n))。隨着模塊n的增大,算法執行的時間的增加率和f(n)的增加率成正比,因此f(n)越小,算法的時間複雜度越低,算法的效率越高。

在計算時間複雜度的時候,先找出算法的基本操做,而後根據相應的各語句肯定它的執行次數,再找出T(n)的同數量級(它的同數量級有如下:1,Log2n ,n ,nLog2n ,n的平方,n的三次方,2的n次方,n!),找出後,f(n)=該數量級,若T(n)/f(n)求極限可獲得一常數c,則時間複雜度T(n)=O(f(n))。

3.常見的時間複雜度

按數量級遞增排列,常見的時間複雜度有:
常數階O(1),  對數階O(log2n),  線性階O(n),  線性對數階O(nlog2n),  平方階O(n^2), 立方階O(n^3),..., k次方階O(n^k), 指數階O(2^n) 。
其中,
1.O(n),O(n^2), 立方階O(n^3),..., k次方階O(n^k) 爲多項式階時間複雜度,分別稱爲一階時間複雜度,二階時間複雜度。。。。
2.O(2^n),指數階時間複雜度,該種不實用
3.對數階O(log2n),   線性對數階O(nlog2n),除了常數階之外,該種效率最高
例:算法:
for(i=1;i<=n;++i)
  {
     for(j=1;j<=n;++j)
     {
         c[ i ][ j ]=0; //該步驟屬於基本操做 執行次數:n^2
          for(k=1;k<=n;++k)
               c[ i ][ j ]+=a[ i ][ k ]*b[ k ][ j ]; //該步驟屬於基本操做 執行次數:n^3
     }
  }
則有 T(n)= n^2+n^3,根據上面括號裏的同數量級,咱們能夠肯定 n^3爲T(n)的同數量級
  則有f(n)= n^3,而後根據T(n)/f(n)求極限可獲得常數c
  則該算法的 時間複雜度:T(n)=O(n^3)

 n和logn那個快?

 

時間複雜度小結:

 空間複雜度

 時間複雜度佔用的是時間,空間複雜度佔用的是內存

列表查找

概述

二分查找

 

 爲何二分查找快?是由於有序,每次把空間縮小一半

def bin_search(data_set, val):
    low = 0
    high = len(data_set) - 1
    while low <= high:
        mid = (low+high)//2
        if data_set[mid] == val:
            return mid
        elif data_set[mid] < val:
            low = mid + 1
        else:
            high = mid - 1
    return

alex的二分查找

def binary_search(dataset, find_num):
    if len(dataset) > 1:
        mid = int(len(dataset) / 2)
        if dataset[mid] == find_num:
            #print("Find it")
            return dataset[mid]
        elif dataset[mid] > find_num:
            return binary_search(dataset[0:mid], find_num)
        else:
            return binary_search(dataset[mid + 1:], find_num)
    else:
        if dataset[0] == find_num:
            #print("Find it")
            return dataset[0]
        else:
            pass
            #print("Cannot find it.")

兩個比較

import time
import random

def cal_time(func):
    def wrapper(*args, **kwargs):
        t1 = time.time()
        result = func(*args, **kwargs)
        t2 = time.time()
        print("%s running time: %s secs." % (func.__name__, t2 - t1))
        return result
    return wrapper

@cal_time
def bin_search(data_set, val):
    low = 0
    high = len(data_set) - 1
    while low <= high:
        mid = (low+high)//2
        if data_set[mid] == val:
            return mid
        elif data_set[mid] < val:
            low = mid + 1
        else:
            high = mid - 1
    return


def binary_search(dataset, find_num):
    if len(dataset) > 1:
        mid = int(len(dataset) / 2)
        if dataset[mid] == find_num:
            #print("Find it")
            return dataset[mid]
        elif dataset[mid] > find_num:
            return binary_search(dataset[0:mid], find_num)
        else:
            return binary_search(dataset[mid + 1:], find_num)
    else:
        if dataset[0] == find_num:
            #print("Find it")
            return dataset[0]
        else:
            pass
            #print("Cannot find it.")

@cal_time
def binary_search_alex(data_set, val):
    return binary_search(data_set, val)


def random_list(n):
    result = []
    ids = list(range(1001,1001+n))
    a1 = ['zhao','qian','sun','li']
    a2 = ['li','hao','','']
    a3 = ['qiang','guo']
    for i in range(n):
        age = random.randint(18,60)
        id = ids[i]
        name = random.choice(a1)+random.choice(a2)+random.choice(a3)

data = list(range(100000000))

print(bin_search(data, 173320))
print(binary_search_alex(data, 173320))

 打印結果以下:

"D:\Program Files\Python35\python3.exe" D:/python13/day32/2.py
bin_search running time: 0.0 secs.
173320
binary_search_alex running time: 2.128999948501587 secs.
173320

Process finished with exit code 0

 慢主要是慢在切片上,由於切片是很是消耗時間的 ,由於要複製一份

列表排序總結:

 

 

相關文章
相關標籤/搜索