例項:二分法查詢。
1.1.1 二分法定義
二分查詢也稱折半查詢(binary search),它是一種效率較高的查詢方法。但是,折半查詢要求線性表必須採用順序儲存結構,而且表中元素按關鍵字有序排列。
1.1.2 查詢過程
首先,假設表中元素是按公升序排列,將表中間位置記錄的關鍵字與查詢關鍵字比較,如果兩者相等,則查詢成功;否則利用中間位置記錄將表分成前、後兩個子表,如果中間位置記錄的關鍵字大於查詢關鍵字,則進一步查詢前一子表,否則進一步查詢後一子表。重複以上過程,直到找到滿足條件的記錄,使查詢成功,或直到子表不存在為止,此時查詢不成功。
1.1.3 **
python**:
def
bin_search
(data_list, val)
:
low =
0# 最小數下標
high =
len(data_list)-1
# 最大數下標
while low <= high:
mid =
(low + high)//2
# 中間數下標
if data_list[mid]
== val:
# 如果中間數下標等於val, 返回
return mid
elif data_list[mid]
> val:
# 如果val在中間數左邊, 移動high下標
high = mid -
1else
:# 如果val在中間數右邊, 移動low下標
low = mid +
1return
# val不存在, 返回none
ret = bin_search(
list
(range(1
,10))
,3)print
(ret)
c/c++**:
int
bsearchwithoutrecursion
(int array,
int low,
int high,
int target)
return-1
;}
int
binsearch
(const
int*array,
int start,
int end,
int key)
return-1
;}
例項:實現printn函式,傳入正整數n,使其順序列印1到n全部正整數。
方法一:迴圈實現
void
printn
(int n)
return
;}
方法二:遞迴實現
void
printn
(int n)
return
;}
看上去兩個**極其相似,但在測試時,如果n=100000的時候,遞迴函式將無法實現,這是因為遞迴函式對空間記憶體占有率過大。當記憶體超出指定範圍的時候,編譯器將直接報錯,程式無法執行下去。
所以,解決問題方法的效率,也是跟空間的利用效率有關。
例項:計算x的多項式f(x)的值。
方法一:小白寫法(逐一計算法)
doublef(
int n,
double a,
double x)
方法二:專業寫法(因式分解法)
doublef(
int n,
double a,
double x)
# include
# include
clock_t start, stop;
double duration;
intmain()
注意:如果一次時間太短無法**捉,則可以多次重複執行該函式,最後處以次數就可以得到執行一次函式所需要的時間。
資料型別
抽象:描述資料型別的方法不依賴於具體表現
如選擇排序演算法的偽碼描述:
void
selecttionsort
(int list,
int n)
}
失敗案例:遞迴函式。
void
printn
(int n)
return
;}
原因:在呼叫printn(100000)後,執行printn(99999),再執行printn(99998),直到printn(0)執行完成後,所以函式才會return,此時空間複雜度正比於輸入值n。如果用迴圈函式實現時,則空間占有量始終為乙個常量,不隨n值的變化而變化。
失敗案例:多項式函式計算。
doublef(
int n,
double a,
double x)
原因:時間複雜度計算時加減法可以忽略不記,主要研究乘法。上述案例中,運用了pow函式,一共運用了(n + 1)* n / 2 次乘法運算,故時間複雜度為t(n) = c1 * n^2 + c2 * n 。而如果採用因式分解的話,則使用了n次乘法運算,時間複雜度為t(n) = c * n。
我們在計算複雜度的時候經常比較最壞情況複雜度(因為在某寫演算法中,平均複雜度很難計算),從而來比較演算法的優劣程度。
例子:給定n個整數的序列,求函式f(i,j)= max 的最大值
2.6.1 演算法一:
int
maxsubseqsum1
(int a,
int n)
}return maxsum;
}
演算法複雜度:t ( n ) = o ( n ^ 3 )
2.6.2 演算法二:
int
maxsubseqsum1
(int a,
int n)
}return maxsum;
}
演算法複雜度:t ( n ) = o ( n ^ 2 )
2.6.3 演算法三:分而治之
原理:將數列對半分,分別求出兩邊的最大子列和,然後再計算過中點線的最大子列和,依此遞推。其演算法複雜度推導如下:
t ( n ) = 2 * t ( n / 2 ) + c * n , 其中: t ( 1 ) = o ( 1 )
t ( n ) = 2 ^ k * o ( 1 ) + c * k * n , 其中: n / 2 ^ k = 1
t ( n ) = o ( n * log n )
**略。
int
maxsubseqsum4
(int a,
int n)
return maxsum;
}
演算法複雜度:t ( n ) = o ( n ) 資料結構學習之基本概念
一 資料結構的概念 早期人們都把計算急理解為數值計算的工具。可現實中,我們更多的不是解決數值計算的問題,而是需要一些更為科學有效的手段 比如表 樹和圖等資料 結構 的幫助,才能夠更好的處理問題。所以資料結構是一門研究非數值計算的程式設計問題中的操作物件,以及他們之間的關係和操作等相關問題的學科。二 ...
資料結構學習 樹的基本概念
參考書籍 資料結構與演算法分析 c語言描述 連線倆個節點的稱為邊 一棵樹是n個節點和n 1條邊的集合 沒有兒子的節點稱為樹葉 葉 具有相同父親的稱為兄弟。某路徑的長為該路徑上邊的條數。對任意節點ni,ni的深度為從根到ni的唯一路經長,其中根的深度為0。一棵樹的深度等於它最深的樹葉深度。深度是向上而...
資料結構 學習筆記01
第一章 概 論 1.資料 資訊的載體,能被計算機識別 儲存和加工處理。2.資料元素 資料的基本單位,可由若干個資料項組成,資料項是具有獨立含義的最小標識單位。3.資料結構 資料之間的相互關係,即資料的組織形式。它包括 1 資料的邏輯結構,從邏輯關係上描述資料,與資料儲存無關,獨立於計算機 2 資料的...