轉 查詢演算法

2021-05-28 10:34:40 字數 3983 閱讀 6398

查詢是在大量的資訊中尋找乙個特定的資訊元素,在計算機應用中,查詢是常用的基本運算,例如編譯

程式中符號表的查詢。用關鍵字標識乙個資料元素

,查詢時根據給定的某個值,在表中確定乙個關鍵字的值等於給定值的記錄或資料元素。在計算機中進行查詢的方法是根據表中的記錄的組織結構

確定的。

順序查詢

也稱為線形查詢,從資料結構線形表的一端開始,順序掃瞄,依次將掃瞄到的結點關鍵字與給定值k相比較,若相等則表示查詢成功;若掃瞄結束仍沒有找到關鍵字等於k的結點,表示查詢失敗。

二分查詢

要求線形表中的結點按關鍵字

值公升序或降序排列,用給定值k先與中間結點的關鍵字比較,中間結點把線形表分成兩個子表,若相等則查詢成功;若不相等,再根據k與該中間結點關鍵字的比較結果確定下一步查詢哪個子表,這樣遞迴進行,直到查詢到或查詢結束發現表中沒有這樣的結點。

分塊查詢

也稱為索引查詢,把線形分成若干塊,在每一塊中的資料元素的儲存順序是任意的,但要求塊與塊之間須按關鍵字值的大小有序排列,還要建立乙個按關鍵字值遞增順序排列的索引表,索引表中的一項對應線形表中的一塊,索引項包括兩個內容:① 鍵域存放相應塊的最大關鍵字;② 鏈域存放指向本塊第乙個結點的指標。分塊查詢分兩步進行,先確定待查詢的結點屬於哪一塊,然後在塊內查詢結點。

雜湊表查詢

是通過對記錄的關鍵字值進行運算,直接求出結點的位址,是關鍵字到位址的直接轉換方法,不用反覆比較。假設f包含n個結點,ri為其中某個結點(1≤i≤n),keyi是其關鍵字值,在keyi與ri的位址之間建立某種函式關係,可以通過這個函式把關鍵字值轉換成相應結點的位址,有:addr(ri)=h(keyi),addr(ri)為雜湊函式。  

順序查詢過程:從表中的最後乙個記錄開始,逐個進行記錄的關鍵字與給定值進行比較,若某個記錄的關鍵字與給定值相等,則查詢成功,找到所查的記錄;反之,若直到第乙個記錄,其關鍵字和給定值比較都不相等,則表明表中沒有所查的記錄,查詢失敗。

演算法描述為

int search(int d,int a,int n)

二分查詢又稱折半查詢,它是一種效率較高的查詢方法。

【二分查詢要求】:1.必須採用順序儲存結構

2.必須按關鍵字

大小有序排列。

【優缺點】折半查詢法的優點是比較次數少,查詢速度快,平均效能好;其缺點是要求待查表為有序表,且插入刪除困難。因此,折半查詢方法適用於不經常變動而查詢頻繁的有序

列表。【演算法思想】首先,將表中間位置記錄的關鍵字與查詢關鍵字比較,如果兩者相等,則查詢成功;否則利用中間位置記錄將表分成前、後兩個子表,如果中間位置記錄的關鍵字大於查詢關鍵字,則進一步查詢前一子表,否則進一步查詢後一子表。

重複以上過程,直到找到滿足條件的記錄,使查詢成功,或直到子表不存在為止,此時查詢不成功。

【演算法複雜度

】假設其陣列長度為n,其演算法複雜度為o(log(n))

下面提供一段二分查詢實現的偽**

:binarysearch(max,min,des)

mid-des then

max=mid-1

else

min=mid+1

return max

分塊查詢又稱索引順序查詢,它是順序查詢的一種改進方法。

方法描述:將n個資料元素"按塊有序"劃分為m塊(m ≤ n)。每一塊中的結點不必有序,但塊與塊之間必須"按塊有序";即第1塊中任一元素的關鍵字都必須小於第2塊中任一元素的關鍵字;而第2塊中任一元素又都必須小於第3塊中的任一元素,……。

操作步驟

step1 先選取各塊中的最大關鍵字構成乙個索引表;

step2 查詢分兩個部分:先對索引表進行二分查詢或順序查詢,以確定待查記錄在哪一塊中;然後,在已確定的塊中用順序法進行查詢。  

1 基本原理

我們使用乙個下標範圍比較大的陣列來儲存元素。可以設計乙個函式(雜湊函式,也叫做雜湊函式

),使得每個元素的關鍵字都與乙個函式值(即陣列下標)相對應,於是用這個陣列單元來儲存這個元素;也可以簡單的理解為,按照關鍵字為每乙個元素"分類",然後將這個元素儲存在相應"類"所對應的地方。

但是,不能夠保證每個元素的關鍵字與函式值是一一對應的,因此極有可能出現對於不同的元素,卻計算出了相同的函式值,這樣就產生了"衝突",換句話說,就是把不同的元素分在了相同的"類"之中。後面我們將看到一種解決"衝突"的簡便做法。

總的來說,"直接定址"與"解決衝突"是雜湊表的兩大特點。

2 函式構造

建構函式

的常用方法(下面為了敘述簡潔,設 h(k) 表示關鍵字為 k 的元素所對應的函式值):

a) 除餘法:

選擇乙個適當的正整數 p ,令 h(k ) = k mod p

這裡, p 如果選取的是比較大的素數

,效果比較好。而且此法非常容易實現,因此是最常用的方法。

b) 數字選擇法:

如果關鍵字的位數比較多,超過長整型範圍而無法直接運算,可以選擇其中數字分布比較均勻的若干位,所組成的新的值作為關鍵字或者直接作為函式值。

3 衝突處理

線性重新雜湊技術易於實現且可以較好的達到目的。令陣列元素個數為 s ,則當 h(k) 已經儲存了元素的時候,依次探查 (h(k)+i) mod s , i=1,2,3…… ,直到找到空的儲存單元為止(或者從頭到尾掃瞄一圈仍未發現空單元,這就是雜湊表

已經滿了,發生了錯誤。當然這是可以通過擴大陣列範圍避免的)。

4 支援運算

雜湊表支援的運算主要有:初始化(makenull)、雜湊函式值的運算(h(x))、插入元素(insert)、查詢元素(member)。

設插入的元素的關鍵字為 x ,a 為儲存的陣列。

初始化比較容易,例如

const empty=maxlongint; // 用非常大的整數代表這個位置沒有儲存元素

p=9997; // 表的大小

procedure makenull;

var i:integer;

begin

for i:=0 to p-1 do

a[i]:=empty;

end;

雜湊函式值的運算根據函式的不同而變化,例如除餘法的乙個例子:

function h(x:longint):integer;

begin

h:= x mod p;

end;

我們注意到,插入和查詢首先都需要對這個元素定位,即如果這個元素若存在,它應該儲存在什麼位置,因此加入乙個定位的函式 locate

function locate(x:longint):integer;

var orig,i:integer;

begin

orig:=h(x);

i:=0;

while (ix)and(a[(orig+i)mod s]empty) do

inc(i);

//當這個迴圈停下來時,要麼找到乙個空的儲存單元,要麼找到這個元

//素儲存的單元,要麼表已經滿了

locate:=(orig+i) mod s;

end;

插入元素

procedure insert(x:longint);

var posi:integer;

begin

posi:=locate(x); //定位函式的返回值

if a[posi]=empty then a[posi]:=x

else error; //error 即為發生了錯誤,當然這是可以避免的

end;

查詢元素是否已經在表中

procedure member(x:longint):boolean;

var posi:integer;

begin

posi:=locate(x);

if a[posi]=x then member:=true

else member:=false;

end;

查詢演算法

轉)斐波那契查詢演算法(黃金分割查詢演算法)

斐波那契數列,又稱 分割數列,指的是這樣乙個數列 1 1 2 3 5 8 13 21 在數學上,斐波那契被遞迴方法如下定義 f 1 1,f 2 1,f n f n 1 f n 2 n 2 該數列越往後相鄰的兩個數的比值越趨向於 比例值 0.618 斐波那契查詢就是在二分查詢的基礎上根據斐波那契數列進...

轉oracle查詢功能

查詢所有表名 select t.table name from user tables t 查詢所有欄位名 select t.column name from user col comments t 查詢指定表的所有欄位名 select t.column name from user col com...

轉 tarjan演算法

說到以tarjan命名的演算法,我們經常提到的有3個,其中就包括本文所介紹的求強連通分量的tarjan演算法。而提出此演算法的普林斯頓大學的robert e tarjan教授也是1986年的圖靈獎獲得者 具體原因請看本博 歷屆圖靈獎得主 一文 首先明確幾個概念。強連通圖。在乙個強連通圖中,任意兩個點...