查詢演算法的總結

2021-07-28 16:48:50 字數 3905 閱讀 7374

一、查詢技術分類

1、靜態查詢表技術(順序查詢、二分查詢、分塊查詢)

2、動態查詢表技術(二叉查詢樹)

3、雜湊表技術(雜湊表技術)

二、查詢技術說明

衡量查詢演算法優劣的標準——平均搜尋長度(asl)=,其中ci為查詢第

i個數需要進行比較的次數(比如開始對比乙個陣列中的第

i個數,則前面已經對比了

i-1個數字),

pi表示查詢第

i個數的概率(一般會平均,即

1/n)。

a、靜態查詢表技術

1、順序查詢

(1)平均查詢長度為:(n+1)/2,即時間複雜度為o(n)。

2、二分查詢

(1)必須是有序表,而且只適用於順序儲存結構;效能只有在均勻分布的時候才是最優的。

(2)查詢長度:每經過一次比較,查詢範圍都要縮小一半,因此最大查詢長度為msl=[log2 n]+1。當

n足夠大時,可近似的表示為

log2(n)

,即時間複雜度為o(log2(n))。

(3)二分查詢要求查詢表按關鍵字有序,而排序是一種很費時的運算;而且二分查詢法要求表是順序儲存的,為保持表的有序性,在進行插入和刪除操作時,都必須移動大量記錄。因此,二分查詢的高查詢效率是以犧牲排序為代價的,它特別適合於一經建立就很少移動、而又經常需要查詢的線性表。

(4)**示例

//k為待查詢的數字,r為資料集合,函式返回k在r中的位置

int binsearch(int r, int k)

if (find)

return (mid); /*查詢成功,返回找到的元素位置*/

else

return (-1); /*查詢失敗,返回-1*/

}

3、分塊查詢(索引順序查詢)

(1)分塊查詢要求把線性表分成若干塊,塊與塊之間必須有序(即假如公升序排列,那麼第一塊的最大值,必須小於第二塊的最小值),但是在每一塊中記錄的關鍵字不一定有序。假設這種排序是按關鍵字值遞增排序的,抽取各塊中的最大關鍵字及該塊的起始位置構成乙個索引表,按塊的順序存放在乙個陣列中,顯然這個陣列是有序的。

(2)分塊查詢過程分兩步進行:

a、首先查詢索引表,確定待查記錄所在塊(可用二分查詢法或順序查詢法);

b、在相應塊(子表)中用順序查詢法查詢記錄。

(3)分塊查詢的效率介於順序查詢和折半查詢之間,對於資料量巨大的線性表,它是一種較好的方法。在表中插入或刪除乙個記錄時,只要找到該記錄所屬的塊,就可以在該塊內進行插入和刪除運算,插入和刪除無需移動大量記錄。分塊查詢的主要代價是:需要增加乙個輔助陣列的儲存空間和將初始表分塊排序的運算。

(4)**示例:

struct idtable

;struct idtable id[b]; /*b為塊數*/

int blksearch(int r, struct idtable id, int k)

/*查詢完畢,low1存放找到的塊號*/

if (low1 < b)

else /*若low1>=b,則k大於查詢表r中的所有關鍵字*/

return -1;

b、動態查詢表技術

c、雜湊表技術

1、雜湊表的定義

雜湊表是通過關鍵字進行某種計算(對映)來確定該記錄的儲存位置的一種查詢表。

2、衝突解決方法

不同的關鍵字,根據雜湊函式被對映到同乙個儲存位址,這種現象被稱為衝突。衝突是不可避免的,因為關鍵字的取值集合遠遠大於表空間的位址集合,我們只能儘量減少衝突的發生。在構造雜湊函式時,主要面臨兩個問題:一是構造較好的雜湊函式,把關鍵字集合中元素盡可能均勻地分布到位址空間中去,減少衝突的發生,另乙個就是找到解決衝突的方法。

解決衝突的方法中比較常用的是

3、雜湊演算法的過程:首先得建立雜湊表(一般都有從檔案中讀取吧?),其次才是查詢。

4、完整**示例:

#include#includestruct keynum

;struct keynum* hash[100];

struct keynum* inserthash(struct keynum*, int m);//關鍵字插入鍊錶

int searchhash(struct keynum*, int m);//查詢鍊錶中是否存在值為m的整數

void print(struct keynum*);//列印鍊錶

void main()

fscanf(p, "%d", &num);第乙個值為關鍵字的個數,因此num讀入的是關鍵字的個數,這裡預設num小於100的

for (i = 0; ikey = m;

p1 = head;

p0 = temp;//要插入的節點(值為m);

if (head == null)//1,原來的鍊錶為空,插入到head後

else//原來的鍊錶不為空

if (p0->key <= p1->key)

else//4,插入到結尾處

}return(head);

}int searchhash(struct keynum*head, int m)//查詢鍊錶head中是否存在m

p = p->next;

} while (p != null);

return(k);//存在m值則返回1,否則返回0;

}void print(struct keynum*head)//列印鍊錶head

while (p != null);

} else

printf("null");}/*

struct keynum * inserthash(struct keynum*head, int k)//

else//如果不是,則在原來的鏈條的尾巴上新增新的節點(上面已經建立好的節點)

//具體的實現方法,就是將head指標指向剛才所建立的結構體空間?(no):head並不是指向尾巴節點的指標,而是整個鏈條的首指標!!!!

return head;

}*/

總結:(1)順序查詢的查詢效率很低;但是對於待查記錄的儲存結構沒有任何要求,既適用於順序儲存,又適用於鏈式儲存;當待查表中的記錄個數較少時,採用順序查詢法較好。

(2)折半查詢的平均查詢長度較小,查詢速度快;但它只能用於順序儲存,不能用於鏈式儲存;且要求表中的記錄是有序的。對於不常變動的有序表,採用折半查詢法是較為理想的。

(3)分塊查詢的平均查詢長度介於順序查詢和折半查詢之間;跟順序查詢一樣,對記錄的儲存結構沒什麼要求,既可以用於順序儲存,也可用於鏈式儲存;要求表中元素是逐段有序的,即塊與塊之間的記錄按關鍵字有序。當待查表的資料量較大時,分塊查詢的優越性更為突出。

(4)雜湊法是一種直接計算位址的方法,通過對關鍵字值進行某種運算來確定待查記錄的儲存位址。在查詢過程中不需要進行比較,因此,其查詢時間與表中記錄的個數無關。當所選擇的雜湊函式能得到均勻的位址分布時,其查詢效率比前面的三種方法都要快。雜湊法的查詢效率取決於以下三個因素:雜湊函式、處理衝突的方法及裝填因子。

p.s.線性表包括順序儲存表(比如陣列)、鏈式儲存表(鍊錶)。

另外在程式設計的過程中,也體會到了以下內容:指向結構體的指標p或者head,無論是通過賦值還是開創的空間的強制轉換,head->next,p->next都是p結構體內next。

查詢演算法總結

順序查詢演算法 1.演算法描述 順序比較即可。2.平均查詢長度 n 1 2,其中n為表長。3.演算法實現 省略4.優化思想 根據經驗,目前被查到越多的元素,將來可能被查到的可能性也越大。所以可以考慮,每次查詢到乙個元素後,將它和直接前驅交換位置。如果上述的經驗從概率上來講是成立的,則可以加快順序查詢...

查詢演算法總結

順序查詢演算法 1.演算法描述 順序比較即可。2.平均查詢長度 n 1 2,其中n為表長。3.演算法實現 省略4.優化思想 根據經驗,目前被查到越多的元素,將來可能被查到的可能性也越大。所以可以考慮,每次查詢到乙個元素後,將它和直接前驅交換位置。如果上述的經驗從概率上來講是成立的,則可以加快順序查詢...

查詢演算法總結

一 順序查詢 二 二分查詢 int binarysearchrecursion int arry,int value,int start,int end else int binarysearchrecursion int arry,int len,int value int binarysearc...