查找算法:就是在是數據元素集合中查看是否存在於指定的關鍵字相等的元素。html
查找分爲兩種:靜態查找和動態查找。ios
1) 靜態查找:是指在數據元素集合中查找與給定的關鍵字相等的元素。算法
2) 動態查找:就是指在查找過程當中,若是數據元素集合中不存在與給定的關鍵字相等的元素,則將該元素插入到數據元素集合中。函數
靜態查找主要包括順序表、有序順序表和索引順序表的查找。spa
1) 順序表的查找,就是指從表的第一個元素與給定關鍵字比較,直到表的最後。指針
2) 有序順序表的查找,在查找的過程當中若是給定的關鍵字大於表的元素,就能夠中止查找,說明表中不存在該元素(假設表中的元素按照關鍵字從小到大排列,而且查找從第一個元素開始比較)code
3) 索引順序表的查找是爲主表創建一個索引,根據索引肯定元素所在的範圍,這樣能夠有效地提升查找的效率。orm
動態查找主要包括二叉排序樹、平衡二叉樹、B-樹和B+樹。htm
這些都是利用二叉樹和樹的特色對數據元素集合進行排序,經過將元素插入到二叉樹或樹中創建二叉樹或樹,而後經過對二叉樹或樹的遍歷按照從小到大輸出元素的序列。對象
散列表是利用散列函數的映射關係直接肯定要查找元素的位置,大大減小了與元素的關鍵字的比較次數。
創建散列表的方法主要有直接定址法、平方取中法、摺疊法和除留餘數法(最經常使用)等。
可是會存在衝突,解決衝突的最爲經常使用的方法主要有兩個:開放定址法和鏈地址法。
1.順序表的查找——順序查找
從表的一端開始,向另外一端逐個按要查找的值key 與關鍵碼key進行比較,若找到,查找成功,並給出數據元素在表中的位置;若整個表檢測完,仍未找到與關鍵碼相同的key值,則查找失敗,給出失敗信息。
說白了就是,從頭至尾,一個一個地比,找着相同的就成功,找不到就失敗。很明顯的缺點就是查找效率低。
【適用性】:適用於線性表的順序存儲結構和鏈式存儲結構。
平均查找長度=(n+1)/2.
【順序查找優缺點】:
缺點:是當n 很大時,平均查找長度較大,效率低;
優勢:是對錶中數據元素的存儲沒有要求。另外,對於線性鏈表,只能進行順序查找。
#include<iostream> using namespace std; #define MAX 11 typedef int key_type; typedef struct element { key_type key; //關鍵字 }elem; int seq_search(elem e[], key_type key, int n) { int i = 0; while(i < n && e[i].key != key) { i++; } if(i < n) return i; else return -1; } int main(int argc, char** argv) { elem linelist[MAX] = {1,5,9,7,12,11,10,8,6,2,3}; int n = 11; int i = 0; key_type key = 8; printf("線性表中的元素爲: \n"); while(i < n) { printf("%d\n",linelist[i].key); i++; } printf("\n關鍵字[%d]在線性表中的位置下標爲[%d]\n", key, seq_search(linelist, key, n)); getchar(); system("pause"); }
2.有序順序表的查找——折半查找
在有序表中,取中間元素做爲比較對象,若給定值與中間元素的關鍵碼key相等,則查找成功;若給定值小於中間元素的關鍵碼,則在中間元素的左半區繼續查找;若給定值大於中間元素的關鍵碼,則在中間元素的右半區繼續查找。不斷重複上述查找過程,直到查找成功,或所查找的區域無數據元素,查找失敗。
【步驟】
① low=0;high=length-1; // 設置初始區間
② 當low>high 時,返回查找失敗信息 // 表空,查找失敗
③ 當low<=high,mid=(low+high)/2; //肯定該區間的中點位置
a. 若key < elem[mid].key,high = mid-1;轉② // 查找在左半區進行
b. 若key > elem[mid].key,low = mid+1; 轉② // 查找在右半區進行
c. 若key = elem[mid].key,返回數據元素在表中位置 // 查找成功
有序表按關鍵碼排列以下:
3, 5, 6, 8, 9, 12, 17, 23, 30, 35, 39, 42
在表中查找關鍵碼爲9的數據元素:
#include<iostream> using namespace std; #define MAX 12 typedef int key_type; typedef struct element { key_type key; //關鍵字 }elem; int binary_search(elem e[], key_type key, int n) { int low = 0, high = n - 1; int mid; while(low <= high) { mid = (low + high)/2; if(e[mid].key == key) return mid; else if(key < e[mid].key) high = mid - 1; else low = mid + 1; } return -1; //沒找到 } int main(int argc, char** argv) { elem linelist[MAX] = {3,5,6,8,9,12,17,23,30,35,39,42}; int n = 12; int i = 0; key_type key = 9; printf("線性表中的元素爲: \n"); while(i < n) { printf("%d\n",linelist[i].key); i++; } printf("\n關鍵字[%d]在線性表中的位置下標爲[%d]\n", key, binary_search(linelist, key, n)); getchar(); system("pause"); }
3.分塊查找(索引查找)
分塊查找又稱索引順序查找,是對順序查找的一種改進。分塊查找要求將查找表分紅 若干個子表,並對子表創建索引表,查找表的每個子表由索引表中的索引項肯定。索引項包括兩個字段:關鍵碼字段(存放對應子表中的最大關鍵碼值) ;指針字段(存放指向對 應子表的指針) ,而且要求索引項按關鍵碼字段有序。查找時,先用給定值key 在索引表中 檢測索引項,以肯定所要進行的查找在查找表中的查找分塊(因爲索引項按關鍵碼字段有序,可用順序查找或折半查找) ,而後,再對該分塊進行順序查找。
如關鍵碼集合爲:
(8, 20, 13, 17, 40, 42, 45, 32, 49, 58, 50, 52, 67, 79, 78, 80)
按關鍵碼值20,45,58, 80分爲四塊創建索引表。
設表共n個結點,分b塊,s=n/b
(分塊查找索引表)平均查找長度=Log2(n/s+1)+s/2
(順序查找索引表)平均查找長度=(S2+2S+n)/(2S)
#include<iostream> using namespace std; #define MAX 16 typedef int key_type; struct elem { key_type key; //關鍵字 }; //索引結構 struct index { key_type key; //索引值 long low; //起始位置 long high; //終止位置 }; int index_search(elem e[], key_type key, int n, index idx[], int idx_length) { int low = 0; int high = idx_length - 1; int mid; //採用折半查找在索引表裏找到關鍵字所在的塊 while(low <= high) { mid = (low + high)/2; if(key < idx[mid].key) high = mid - 1; else if(key > idx[mid].key) low = mid + 1; else break; } //採用順序查找的方法從塊中查找關鍵值 int i = idx[mid].low; while(i <= idx[mid].high && e[i].key != key) { i++; } if(i > idx[mid].high) return -1; else return i; } int main(int argc, char** argv) { elem linelist[MAX] = { 8, 20, 13, 17, 40, 42, 45, 32, 49, 58, 50, 52, 67, 79, 78, 80 }; int n = sizeof(linelist) / sizeof(elem); key_type key = 50; //創建索引表 index index_table[4] = {{20,0,3}, {45,4,7}, {58,8,11}, {80,12,15}}; int idx_length = sizeof(index_table) / sizeof(index); printf("線性表中的元素爲:\n"); int i = 0; while(i < n) { printf("%d\n",linelist[i].key); i++; } printf("\n關鍵字[%d]在線性表中的位置下標爲[%d]", key, index_search(linelist, key, n, index_table, idx_length)); getchar(); system("pause"); }