【筆記】靜態查詢演算法
關鍵字與主關鍵字:資料元素中某個資料項的值。如果該關鍵字可以將所有的資料元素區別開來,也即可以唯一標識一個資料元素,則該關鍵字稱為主關鍵字,否則稱為次關鍵字。特別地,如果資料元素只有一個資料項,則資料元素的值即是關鍵字。
查詢表:是由同種型別的資料元素構成的集合。查詢表中的資料元素是完全鬆散的,資料元素之間沒有直接的聯絡。
查詢:根據關鍵字在特定的查詢表中找到一個與給定關鍵字相同的資料元素的操作。如果在表中找到相應的資料元素,則稱查詢是成功的,否則稱查詢是失敗的。
對查詢表經常進行的操作有查詢某個“特定的”資料元素是否在查詢表中、檢索某個“特定的”資料元素的各種屬性、在查詢表中插入一個資料元素、從查詢表中刪除某個資料元素。若對查詢表只進行前兩種操作,則稱此類查詢表為靜態查詢表,相應的查詢方法稱為靜態查詢。若在查詢過程中同時插入查詢表中不存在的資料元素,或者從查詢表中刪除已存在的某個資料元素,則稱此類查詢為動態查詢表,相應的查詢方法為動態查詢。
平均查詢長度:是指在查詢過程中,需要比較關鍵字的平均次數,它是衡量查詢演算法的效率標準。平均查詢長度的數學定義式為
1.順序表的查詢
順序表的查詢過程為從表的一端開始,逐個與關鍵字進行比較,若某個資料元素的關鍵字與給定的關鍵字相等,則查詢成功,函式返回該資料元素所在的順序表的位置;否則查詢失敗,返回0。
- 型別定義檔案
#define MaxSize 100
typedef int KeyType;
typedef struct /*元素的定義*/
{
KeyType key;
}DataType;
typedef struct /*順序表的型別定義*/
{
DataType list[MaxSize];
int length;
}SSTable;
- 順序查詢函式
int SeqSearch(SSTable S,DataType x)
/*在順序表中查詢關鍵字為x的元素,如果找到返回該元素在表中的位置,否則返回0*/
{
int i=0;
while(i<S.length&&S.list[i].key!=x.key) /*從順序表的第一個元素開始比較*/
i++;
if(S.list[i].key==x.key)
return i+1;
else
return 0;
}
以上演算法也可以通過設定監視哨的方法實現:
int SeqSearch2(SSTable S,DataType x)
{
/*設定監視哨S.list[0],在順序表中超找關鍵字為x的元素,如果找到返回該元素在表中的位置,否則返回0*/
int i=S.length;
S.list[0].key=x.key; /*將關鍵字存放在第0號位置,防止越界*/
while(S.list[i].key!=x.key)/*從順序表的最後一個元素開始向前比較*/
i--;
return i;
}
其中S.list[0]被稱為監視哨,可以防止出現陣列越界。
假設表中有n個資料元素,且資料元素在表中出現的概率都相等,即
2.有序順序表的查詢
有序順序表就是順序表中的元素是以關鍵字進行有序排列的。對於有序順序表的查詢有兩種方法,即順序查詢和折半查詢。
順序查詢
有序順序表的查詢演算法與順序表的查詢演算法類似。在通常情況下,無須比較表中的所有元素。如果要查詢的元素在表中,則返回該元素的標號,否則返回0。
int SeqSearch3(SSTable S,DataType x)
{
/*設定監視哨S.list[0],在有序順序表中查詢關鍵字為x的元素,如果找到返回該元素在表中的位置,否則返回0*/
int i=S.length;
S.list[0].key=x.key;/*將關鍵字存放在第0號位置,防止越界*/
while(S.list[i].key>x.key)/*從有序順序表的最後一個元素開始向前比較*/
i--;
return i;
}
設表中有n個資料元素,且資料元素在表中出現的概率都相等,即
折半查詢
又稱為二分查詢,這種查詢演算法要求待查詢的元素序列必須是從小到大排列的有序序列。
折半查詢即將待查詢的元素與表中的元素進行比較,如果兩者相等,在說明查詢成功,否則利用中間位置將表分成兩個部分;如果待查詢元素小於中間位置的元素值,則繼續與前一個子表的中間位置元素進行比較,否則與後一個子表的中間位置進行比較;不斷重複以上操作,直到找到與待查詢元素相等的元素,表明查詢成功;如果子表變為空表,表明查詢失敗。
例如一個有序順序表為(9,23,26,32,36,47,56,63,79,81),如果要查詢的元素為56,利用折半查詢演算法的查詢過程如下:
圖中low和high兩個指標,分別指向待查詢元素的下界和上界,指標mid指向low和high的中間位置,即mid=(low+high)/2。
int BinarySearch(SSTable S,DataType x)
/*在有序順序表中折半查詢關鍵字為x的元素,如果找到返回該元素在表中的位置,否則返回0*/
{
int low,high,mid;
low=0,high=S.length-1; /*設定待查詢元素範圍的下界和上界*/
while(low<=high)
{
mid=(low+high)/2;
if(S.list[mid].key==x.key) /*如果找到元素,則返回該元素所在的位置*/
return mid+1;
else if(S.list[mid].key<x.key)/*如果mid所指示的元素小於關鍵字,則修改low指標*/
low=mid+1;
else if(S.list[mid].key>x.key)/*如果mid所指示的元素大於關鍵字,則修改high指標*/
high=mid-1;
}
return 0;
}
整個查詢過程可以用一個判定樹來描述。
如果表中有n個元素,折半查詢成功時,至多需要比較的次數為
對於具有n個結點的有序表(恰好構成一個深度為h的滿二叉樹)來說,有
3.索引順序表的查詢
當順序表的資料量非常大時,無論使用前述哪種查詢演算法都需要很長的時間,此時提高查詢效率的一個常用方法就是在順序表中建立索引表。建立索引表的方法就是將順序表分成幾個單元,然後分別為這幾個單元建立一個索引,原來的順序表稱為主表,提供索引的表稱為索引表。索引表中只存放主表中要查詢的資料元素的主關鍵字和索引資訊。
如下圖所示,其中索引表包括兩部分,即順序表中每個單元的最大關鍵字和順序表中每個單元的第一個元素的下標。
這樣的表稱為索引順序表,要使查詢效率高,索引表必須有序,但主表中的元素不一定要按關鍵字有序排列。索引順序表的查詢也稱為分塊查詢。
如果主表中米格單元中的元素個數是不相等,就需要在索引表中增加一項,即用來儲存主表中每個單元元素的個數,將這種利用索引表示的順序表稱為不等長索引順序表。
int SeqIndexSearch(SSTable S,IndexTable T,int m,DataType x)
/*在主表S中查詢關鍵字為x的元素,T為索引表。如果找到返回該元素在表中的位置,否則返回0*/
{
int i,j,bl;
for(i=0;i<m;i++) /*通過索引表確定要查詢元素所在的單元*/
if(T[i].maxkey>=x.key)
break;
if(i>=m) /*如果要查詢的元素不在索引順序表中,則返回0*/
return 0;
j=T[i].index; /*要查詢的元素在的主表的第j單元*/
if(i<m-1) /*bl為第j單元的長度*/
bl=T[i+1].index-T[i].index;
else
bl=S.length-T[i].index;
while(j<T[i].index+bl)
if(S.list[j].key==x.key)/*如果找到關鍵字,則返回該關鍵字在主表中所在的位置*/
return j+1;
else
j++;
return 0;
}
因索引表中的元素的關鍵字是有序的,故在確定元素所在主表的單元時,既可採用順序查詢發也可採用折半查詢法,但對於主表,只能採用順序法查詢。索引順序表的平均查詢長度可以表示為
假設主表中的元素個數為n,並將主表平均分為b個單元,且每個單元有s個元素,即b=n/s。如果表中的元素查詢概率相等,則每個單元中元素的查詢概率就是1/s,主表中每個單元的查詢概率是1/b。如果用順序查詢法查詢索引表中的元素,則索引順序表查詢成功時的平均查詢長度為
如果用折半查詢法查詢索引表中的元素,則有
4.靜態查詢應用例項
給定一組元素序列,利用順序表查詢、有序順序表查詢和索引順序表查詢值x的元素。
- 型別定義檔案
#define MaxSize 100
#define IndexSize 20
typedef int KeyType;
typedef struct /*元素的定義*/
{
KeyType key;
}DataType;
typedef struct /*順序表的型別定義*/
{
DataType list[MaxSize];
int length;
}SSTable;
typedef struct /*索引表的型別定義*/
{
KeyType maxkey;
int index;
}IndexTable[IndexSize];
- 查詢函式檔案
int SeqSearch(SSTable S,DataType x)
/*在順序表中查詢關鍵字為x的元素,如果找到返回該元素在表中的位置,否則返回0*/
{
int i=0;
while(i<S.length&&S.list[i].key!=x.key) /*從順序表的第一個元素開始比較*/
i++;
if(S.list[i].key==x.key)
return i+1;
else
return 0;
}
int BinarySearch(SSTable S,DataType x)
/*在有序順序表中折半查詢關鍵字為x的元素,如果找到返回該元素在表中的位置,否則返回0*/
{
int low,high,mid;
low=0,high=S.length-1; /*設定待查詢元素範圍的下界和上界*/
while(low<=high)
{
mid=(low+high)/2;
if(S.list[mid].key==x.key) /*如果找到元素,則返回該元素所在的位置*/
return mid+1;
else if(S.list[mid].key<x.key)/*如果mid所指示的元素小於關鍵字,則修改low指標*/
low=mid+1;
else if(S.list[mid].key>x.key)/*如果mid所指示的元素大於關鍵字,則修改high指標*/
high=mid-1;
}
return 0;
}
int SeqIndexSearch(SSTable S,IndexTable T,int m,DataType x)
/*在主表S中查詢關鍵字為x的元素,T為索引表。如果找到返回該元素在表中的位置,否則返回0*/
{
int i,j,bl;
for(i=0;i<m;i++) /*通過索引表確定要查詢元素所在的單元*/
if(T[i].maxkey>=x.key)
break;
if(i>=m) /*如果要查詢的元素不在索引順序表中,則返回0*/
return 0;
j=T[i].index; /*要查詢的元素在的主表的第j單元*/
if(i<m-1) /*bl為第j單元的長度*/
bl=T[i+1].index-T[i].index;
else
bl=S.length-T[i].index;
while(j<T[i].index+bl)
if(S.list[j].key==x.key)/*如果找到關鍵字,則返回該關鍵字在主表中所在的位置*/
return j+1;
else
j++;
return 0;
}
- 主程式
#include<stdio.h>
#include<stdlib.h>
void main()
{
SSTable S1={{265,55,15,67,9,64,88,50},8};
SSTable S2={{20,28,37,40,46,55,64,76},8};
SSTable S3={{12,8,26,20,19,40,29,43,35,33,56,50,63,55,58,75,64,66,85,79},20};
IndexTable T={{26,0},{43,5},{63,10},{85,15}};
DataType x={64};
int pos;
if((pos=SeqSearch(S1,x))!=0)
printf("順序表的查詢:關鍵字32在主表中的位置是:%2d\n",pos);
else
printf("查詢失敗!\n");
if((pos=BinarySearch(S2,x))!=0)
printf("折半查詢:關鍵字32在主表中的位置是:%2d\n",pos);
else
printf("查詢失敗!\n");
if((pos=SeqIndexSearch(S3,T,4,x))!=0)
printf("索引順序表的查詢:關鍵字32在主表中的位置是:%2d\n",pos);
else
printf("查詢失敗!\n");
}
- 測試結果
相關文章
- 查詢(1)--靜態查詢
- DS靜態查詢之順序查詢
- 靜態方法查詢類名
- Spring Data Jpa 的簡單查詢多表查詢HQL,SQL ,動態查詢, QueryDsl ,自定義查詢筆記SpringSQL筆記
- RMAN筆記之查詢rman備份資訊狀態筆記
- MYSQL學習筆記25: 多表查詢(子查詢)[標量子查詢,列子查詢]MySql筆記
- 漏洞挖掘-靜態分析實驗筆記筆記
- MYSQL學習筆記26: 多表查詢|子查詢MySql筆記
- Object C學習筆記10-靜態方法和靜態屬性Object筆記
- 一種期望線性的靜態區間查詢
- 查詢(2)--動態查詢
- 子查詢學習筆記1筆記
- 【vue隨手筆記】Vue設定靜態常量Vue筆記
- 偽靜態和重定向(apache)學習筆記Apache筆記
- PHP學習筆記——延遲靜態繫結PHP筆記
- 查詢演算法集:順序查詢、二分查詢、插值查詢、動態查詢(陣列實現、連結串列實現)演算法陣列
- (MySQL學習筆記)分頁查詢MySql筆記
- es 筆記二之基礎查詢筆記
- EntityFramework Core筆記:查詢資料(3)Framework筆記
- 查詢演算法__插值查詢演算法
- ES 筆記三十四:剖析分散式查詢及相關性演算法筆記分散式演算法
- MYSQL學習筆記24: 多表查詢(聯合查詢,Union, Union All)MySql筆記
- php頁面靜態化技術;學習筆記PHP筆記
- HTML+CSS編寫靜態網站-37 媒體查詢初探HTMLCSS網站
- 查詢演算法__二分查詢演算法
- 查詢演算法__Fibonacci查詢演算法
- ReactFlow程式碼靜態檢查React
- PLSQL Language Referenc-PL/SQL靜態SQL-帶有子查詢的查詢結果集處理SQL
- oracle學習筆記(十一) 高階查詢Oracle筆記
- 筆記 mongo查詢慢日誌,建立索引筆記Go索引
- Jive筆記8--查詢的Bug (轉)筆記
- 查詢演算法演算法
- 演算法 - 查詢演算法
- 演算法(查詢)演算法
- #查詢演算法#【1】簡單查詢:順序、折半查詢演算法
- [演算法學習筆記] 並查集演算法筆記並查集
- 筆記: 判斷lib庫是動態庫還是靜態庫筆記
- 查詢演算法之二分查詢演算法