在日常生活中,幾乎每天都要進行一些查詢的工作,在**簿中查閱某個人的**號碼;在電腦的資料夾中查詢某個具體的檔案等等。本節主要介紹用於查詢操作的資料結構——查詢表。
查詢表是由同一型別
的資料元素構成的集合。例如**號碼簿和字典都可以看作是一張查詢表。
一般對於查詢表有以下幾種操作:
在查詢表中只做查詢操作,而不改動表中資料元素,稱此類查詢表為靜態查詢表;反之,在查詢表中做查詢操作的同時進行插入資料或者刪除資料的操作,稱此類表為動態查詢表。
在查詢表查詢某個特定元素時,前提是需要知道這個元素的一些屬性。例如,每個人上學的時候都會有自己唯一的學號,因為你的姓名、年齡都有可能和其他人是重複的,唯獨學號不會重複。而學生具有的這些屬性(學號、姓名、年齡等)都可以稱為關鍵字。
關鍵字又細分為主關鍵字和次關鍵字。若某個關鍵字可以唯一地識別乙個資料元素時,稱這個關鍵字為主關鍵字,例如學生的學號就具有唯一性;反之,像學生姓名、年齡這類的關鍵字,由於不具有唯一性,稱為次關鍵字。
不同的查詢表,其使用的查詢方法是不同的。例如每個人都有屬於自己的朋友圈,都有自己的**簿,**簿中資料的排序方式是多種多樣的,有的是按照姓名的首字母進行排序,這種情況在查詢時,就可以根據被查詢元素的首字母進行順序查詢;有的是按照類別(親朋好友)進行排序。在查詢時,就需要根據被查詢元素本身的類別關鍵字進行排序。
具體的查詢方法需要根據實際應用中具體情況而定。靜態查詢表既可以使用順序表表示,也可以使用鍊錶結構表示。雖然乙個是陣列、乙個鍊錶,但兩者在做查詢操作時,基本上大同小異。
靜態查詢錶用順序儲存結構表示時,順序查詢的查詢過程為:從表中的最後乙個資料元素開始,逐個同記錄的關鍵字做比較,如果匹配成功,則查詢成功;反之,如果直到表中第乙個關鍵字查詢完也沒有成功匹配,則查詢失敗。
#includeusing namespace std;
typedef struct elemtype;
typedef struct sstable;
//建立查詢表
void creat(sstable **st,int length)
}//查詢表查詢的功能函式,其中key為關鍵字
int search_seq(sstable *st, int key)
int main()
else
return 0;
}
輸入表中的資料元素:
1 2 3 4 5 6
請輸入查詢資料的關鍵字:
2資料在查詢表中的位置為:2
使用監視哨對普通的順序表的遍歷演算法做了改進,在資料量大的情況下,能夠有效提高演算法的執行效率。折半查詢,也稱二分查詢,在某些情況下相比於順序查詢,使用折半查詢演算法的效率更高。但是該演算法的使用的前提是靜態查詢表中的資料必須是有序的。
例如,在這個查詢表使用折半查詢演算法查詢資料之前,需要首先對該表中的資料按照所查的關鍵字進行排序:
。
在折半查詢之前對查詢表按照所查的關鍵字進行排序的意思是:若查詢表中儲存的資料元素含有多個關鍵字時,使用哪種關鍵字做折半查詢,就需要提前以該關鍵字對所有資料進行排序。
#includeusing namespace std;
#define max_int 20
//int a[max_int];//儲存元素
int n;//陣列大小
int binarysearch(int a, int value)
} return -1;
}int main() ;//sorted arrays
n = 5;
int ans = binarysearch(a, 3);
if (ans == -1)cout << " not find " << endl;
else cout << ans + 1 << endl;
return 0;
}
注意:在做查詢的過程中,如果 left 和 right 的中間位置在計算時位於兩個關鍵字中間,即求得 mid 的位置不是整數,需要統一做取整操作。通過比較折半查詢的平均查詢長度,同前面介紹的順序查詢相對比,明顯折半查詢的效率要高。但是折半查詢演算法只適用於有序表,同時僅限於查詢錶用
順序儲存結構
表示。
當查詢表使用鏈式儲存結構
表示時,折半查詢演算法無法有效地進行比較操作(排序和查詢操作的實現都異常繁瑣)。
分塊查詢,也叫索引順序查詢,演算法實現除了需要查詢表本身之外,還需要根據查詢表建立乙個索引表。例如圖 1,給定乙個查詢表,其對應的索引表如圖所示:
圖中,查詢表中共 18 個查詢關鍵字,將其平均分為 3 個子表,對每個子表建立乙個索引,索引中包含中兩部分內容:該子表部分中最大的關鍵字以及第乙個關鍵字在總表中的位置,即該子表的起始位置。
建立的索引表要求按照關鍵字進行公升序排序,查詢表要麼整體有序,要麼分塊有序。
分塊有序
指的是第二個子表中所有關鍵字都要大於第乙個子表中的最大關鍵字,第三個子表的所有關鍵字都要大於第二個子表中的最大關鍵字,依次類推。
塊(子表)中各關鍵字的具體順序,根據各自可能會被查詢到的概率而定。如果各關鍵字被查詢到的概率是相等的,那麼可以隨機存放;否則可按照被查詢概率進行降序排序,以提高演算法執行效率。
所有前期準備工作完成後,開始在此基礎上進行分塊查詢。分塊查詢的過程分為兩步進行:
確定要查詢的關鍵字可能存在的具體塊(子表);
在具體的塊中進行順序查詢。
以圖中的查詢表為例,假設要查詢關鍵字 38 的具體位置。首先將 38 依次和索引表中各最大關鍵字進行比較,因為 22 < 38 < 48,所以可以確定 38 如果存在,肯定在第二個子表中。
由於索引表中顯示第二子表的起始位置在查詢表的第 7 的位置上,所以從該位置開始進行順序查詢,一直查詢到該子表最後乙個關鍵字(一般將查詢表進行等分,具體子表個數根據實際情況而定)。結果在第 10 的位置上確定該關鍵字即為所找。
tip:在第一步確定塊(子表)時,由於索引表中按照關鍵字有序,所有可以採用折半查詢演算法。而在第二步中,由於各子表中關鍵字沒有嚴格要求有序,所以只能採用順序查詢的方式。具體實現**:
#includeusing namespace std;
struct index newindex[3]; //定義結構體陣列
int search(int key, int a);
int cmp(const void *a, const void* b)
int main() ;
//確認模組的起始值和最大值
for (i = 0; i < 3; i++)
} }//對結構體按照 key 值進行排序
qsort(newindex, 3, sizeof(newindex[0]), cmp);
//輸入要查詢的數,並呼叫函式進行查詢
printf("請輸入您想要查詢的數:\n");
scanf("%d", &key);
k = search(key, a);
//輸出查詢的結果
if (k > 0)
else
return 0;
}int search(int key, int a)
if (i >= 3)
startvalue = newindex[i].start; //startvalue等於塊範圍的起始值
while (startvalue <= startvalue + 5 && a[startvalue] != key)
if (startvalue > startvalue + 5)
return startvalue;
}
請輸入您想要查詢的數:
22查詢成功!您要找的數在陣列中的位置是:7
分塊查詢演算法的執行效率受兩部分影響:
查詢塊的操作和塊內查詢的操作。查詢塊的操作可以採用順序查詢,也可以採用折半查詢(更優);塊內查詢的操作採用順序查詢的方式。相比於折半查詢,分塊查詢時間效率上更低一些;相比於順序查詢,由於在子表中進行,比較的子表個數會不同程度的減少,所有分塊查詢演算法會更優。
總體來說,分塊查詢演算法的效率介於順序查詢和折半查詢之間。
查詢表結構
select case when a.colorder 1 then d.name else null end 表名,a.colorder 字段序號,a.name 欄位名,case when columnproperty a.id,a.name,isidentity 1 then else end ...
查詢表結構
方法一 select 序號 c.column id,列名 c.name,是否主鍵 isnull idx.primarykey,n 資料型別 t.name,長度 c.max length,precision c.precision,小數字 c.scale,允許空 case when c.is null...
oracle 查詢表結構
通過資料字典來獲取,select table name,column name,data type,data length from user tab columns where table name not in select view name from user views and table...