0.數據結構(python語言) 基本概念 算法的代價及度量!!!
先看思維導圖:
*思維導圖有點簡陋,本著循循漸進的思想,這小節的知識大多只做了解即可。
*重點在於算法的代價及度量!!!查找資料務必弄清楚.
零.四個基本概念
- 問題:一個具體的需求
- 問題實例:針對問題(需求)的具體的例子
- 算法:解決問題的過程,是對一個計算過程的嚴格描述
- 程序:程序可以看作是采用計算裝置能夠處理的語言描述的算法
一.算法的5大性質
- 有窮性(算法描述的又窮性):算法必須用有限長的描述說清楚
- 能行性:算法的每一步都是可行的,也就是說,每一步都能通過執行有限次數完成
- 確定性:別人看了過後,很清楚的明白,不會有歧義
- 終止性(行為的有窮性):指算法在執行有限的步驟後,自動結束而不會出現無限循環,並且每一個步驟在可接受的時間內完成
- 輸入/輸出:算法具有零個(print("Hello World"))或多個輸入(輸入參數);算法至少有一個或多個輸出
二.算法的描述(最常用的兩種)
- 類似編程語言的形式:用類似編程語言的形式描述算法的過程,其中參雜使用一些數學符號和記號,用於描述算法中一些細節和具體操作
- 偽代碼:類似於前一方式
三.算法的設計模式
*知道有這六種即可,我也沒深入了解具體是什麽怎麽實現的,知道有這幾種就行,遇到了再掌握吧!
*算法一般是多種模式的有機結合
四.算法的代價及度量
*首先明確,對於算法的研究,人們主要關註算法的最壞情況代價
1.時間代價(時間復雜度)
- 測定運行時間最可靠的方法就是計算對運行時間有消耗的基本操作的執行次數
舉個栗子:對於同一個問題,算法A要做 2n+3 次操作、算法B要做 3n+1 次操作、算法c要做 2n^2+1 次操作,哪個算法好???
答:很明顯隨著n的增長(N趨近於無窮大),總體來說 A<B<C
- 會用到"大O記法"(針對不同階的表達式),定義什麽的太麻煩了,直接簡單的寫步驟:
(要知道對於不同階的表達式(比如 線性階3n+10 平方階2n^2 2n^2+3n+1) 隨著n的增長(趨近於無窮大),第二種算法趨近於第三種算法,而第1種算法遠小於其余兩種算法)
(因而得出結論 對於不同階的表達式的比較 算法執行次數表達式的常數項和與最高次數相乘的常數乃至於次要項都不能起決定作用)
第一步:用常數1取代運行時間中的所有加法常數
第二步:再修改後的運算次數函數中,只保留最高階項
第三步:如果最高階項存在且不是1,則去除與這個項相乘的常數
- 下面列出常見的時間復雜度
執行次數函數舉例 階 非正式術語 12 O(1) 常數階 2n+3 O(n) 線性階 3n2+2n+1 O(n2) 平方階 5log2n+20 O(logn) 對數階 2n+3nlog2n+19 O(nlogn) nlogn階 6n3+2n2+3n+4 O(n3) 立方階 2n O(2n) 指數階
#註意,經常將log2n(以2為底的對數)簡寫成logn!!
所消耗的時間從小到大
O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3) < O(2n) < O(n!) < O(nn)
我們舉個栗子,推導下對數階
count = 1 while count < n: count = count * 2 # 這行代碼時間復雜度為O(1)
問:上述代碼的時間復雜度為多少?
答:由於每次count*2後就會更接近於n,所以我們就要算 有多少個2相乘後大於n,使其退出循環。由2^x = n得到 x = logn.這個循環的時間復雜度為O(logn)
- 由於python程序是算法的實現,所以不得不考慮python程序的計算代價
*有點懵 看不明白也沒關系,我也看不明白,等學完用python語言程序實現後就自然而言明白了。
2.空間代價(空間復雜度)
*時間復雜度指運行時間的需求,空間復雜度指空間需求。現目前,不必考慮。所以不準備怎麽了解,先放放。
五.數據結構及分類
1.組成
- 數據:是描述客觀事物的符號,是計算機可以操作的對象,是能被計算機識別並輸出給計算機處理的符號集合
- 數據對象:是性質相同的數據元素的集合,在不混淆的情況下,數據=數據對象
- 數據元素:是組成數據的一定意義的基本單位,在計算機中通常作為整體處理
- 數據項:是數據不可分割的最小單位,一個數據元素可以由若幹個數據項組成
數據結構:是相互之間存在一種或者多種特定關系的數據元素的集合.由邏輯結構和物理結構.
2.邏輯結構
*邏輯結構是指數據對象中數據元素之間的相互關系
*邏輯結構包括:集合結構、序列結構(一對一)、層次結構、樹形結構(一對多)、圖結構(多對多)
3.物理結構
*物理結構是指數據的邏輯結構在計算機中的存儲形式
- 順序存儲結構:把數據元素存放在地址連續的存儲單元裏
- 鏈式存儲結構:把數據元素存放在任意的存儲單元裏,這組存儲單元可以是連續的,也可以是不連續的
*那麽我們不得不討論下計算機內存對象的表示,以及python變量的引用語義
- 計算機內存對象表示
#內存是CPU可以直接訪問的存儲設備,與其對應的是外存(磁盤、光盤、磁帶等)
#內存的基本結構是線性排列的一批存儲單元(存儲單元具有唯一的編號,稱為單元地址或簡稱地址)。每個單元的大小相同,可以保存一個單位大小的數據.
舉個例子:目前常見的64位操作系統,一次可以讀取8個單元的數據,現在由一個float64的數據,我們可以得知float64 = 8字節 = 8個單元 = 64位二進制數
#當一個對象不再使用的時候,存儲管理系統會設法回收其占用的存儲,以便於用於存儲其它對象
#對於一個組合對象,其中包含了一組元素,這些元素被安排到了一組連續的存儲單元裏,我們現在知道其起始地址位P,每個元素的大小相等為a,那麽我們可以得知第K個元素的地址 loc(k) = p + k*a;
#還有一種情況,每個元素的大小不相等,那麽我們就可以計算這類對象裏的各個元素相對於起始地址的相對位置,稱為元素的存儲偏移量
- python變量的引用語義
#python語言是引用語義,C語言是值語義。簡單來說,有一個值3.1415存儲在內存的中,地址為p,那麽 a = 3.1415,a變量裏保存的是p,同樣的我們再把3.1415賦值給b,b變量裏保存的同樣是p,a和b的同時指向了3.1415這一數據所在的地址,即a和b變量的存儲區裏保存的都是p。而C語言是吧變量的值直接保存在變量的存儲區裏。
0.數據結構(python語言) 基本概念 算法的代價及度量!!!