靜態查詢表 順序查詢 折半查詢 分塊查詢

2021-06-22 18:47:01 字數 4075 閱讀 6382

引言:

除去各種線性和非線性的資料結構外,還有一種在實際應用中大量使用的資料結構——查詢表。查詢表是由同一型別的資料元素構成的集合。

對查詢表經常進行的操作有:1、查詢某個"特定的"資料元素是否在查詢表中;2、檢索某個"特定的"資料元素的各種屬性;3、在查詢表中插入乙個資料元素;4、從查詢表中刪去某個資料元素。對查詢表只作前兩種統稱為"查詢"的操作,則稱此類查詢表為靜態查詢表。若在查詢過程中同時插入查詢表中不存在的資料元素,或者從查詢表中刪除已存在的某個資料元素,則稱此類表為動態查詢表。

基礎知識:

[cpp]view plain

copy

print?

關鍵字型別和資料元素型別統一說明如下:    

典型的關鍵字型別說明可以是:    

typedef

float

keytype;      

//實型  

typedef

intkeytype;            

//整型  

typedef

char

keytype;            

//字串型  

資料元素型別定義為:    

typedef

struct

selmtype;    

對兩個關鍵字的比較約定如下的巨集定義:    

//對數值型關鍵字  

#define eq(a, b)    ((a) == (b))  

#define lt(a, b)     ((a) < (b))  

#define lq(a, b)     ((a) > (b))  

//對字串型關鍵字  

#define eq(a, b)    (!strcmp((a), (b)))  

#define lt(a, b)     (strcmp((a), (b)) < 0)  

#define lq(a, b)     (strcmp((a), (b)) > 0) 

具體分析:

1、順序查詢。

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

效能分析:我們知道當討論乙個程式的效能時一般從3個角度:時間複雜度、空間複雜度、和演算法的其他效能。由於在查詢過程中,通常只是需要乙個固定大小的輔助空間來做比較,所以空間複雜度是一定的。而時間複雜度卻是可變的:其關鍵字和給定值進行過比較的記錄個數的平均值。

適用範圍:順序查詢一般適用於查詢資料比較少的情況下。

優點:

1、演算法實現簡單且適應面廣

2、對錶的結構無任何要求,無論記錄是否按關鍵字有序排列。

3、即適用於順序表又適用於單鏈表。

缺點:

1、平均查詢長度較大,特別是當n很大時,查詢效率較低。

2、速度慢,平均查詢長度為 (n + 1) / 2,時間複雜度為 o(n) 

[cpp]view plain

copy

print?

typedef

intelementtype;    

#define eq(a, b)  ((a) == (b))  

intsequential(

intarray, elementtype key, 

intn)    

return

-1;    

}    

2、折半查詢。

折半查詢:折半查詢又稱二分查詢,先確定待查記錄所在的範圍(區間),然後逐步縮小範圍直到找到或找不到該記錄為止。

適用範圍:對於規模較大的有序表查詢,效率較高。適合很少改動但經常查詢的表。

優點:

1、折半查詢的效率比順序查詢要高。

2、折半查詢的時間複雜度為log2(n)

3、折半查詢的平均查詢長度為log2(n+1) - 1

缺點:

1、折半查詢只適用於有序表

2、折半查詢限於順序儲存結構,對線性鍊錶無法有效地進行折半查詢     

關鍵字key與表中某一元素array[i]比較,有3中情況:

1. key == array[i], 查詢成功

2.key > array[i], 待查詢元素可能的範圍是array[i]之前

3.key < array[i], 待查詢元素可能的範圍是array[i]之後

[cpp]view plain

copy

print?

typedef

intelementtype;    

#define eq(a, b)  ((a) == (b))  

#define lt(a, b)  ((a) < (b))  

#define lq(a, b)  ((a) <= (b))  

intsearch_bin(elementtype array, 

intnum, 

intlength)    

return

-1;    

}    

3、分塊查詢。

分塊查詢:分塊查詢又稱索引順序查詢,它是順序查詢的一種改進方法。將n個資料元素「按塊有序」劃分為m塊(m<=n)。每一塊中的資料元素不必有序,但塊與塊之間必須「按塊有序」,即第1快中的任一元素的關鍵字都必須小於第2塊中任一元素的關鍵字;而第2塊中任一元素又都小於第3塊中的任一元素,……    

操作步驟:

1、先選取各快中的最大關鍵字構成乙個索引表

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

優點:在表中插入或刪除乙個記錄時,只要找到該記錄所在塊,就在該塊中進行插入或刪除運算(因快內無序,所以不需要大量移動記錄)。

缺點:增加了乙個輔助陣列的儲存空間和將初始表分塊排序的運算。

效能:介於順序查詢和二分查詢之間。

[cpp]view plain

copy

print?

#define max 3  

#define maxsize 18  

typedef

intelemtype;    

typedef

struct

indexitemindexitem;    

indexitem indexlist[max];    

elemtype mainlist[maxsize] = ;    

intsequential(indexitem indexlist, elemtype key)    

return

0;    

}    

intmainsequential(elemtype mainlist, 

intindex, elemtype key)    

for(i = num; i < num+indexlist[index-1].length; i++)    

return

-1;    

}    

除上面介紹的3種查詢方法,還有針對有序表的斐波那契查詢和插值查詢以及靜態樹表的查詢。

靜態查詢(順序查詢和折半查詢)

聽說過一句話,程式設計之久,除了資料結構和演算法什麼也不屬於我們。為了更好的學習資料結構和演算法,今天決定先把清華大學出版的資料結構 c語言版 書中的演算法實現一遍。現在開始第一彈。貴在堅持。順序查詢 演算法描述 include include 順序表的查詢 define eq a,b a b de...

靜態查詢(順序 折半)

include include void seqsearch int a,int r 順序查詢 if i 0 printf 元素所在位置 d n i else printf 沒有該元素!int binsearch1 int a,int r 折半查詢 非遞迴 return 0 int binsearc...

靜態查詢 順序查詢和折半查詢法

一 靜態查詢 只是起查詢或檢索的作用,不涉及插入 刪除,反之為動態查詢。二 順序查詢 順序查詢過程中往往設定監視哨,在查詢過程中不用每一步都檢查整個表是否查詢完畢。假設,每個元素的查詢概率相同,順序查詢成功時平均查詢長度為 n 1 2 順序查詢不成功時平均查詢長度為 n 1 4 考慮到查詢不成功的情...