67 線性表的查詢

2021-08-22 03:19:35 字數 3970 閱讀 5009

線性表的查詢主要有:順序查詢,二分查詢,分塊查詢。

通過前面的學習可知,線性表有順序和鏈式兩種儲存結構,而這裡我們主要是介紹的線性表查詢演算法是基於順序儲存結構的,其順序表的儲存型別定義:

#define maxl 100

typedef

int keytype;

typedef

char infotype[10];

typedef

struct

nodetype;

typedef nodetype seqlist[maxl]; //查詢順序表型別

例如,查詢表:3 9 1 5 8 10 6 7 2 4,要查詢的值:k=10

圖1-順序查詢

順序查詢思路如圖1所示:

從表的一端開始,順序掃瞄線性表,依次將掃瞄到的關鍵字和給定值k相比較。若當前掃瞄到的關鍵字與k相等,則查詢成功;若掃瞄結束後,仍未找到關鍵字等於k的記錄,則查詢失敗。

順序查詢:

/*

順序查詢:

引數r表示要查詢的順序表

n表示元素個數

k表示要查詢的元素

*/int seqsearch(seqlist r , int n , keytype key)

}return -1;

}

折半查詢也稱為二分查詢,要求線性表中的節點,按關鍵字值的遞增或遞減順序排列。

圖2-折半查詢

2 . 遞迴進行下去,直到找到滿足條件的節點或者該線性表中沒有這樣的節點。

折半查詢演算法實現:

/*

引數r表示要查詢的順序表

引數n表示元素個數

引數k表示要查詢的元素

*/int binsearch(seqlist r,int n,keytype k)

//否則繼續在[high ... mid - 1]中查詢

if (r[mid].key>k)

//繼續在[low ... mid - 1]中查詢

else

}//查詢失敗則返回0

return

0;}

二分查詢演算法遞迴版實現:

/*

二分查詢的遞迴版演算法

low表示開始下標

high表示結尾下標

*/int binsearch1(seqlist r,int low,int high,keytype k)

if (r[mid].key>k)

else

}return

0 ;}

二分查詢的特點:利用了順序查詢的有序性,使得查詢過程得到提高。

圖3-資料表

上圖中有乙個城市的資料表,其中區號是作為資料表中的關鍵字,資料表中的區號是無序的,當我們要從這張資料表中去查詢乙個城市的資料,應該怎麼去查詢呢?

根據我們前面學過的查詢演算法可知,有兩種:順序查詢和折半查詢。

對於順序查詢來說,當資料表中的資料量非常大的時候,需要乙個乙個的去查詢資料,直到查詢到資料為止,顯然順序查詢的效率是比較低。折半查詢也存在同樣的問題,因為折半查詢的資料前提是有序的,但是對於大量的資料進行排序卻是非常耗時的,因此折半查詢的效率也是非常低的。

圖4-索引儲存結構

當資料量非常大時,在實際的應用中更多的是採用索引儲存結構來實現,而索引儲存結構一般是由索引表和資料表組成的。

我們可以知道索引儲存結構,這種解決方案是通過索引表來查詢資料的,也就是說,當我們在索引表中查詢到資料的索引項時,直接通過索引項中儲存的位址,就可以從資料表中訪問到對應的城市資料。特別是針對資料量非常大的時候,避免了直接查詢資料表,從而提高查詢效率。

下面通過乙個例子來說明分塊查詢

假設有乙個線性表,其中包含23個記錄:

關鍵字序列:8 , 14 , 6 , 9 , 10 , 22 , 34 , 18 , 19 , 31 , 40 , 38 , 54 , 66 , 46 , 71 , 78 , 68 , 80 , 85 , 99 , 94 , 88

我們要做的就是將23個記錄分為5塊,每塊中有5個記錄,在進行分塊時,需要滿足以下幾個條件:

1. 將資料表r中23個記錄均分為b塊,前b-1塊中,每塊的記錄個數為5,但是最後一塊即第b塊的記錄數小於等於5;

2 . 每一塊中的關鍵字不一定有序,但前一塊中的最大關鍵字必須小於後一塊中的最小關鍵字,即要求表是「分塊有序」的。

3 . 抽取各塊中的最大關鍵字,構建索引表idx, 在索引表idx中的link存放著第i塊在表r中的起始位置,而索引表idx中的key存放著每一塊中的最大關鍵字,由於表r是分塊有序的,所以索引表是乙個遞增有序表。

最後構建成的分塊索引表如下所示:

圖5-索引儲存結構

當我們在這樣的分塊索引表中查詢就可以這樣做:

1 . 先在索引表中查詢關鍵字所在的塊,由於索引表中的塊是有序的,因此可以利用折半查詢,也可以利用順序查詢,比如查詢關鍵字為80的,即 66< 80 < 85,在第4個分塊中。

2 . 於是再根據分塊中的link找到分塊中的關鍵字起始位置,由於分塊內的關鍵字是無序的,因此只能通過順序查詢。比如找到第4塊的關鍵字起始位置(71),通過順序查詢逐個比較,最終在第四次查詢中找到了關鍵字為80的。

由此可知,在索引表中順序查詢的話,需要查詢4次,在對應的塊中查詢,需要查詢4次,加起來總共需要8次比較。但如果我們直接在資料表r中採用順序查詢的話,總共需要19次才能找到。也就是說,分塊查詢的效能是介於順序查詢和折半查詢之間的

儲存結構:

#define maxl    100 //資料表的最大長度

#define maxi 20 //索引表的最大長度

typedef

int keytype;

typedef

char infotype[10];

typedef

struct

nodetype;

typedef nodetype seqlist[maxl]; //資料表型別

seqlist r;

typedef

struct

idxtype;

typedef idxtype idx[maxi]; //索引表型別

idx idx;

分塊查詢演算法實現:

//m表示陣列i(索引表)中的元素個數

//n表示陣列r(資料表)中的元素個數

//k表示要查詢的關鍵字

int idxsearch(idx i , int m , seqlist r , int n , keytype k)

//在資料表中順序查詢

i = i[high+1].link;

while (i <= i[high+1].link+b-1 && r[i].key != k)

i++;

//如果找到了則返回關鍵字的邏輯下標+1

if (i <= i[high+1].link+b-1)

return i+1;

//否則沒找到就返回0

else

return

0;}

線性表查詢

查詢的基本概念 廣義地講 查詢是在具有相同型別的記錄構成的集合中找出滿足給定條件的記錄。給定的查詢條件可能是多種多樣的,為了便於討論,我們把查詢條件限制為 匹配 即在查詢關鍵碼等於給定值的記錄。順序查詢 順序查詢又稱線性查詢,是最基本的查詢技術之一,其基本思想為 從線性表的一端向另外一端逐個將關鍵碼...

查詢 線性表的查詢

標頭檔案 sqlistsearch.h include const int maxsize 100 順序表中最多元素個數 template struct rectype 順序表記錄型別 template struct idxtype 索引表型別 template class sqlistsearch...

查詢 線性表的查詢技術

查詢基本概念 列表 由同一型別的資料元素組成的集合。關鍵碼 資料元素中的某個資料項,可以標識列表中的乙個或一組資料元素。鍵值 關鍵碼的值。主關鍵碼 可以唯一地標識乙個記錄的關鍵碼。次關鍵碼 不能唯一地標識乙個記錄的關鍵碼。查詢 在具有相同型別的記錄構成的集合中找出滿足給定條件的記錄。查詢的結果 若在...