日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

算法导论中C语言代码,算法导论-学习笔记与进度

發布時間:2025/4/17 编程问答 62 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法导论中C语言代码,算法导论-学习笔记与进度 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

算法導論 閱讀進度

第一部分 基礎知識

第一章 計算中算法的角色 Done

1.1 算法

輸入與輸出

算法可以解決哪些問題

數據結構

技術

一些比較難的問題

1.2 作為一種技術的算法

效率

算法和其他技術

第二章 算法入門 Done

2.1 插入排序

偽代碼如下:

INSERTION_SORT(A)

for j = 2 to length[A]

do key = A[j]

i = j-1

// 將其與已經排好序的數組進行挨個比較

while i>0 and A[i] > key

do A[i+1] = A[i]

i = i-1

A[i+1] = key

原理

其實就是在每次進入一個元素key后,將其與已經排好序的序列進行比較,如果key值小于序列的第一個值(默認為從小到大排序),那么就表明該key應該置入這個序列當中,并且將比較過的元素自動向后移動,以騰出空間放置key。最后將key值置入空位中。

現實中就是在接牌時,插入和調整撲克牌順序的問題了,算法復雜度為O(n^2)

插入排序采用的是增量方法(incremental),采用分治法的合并排序時間復雜度為O(nlgn)

分治法

- 分解

- 解決

- 合并

主要在于合并算法MERGE(A, p, q, r)

偽代碼如下:

MERGE(A, p, q, r)

n1 = q-p+1

n2 = r-q

for i = 1 to n1

do L[i] = A[p+i-1]

for j = 1 to n2

do R[j] = A[q+j]

L[n1+1] = -oo

R[n2+1] = -oo

i = j = 1

for k = p to r

do if L[i] <= R[j]

then A[k] = L[i]

i = i+1

else

A[k] = R[j]

j = j+1

原理

首先將輸入數組分割,然后在對分割后的數組進行一一比較,如果L的元素小,就將其輸出至目的數組A,如果R小,則輸出R至A.

此時MERGE-SORT算法就清晰了,如果將一個數組通過遞歸不斷將其分割,最終分割為每個數組只有一個元素,那么使用MERGE時,就能夠將此二元素排序,然后對4元素排序,然后是8元素....

偽代碼如下:

MERGE-SORT(A, p, r)

if p

then q = (p+r)/2

MERGE-SORT(A, p ,q)

MERGE-SORT(A, q+1, r)

MERGE(A, p , q, r)

冒泡排序

偽代碼如下:

BUBBLE-SORT(A)

for i = 1 to length[A]

do for j = length[A] downto i+1

do if A[j] < A[j-1]

then exchange A[j], A[j-1]

通過不斷交換相鄰的兩個反序元素達到排序的目的,時間復雜度為O(n^2)

1----n-1

2----n-2

3----n-4

....

n-1----1

1+2+3+4+....+n = n(n+1)/2,所以時間復雜度為O(n^2)

第三章 函數的增長 Done

第四章 遞歸 Done

遞歸式 T(n) = aT(n/b) + f(n), 其中a>=1, b>1, f(n) 是給定函數

4.1 代換法

猜測解的形式

用數學歸納法找出真正有效的常數

4.2 遞歸樹方法

仔細畫出遞歸樹

4.3 主方法

是求解遞歸式T(n)的食譜方法。

主方法依賴于定理4.1主定理 設a>=1 和 b >1為常數,設f(n)為一函數,T(n)由遞歸式

T(n) = aT(n/b) + f(n)

對非負整數定義,其中n/b 指上頂或者下底,那么T(n)可能有如下的漸進界

...

主要是針對f(n),a,b等值。

第五章 概率分析與隨機化算法

5.1 雇用問題

概率分析,隨機算法。

使用概率分布預測輸入值的分布,以此來幫助分析算法平均情況行為的。

5.2 指示器隨機變量

I(A) = 1,如果A發生的話;0,如果A不發生的話。

5.3 隨機算法

無法得到輸入分布,考慮使用隨機算法。

隨機排列數組

許多隨機算法通過排列給定的輸入數組來使輸入隨機化。

一個常用方法是為每個數組元素A[i]賦一個隨機的優先級P[i],然后按照優先級對數組進行排序,過程PERMUTE-BY-SORT,花費O(nlgn)

原地排列給定的數組,過程RANDOMIZE-IN-PLACE花費O(n)

5.4 進一步使用

1 生日悖論

一個房間的人數需要達到多少,使得兩個人生日相同的機會達到50%?分析所有人生日互不相同的概率,其補就為至少兩人生日相同。

因此 Pr{Bk} = 1(n-1/n)(n-2/n)(n-3/n)....(n-k+1/n)=1(1-1/n)*(1-2/n)...(1-(k-1)/n)

最后分析得出至少23人在一個房間里,概率就能夠為1/2?;鹦菫?8個人

2 球與盒子

第二部分 排序和順序統計學. Done

第六章 堆排序 Done

二叉堆數據結構可以被視為一顆完全二叉樹。樹的每一層都是被填滿的,最后一層可能除外。

父節點

PARENT(i)

return [i/2]

LEFT(i)

return 2i

RIGHT(i)

return 2i+1

有兩種:最大堆和最小堆,在這兩種堆中,節點內的數組都要滿足堆特性,在最大堆中,除了根以外的每個節點,有

A[PARENT(i)] >= A[i]

根元素為最大值。

最小堆剛好相反。

MAX-HEAPIFY. 保持堆的性質,最大堆性質,根或者子根都是樹最大元素,O(lgn)

對A[i]的這顆字數執行最大堆化。

算法如下:

MAX-HEAPIFY( A, i )

l = LEFT(A[i])

r = RIGHT(A[i]

If l <= heap-size(A) and A[l] > A[i]

then largest = l

else largest = i

If r <= heap-size(A) and A[r] > A[largest]

then largest = r

If largest != i

then exchange(A[i], A[largest])

MAX-HEAPIFY(A, largest)

建堆 Build-MAX-HEAP, 對每一顆非葉子節點樹執行最大堆化,直至根元素。

自n/2 處開始遞減,循環執行Max-HEAPIFY,運行時間的界為O(n)

BUILD-MAX-HEAP(A)

heap-size[A] = length[A]

for i = length[A]/2 downto 1

do MAX-HEAPIFY(A, i)

堆排序 HEAPSORT 自葉節點向跟元素遞減,交換跟元素和葉節點,接著調用MAX-HEAPIFY, 保持該子樹的最大堆性質,即可完成節點自小到大排序,時間復雜度為O(nlgn)

原理

每次都將最大的根元素換至末尾的葉節點,這一操作能夠將最大元素調到最后,并且排除出堆,然后再一次構造最大堆,次最大元素又被調節到根元素位置,然后再一次將其換至葉節點,這樣,不斷循環,就能夠將元素在數組中從小到大排列。

HEAPSORT(A)

BUILD_MAX_HEAP(A)

for i = length[A] downto 2

do exchange(A[1], A[i])

heap-size[A] = heap-size[A] - 1

MAX-HEAPIFY(A,1)

最大優先級隊列,最小優先級隊列的應用如圖所示。

第七章 快速排序 Done

QUICKSORT(A,p, r)

If p < r

Then q = PARTITION(A, p, r )

QUICKSORT(A, p, q-1)

QUICKSORT(A, q+1, r)

最初調用時,QUICKSORT(A, 1, length(A) )

其中PARTITION(A, q, r )算法如下

x = A[r]

i = p-1

For j = p to r-1

Do If A[j] <= x

Then i += 1

Exchange(A[i], A[j])

Exchange(A[i+1], A[r])

Return i + 1

分區算法 不斷將數組分為四個區:

- 第一區 小于 x的區間 A[p, i]

- 第二區 大于x的區間 A[i+1, j]

- 第三區間 尚未比較的區間 A[j+1, r-1]

- 第四區間 主元 A[r]

每一次運行都是O(n)

總共需要遞歸調用O(log n),因此算法時間復雜度為O(n log n)

有時我們需要對樣本加入一些隨機化數據,以便對于所有輸入,都能得到較好的平均性能,因此,采用隨機選擇主元的快速排序隨機化版本。

主要是對分區操作進行修改

RAMDOMIZED-PARTITION(A, p, r)

i = random(p, r)

Exchange(i , r)

Return PARTITION(A, p, r)

新的排序算法修改如下:

RANDOMIZED-QUICKSORT(A, p, r )

If p < r

then q = RANDOMIZED-PARTITION(A, p, r)

RANDOMIZED-QUICKSORT(A, p, q-1)

RANDOMIZED-QUICKSORT(A, q+1, r)

第八章 線性時間排序(即時間復雜度為O(n)) Done

合并排序和堆排序在最壞情況下,達到上界O(nlogn),快速排序在平均情況下達到此上界,最壞O(n^2)

比較排序,非比較排序

8.1 排序算法的時間的下界

比較排序可以抽象為決策樹模型,比如三個值的比較決策結果又3!= 6

定理8.1 任意一個比較排序的算法在最壞情況下,都需要做O(nlgn)次的比較

推論8.2 堆排序和合并排序都是漸進最優的比較排序算法。

8.2 計數排序**

比較有趣的一個排序算法,使用三個數組空間A,B,C。

統計各個值出現的次數.

C[A[j]] = C[A[j]] +1

可見對于C的空間要求將會比較大,只適用于數值比較小的空間。

這樣的排序將會導致各個值A[j]的出現次數按照A[j]值的大小在C中依次由小到大排列。然后計算出C中每個值之前出現多少個值,進而計算出該值所占的位置。

算法如下:

COUNTING-SORT(A, B, k)

for i=0 to k

do C[i] = 0

// 計算A[i] 各個值出現的次數

for j=1 to lenght[A]

do C[A[j]] = C[A[j]]+1

// 計算小于或者等于C[i]值出現的次數

for i=1 to k

do C[i] = C[i]+C[i-1]

// 將A[j]的值按照出現的位置置入B中,并將該值的出現次數減一,使與之相同的值自動排在A[j]的前一個位置

for j = length[A] downto 1

do B[C[A[j]]] = A[j]

C[A[j]] = C[A[j]]-1

該算法很繞,但比較穩定,運行時間為O(n)

8.3 基數排序

基數排序是對具有多個關鍵字域的記錄進行排序,比如年月日。

RADIX-SORT(A,d)

for i = 1 to d

do use a stable sort to sort array A to digit i

可以將一個32位的字視為4個8位的數字,于是就可以將k 縮小至255,數位d變為4.

同樣的,利用計數排序作為中間穩定排序的基數排序不是原地排序,占用空間較大。盡管基數排序執行的遍數可能比快速排序少,但每一遍所需的時間要長得多。因此一般還是使用快排,因為快排能夠有效的利用硬件緩存,同時也是個原地排序。

8.3 桶排序

輸入需要符合均勻分布,即可以以線性時間O(n)運行。計數排序的假設輸入由小范圍內整數構成,而桶排序假設輸入由一個隨機過程產生,該過程均勻分布在區間(0,1]

算法

BUCKET-SORT(A)

n = length(A)

for i = 1 to n

do insert A[i] into list B[nA[i]]

for i = 0 to n-1

do sort list B[i] with insertion sort

concatenate the lists B[0],B[1],....

B[n-1] together in order

第九章 中位數和順序統計學 Done

約定

取下中位數

本章討論從一個由n個不同數值構成的集合中選擇第i個順序統計量的問題。選擇問題的定義如下:

輸入:一個包含n個不同的數的集合A和一個數i, 1=

輸出: 元素x屬于A,它恰大于A中其他的i-1個元素。

最大值和最小值

比如MINIMUM(A)

min = A[1]

for i = 2 to length[A]

do if min > A[i]

min = A[i]

return min

通過n-1比較得出,時間復雜度為O(n)

最大值也是如此。

同時計算最大值和最小值,如使用獨立比較需要比較2(n-1)次。

可通過每次輸入一對數據,然后將其中大的于最大值比較,小的與最小值比較,每個元素比較三次,但只需運行n/2次,所以總的比較次數是3(n/2)次。

9.2 以期望線性時間做選擇

使用RANDOMIZED-SELECT 算法,以第七章快速排序算法為模型,也是對輸入數組進行劃分,但只處理劃分的一邊,該邊通過與需要選擇的位計算而出,期望運行時間為O(n)

RANDOMIZED-SELECT算法利用RADOMIZED-PARTITION程序,返回數組A[p..r]中第i小的元素

RANDOMIZED-SELECT(A, p, r, i)

if p = r

then return A[p]

q = RANDOMIZED-PARTITION(A, p, r)

k = q - p + 1

if i = k

then return A[q]

elseif i < k

then return RANDOMIZED-SELECT(A, p, q-1, i)

//注意i的位置將會做相應的調整,i始終只是相對位置,而q,r都是指在整個數組中的位置

//因此在比較i和k的位置時,是通過計算k的相對位置來與i比較的。

else return RANDOMIZED-SELECT(A, q+1, r, i-k)

按照我的理解,似乎不需要使用i的相對位置,原始位置應該就可以,感覺上沒有限制。

結論,在平均情況下,任何順序統計量特別是中位數,都可以在線性時間內O(n)得到。

9.3 最壞情況線性時間的選擇

最壞情況運行時間為O(n)的SELECT算法。采用快速排序的確定性劃分算法PARTITION,并做了相應的修改。

- 將輸入數組劃分為n/5個組,每組5個

- 尋找n/5個組中的每一組中位數,首先對每組中的元素進行插入排序(插入排序在元素數量較小的情況下有著O(n)的復雜度)然后從排序過的數組中選出中位數。

- 在第二步中選出的中位數,遞歸調用SELECT選出一個中位數x

- 利用修改過的PARTITION過程,按照中位數的中位數x,對輸入數組進行劃分,讓k比劃分地區的元素數目多1,所以x就是第k小元素,并且有n-k個元素在劃分的高區。

- 如果i = k ,則返回x,否則,如果ik, 則在高區遞歸調用尋找第(i-k)個最小元素。

本章結論

本章中選擇算法之所以具有線性時間,是因為這些算法并沒有進行排序。線程時間的行為并不是因為對輸入做假設所得到的結果。在比較模型中,即使是在平均情況下,排序仍然需要O(nlgn)的時間,所以從漸進意義上來看,排序和索引方法的效率是不高的。

第三部分 數據結構

第十章 基本數據結構. Done

第十一章 散列表. Done

第十二章 二叉查找樹. Done

第十三章 紅黑樹. Undone

第八部分 附錄:數學基礎知識

A. 求和. Done

B. 集合等離散數學結構. Done

集合

關系

函數

自由樹

有根樹和有序樹

二叉樹和位置樹

C. 計數和概率. Undone

C.1 計數

在有限集合S上構造一個長度為k的串稱為K串。直觀上,為了在n元集上構造一個k串,有n種方法選擇第一個元素,同樣地,也有N種方法選擇第二個元素,這樣一次進行K次,從而K串的數目為nnn*...n = n^k.

最形象的就是車牌號了。

排列

有限集S的排列是S中所有元素的有序序列,且每個元素僅出現一次。一個N元集的集合有n!種排列,第一個元素有n種選擇,第二個有n-1種選擇,第三個有n-2種選擇...

集合S的k排列是S中k個元素的有序排列,且每個元素出現一次。因此N元集合的K排列數目是

n(n-1)(n-2)(n-3)(n-4)...(n-k+1) = n!/(n-k)!

組合

n元集的K組合就是S的k子集,n元集的k組合的數目可以用排列的數目來表示,對每個k組合,它的元素恰好有k!中排列,每個都是n元集的一個不同的k排列。因此,n元集的k組合數目是其k排列的數目除以k!。這個數量為

n!/(k!(n-k)!)

組合與排列的區別是,組合中k元祖是無序的,而排列是有序的,意味著組合的元祖對應著k!種不同的排列元祖。

因此在計算時需要除去每個元祖的其他的有序排列。

二項式系數

二項式界

下界

= n!/k!(n-k)! 展開>= (n/k)^k

再利用斯特林近似式得上界

<= n^k/k! <= (en/k)^k

C.2 概率

條件概率Pr{A|B} 讀作在事件B發生的條件下,事件A發生的概率

Pr{A|B} = Pr{A交B}/ Pr{B}

A交B是時間A發生,B也發生的事件,因此可以認為這是B中的一個基本事件,因此該事件占整個B事件的概率就是Pr{A交B}/ Pr{N},也即Pr{A|B}

如果Pr{A交B} = Pr{A} Pr{B},則稱連個事件獨立。

貝葉斯定理

Pr{A交B} = Pr{B} Pr{A|B} = Pr{A} Pr{B|A}

通過交換律,可得如下貝葉斯定理

Pr{A|B} = Pr{A} Pr{B|A}/Pr{B}

C.3 離散隨機變量

隨機變量X的概率密度函數

f(x) = Pr{X=x}

隨機變量的期望值

E[X] = ∑xPr{X=x}

方差

Var[X] = E[(X-E[X]^2)]

= E[X^2]-E^2[X]

C.4 幾何分布與二項分布

幾何分布

假設進行一系列的伯努利實驗,每次實驗成功的概率是P,失敗的概率是q=1-p,在取得一次成功前要進行多少次實驗?因為在取得一次成功前有k-1次失敗,從而有

Pr{X=k} = q^(k-1)p

期望 1/p

二項分布

因為有(n k) 種方法從n次實驗中選取k次成功的試驗,且每次發生的概率是p^k*q^(n-k)

Pr{X=k} = (n k)p^k*q^(n-k)

期望E[X] = np, 方差 Var[X] = npq

發自我的 iPad

總結

以上是生活随笔為你收集整理的算法导论中C语言代码,算法导论-学习笔记与进度的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。