標籤:
演算法設計的一般方法
隨機法依賴於隨機數的統計特性。一個應用隨機法的例子是快速排序。
分治法
動態規劃
貪進法
近似法——旅行商問題
指標
在C語言中,通常聲明一個void指標來表示泛型指標。
對於泛型指標來說類型轉換非常重要,因為只有告訴泛型指標通過何種類型來訪問地址時,泛型指標才能正確取到值。這是由於泛型指標不會告訴編譯器它指向的是何種類型資料,因此編譯器不知道多少個位元組要被訪問。也不知道應該如何解析位元組。
函數指標是指向可執行程式碼片段或調用可執行程式碼片段的資訊塊的指標。
例如,在下面一段代碼中,match被聲明為一個函數指標,它接受兩個void指標類型的參數,同時返回一個整型。
int(*match)(void*key1,void*key2);
假設有一個match_int函數,它的兩個void 指標參數指向整型並回返1。可以這樣賦值:
match = match_int;
調用:
retval = match(&x,&y);
遞迴
當遞迴調用是整個函數體中最後執行的語句且它的傳回值不屬於運算式的一部分,這個遞迴調用就是尾遞迴。
當編譯器檢測到一個函數調用是尾遞迴的時候,它就覆蓋當前的活躍記錄而不是在棧中去建立一個新的。
樣本:以尾遞迴的形式計算階乘的一個函數實現
//facttail.c
#include"facttail.h"
int facttail(int n,int a)
{
if(n <0)
return0;
elseif(0== n)
return1;
elseif(1== n)
return a;
else
return facttail( n -1, n * a);
}
計算n!:
facttail(n,1);
雜湊表
樣本:一個適用於處理字串的雜湊函數
//hashpjw.c
#include"hashpjw.h"
//hashpjw
unsignedint hashpjw(constvoid*key)
{
constchar*ptr;
unsignedint val;
//hash the key by performing a number of bit operations on it
val =0;
ptr = key;
while(*ptr !=‘\0‘)
{
unsignedint tmp;
val =(val <<4)+(*ptr);
if( tmp =(val &0xf0000000))
{
val = val ^(tmp >>24);
val = val ^ tmp;
}
ptr++;
}
//In practice, replace PRIME_TBLSIZ with the actual table size.
return val % PRIME_TBLSIZ;
}
樹的平衡
樹的平衡是指對於給定數量的結點,保證樹的高度儘可能短的過程。這意味著在結點加入下一層之前必須保證本層結點滿額。正式的說法是,如果滿足樹的所有葉子結點都在同一層上,或者所有 葉子結點都在最後兩層上,且倒數第二層是滿的,則這棵樹是平衡的。
如果一棵平衡樹最後一層的所有葉子結點都在最靠左邊的位置上,則稱這棵樹是左平衡的。
運算式樹狀架構
針對錶達式(((74-10)/32×(23+17))的運算式樹狀架構
使用先序、中序、後序遍曆樹,並把運算元與相關的操作符用括弧括起來,得到首碼、中綴、尾碼運算式:
首碼運算式
(×(/(-74 10)32)(+ 23 17)) = 80
中綴運算式
(((74 - 10)/32×(23+17)) = 80
尾碼運算式(逆波蘭運算式)
(((74 10 - )32/)(23 17+)× ) = 80
採用抽象棧狀態機器(abstract stack machine)來處理尾碼運算式(逆波蘭運算式)
二叉搜尋樹
為了更進一步理解保持一棵二叉搜尋樹平衡的重要性,不妨考慮一下當一棵二叉搜尋樹變得越來越不平衡的狀態。如果是這樣的話,尋找一個結點的複雜度就變成了O(n),這就相當於從頭到尾檢索所有的結點。
NP完全問題
沒有已知的求解多項式時間的演算法,但也無法證明此多項式不存在,這類問題被稱為NP完全問題
LRU頁面置換演算法
第二次機會置換法是實現LRU頁面置換演算法的一種方式。
它的工作方式是:維護一個當前存在於實體記憶體中的頁面的迴圈鏈表。為了簡化說明,假設鏈表中的每個元素只儲存一個頁碼和一個引用值,引用值要麼為1要麼為0。所有的頁面初始引用值都設定為0。每當系統訪問頁面時(比如,某個進程開始讀或寫某個頁面),該頁面的引用值就設定為1.
當需要某個頁幀時,作業系統就使用它維護的迴圈鏈表以及引用值來判斷哪些頁面應該釋放其頁幀。為了確定這一點,開始遍曆鏈表直到找到一個引用值為0的元素。當遍曆每一個頁面時,作業系統將頁面的引用值從1重設回0。一旦它遇到引用值為0的元素,它就找到了一個自從上次遍曆鏈表以來都沒有被 系統訪問過的頁面,因此這個頁面就是最近最少使用的頁面。
集合覆蓋歸併排序
歸併排序需要額外的儲存空間來運行,這也是它的一個缺點。然而,歸併排序對于海量資料處理還是非常有價值的,因為它能夠按預期將資料集分開。這使得我們能夠將資料集分割為更加可管理的資料,接著用歸併排序來處理資料,然後不斷地合并資料,在這個過程中並不需要一次儲存所有的資料。
多項式插值
求函數近似值的一種方法。其中函數值僅在幾個點上已知。該演算法的基礎是建立級數小於等於n的一個插值多項式pn(z),其中n+1是已知函數值的個數。
最小二乘法
給定函數y(x)=b1x+b0,用來確定b1和b0的估計器方法,使得y(x)是n個點(x0,y0),...,(xn-1,yn-1)的集合的最佳擬合線。最佳擬合線使用最小二乘估計法來最小化每個點(xi,yi),i=0,...,n-1與沿y(x)的相應點(xi,y(xi))之間的垂直距離的平方和。
方程求解
使用牛頓迭代法
LZ77
相關資料結構(其中一種實現)
12位可以讓滑動視窗容納4KB,在一個32位元組的緩衝區中,重複的位元組不會超過32個位元組,即長度為5位,下一個位元組儲存在【未匹配的符號】欄位內。
第一位用1和0來表示在有重複項和沒有重複項時資料表示的不同。
旅行商問題
在一幅圖中,訪問每個頂點一次,並最終返回起始頂點,這個訪問的軌跡稱為哈密頓圈。
要解決旅行商問題,需要用圖G=(V,E)作為 模型,尋找圖中最短的哈密頓圈。
一種近似地算旅行商路線的方法就是使用最近鄰法。其運算方法如下,從一條僅包含起始點的路線開始,將此頂點塗黑。其他頂點為白色,在其它頂點加入此路線中後,再將相應頂點塗黑。接著,對於每個不在路線中的頂點v,要為最後加入路線的頂點u與v之間的邊計算權值。回想一下,在旅行商問題中u與v之間邊的權值就是u到v之間的距離。這個距離可以用每個頂點的座標計算得到。
得到的近似解
實際上的最佳化效果為:
幾何演算法判斷線段是否相交凸包
來自為知筆記(Wiz)
《演算法精解 C語言描述》