第七章 查找技术
7.1概述
7.1.1查找的基本概念
1.關鍵碼
關鍵碼:可以標識一個記錄的某個數據項。?
?鍵值:關鍵碼的值。
?主關鍵碼:可以唯一地標識一個記錄的關鍵碼。
?次關鍵碼:不能唯一地標識一個記錄的關鍵碼
2.查找
查找 :在具有相同類型的記錄構成的集合中找出滿足給定條件的記錄。?
?給定的查找條件可能是多種多樣的,為便于討論,把查找條件限制為“匹配”,即查找關鍵碼等于給定值的記錄。?
查找的結果 :若在查找集合中找到了與給定值相匹配的記錄,則稱查找成功;否則,稱查找失敗
靜態查找 :不涉及插入和刪除操作的查找 。
?動態查找 :涉及插入和刪除操作的查找。
靜態查找適用于:查找集合一經生成,便只對其進行查找,而不進行插入和刪除操作,或經過一段時間的查找之后,集中地進行插入和刪除等修改操作;
動態查找適用于:查找與插入和刪除操作在同一個階段進行,例如當查找成功時,要刪除查找到的記錄,當查找不成功時,要插入被查找的記錄。
查找結構 :面向查找操作的數據結構 ,即查找基于的數據結構。
?線性表:適用于靜態查找,主要采用順序查找技術和折半查找技術。
?樹表:適用于動態查找,主要采用二叉排序樹的查找技術。
?散列表:靜態查找和動態查找均適用,主要采用散列技術。?
7.2線性表的查找順序
1.順序查找
基本思想:從線性表的一端向另一端逐個將關鍵碼與給定值進行比較,若相等,則查找成功,給出該記錄在表中的位置;若整個表檢測完仍未找到與給定值相等的關鍵碼,則查找失敗,給出失敗信息。
int SeqSearch1(int r[ ], int n, int k)
//數組r[1] ~ r[n]存放查找集合
{ ??
? ? ?i = n;
? ? ?while (i > 0 && r[i] != k)
? ? ? ? ?i--;
? ? ?return i;
}
順序查找的優缺點:
優點:算法簡單而且使用面廣
對表中記錄的存儲沒有任何要求,順序存儲和鏈接存儲均可;
對表中記錄的有序性也沒有要求,無論記錄是否按關鍵碼有序均可。
缺點:平均查找長度較大,特別是當待查找集合中元素較多時,查找效率較低。
2.折半查找
基本思想:在有序表中,取中間記錄作為比較對象,若給定值與中間記錄的關鍵碼相等,則查找成功;若給定值小于中間記錄的關鍵碼,則在中間記錄的左半區繼續查找;若給定值大于中間記錄的關鍵碼,則在中間記錄的右半區繼續查找。不斷重復上述過程,直到查找成功,或所查找的區域無記錄,查找失敗。
折半查找——非遞推算法
int BinSearch1(int r[ ], int n, int k)
{ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//數組r[1] ~ r[n]存放查找集合
? ? low = 1; high = n;
? ? while (low <= high) ? ? ? ? ? ? ? ? ??
? ? {
? ? ? ?mid = (low + high) / 2; ? ? ? ? ? ?
? ? ? ?if (k < r[mid]) ?high = mid - 1;
? ? ? ?else if (k > r[mid]) ?low = mid + 1;?
? ? ? ? ? ? ? else return mid;
? ? }
? ? return 0;
}
折半查找——遞推算法
int BinSearch2(int r[ ], int low, int high, int k)
{ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//數組r[1] ~ r[n]存放查找集合
? ? if (low > high) return 0; ?
? ? else {
? ? ? ?mid = (low + high) / 2;
? ? ? ?if (k < r[mid])?
? ? ? ? ? ?return BinSearch2(r, low, mid-1, k);
? ? ? ?else ?if (k > r[mid])?
? ? ? ? ? ? ? ? ? ?return BinSearch2(r, mid+1, high, k);?
? ? ? ? ? ? ? ?else return mid;
? ? ?}
?}
折半查找判定樹
判定樹:折半查找的過程可以用二叉樹來描述,樹中的每個結點對應有序表中的一個記錄,結點的值為該記錄在表中的位置。通常稱這個描述折半查找過程的二叉樹為折半查找判定樹,簡稱判定樹。
判定樹的構造方法
⑴ 當n=0時,折半查找判定樹為空;
⑵ 當n>0時,折半查找判定樹的根結點是有序表中序號為mid=(n+1)/2的記錄,根結點的左子樹是與有序表r[1] ~ r[mid-1]相對應的折半查找判定樹,根結點的右子樹是與r[mid+1] ~ r[n]相對應的折半查找判定樹。?
7.3數表的查找技術
1.二叉查找樹
二叉排序樹(也稱二叉查找樹):或者是一棵空的二叉樹,或者是具有下列性質的二叉樹:
⑴ 若它的左子樹不空,則左子樹上所有結點的值均小于根結點的值;
⑵ 若它的右子樹不空,則右子樹上所有結點的值均大于根結點的值;
⑶ 它的左右子樹也都是二叉排序樹。
二叉樹的構造算法
BiSortTree::BiSortTree(int r[ ], int n)
{ ? ??
? ? for (i = 0; i < n; i++)
? ? {
? ? ? ?s = new BiNode<int>;?
? ? ? ?s->data = r[i];
? ? ? ?s->lchild = s->rchild = NULL;
? ? ? ?InsertBST(root, s);
? ? }
}
小結
一個無序序列可以通過構造一棵二叉排序樹而變成一個有序序列;
每次插入的新結點都是二叉排序樹上新的葉子結點;
找到插入位置后,不必移動其它結點,僅需修改某個結點的指針;
在左子樹/右子樹的查找過程與在整棵樹上查找過程相同;
新插入的結點沒有破壞原有結點之間的關系。
二叉排序樹的查找
BiNode *BiSortTree::SearchBST(BiNode<int> *root, int k)
{
? ? if (root == NULL)
? ? return NULL;
? ? else if (root->data == k)?
? ? ? ? ? ? ? return root;
? ? ? ? ? ?else if (k < root->data)?
? ? ? ? ? ? ? ? ? ? ? return SearchBST(root->lchild, k);
? ? ? ? ? ? ? ? ? else return SearchBST(root->rchild, k);
}
2.平衡二叉樹
平衡二叉樹:或者是一棵空的二叉排序樹,或者是具有下列性質的二叉排序樹:
⑴ 根結點的左子樹和右子樹的深度最多相差1;
⑵ 根結點的左子樹和右子樹也都是平衡二叉樹。
7.4散列表的查找技術
散列的基本思想:在記錄的存儲地址和它的關鍵碼之間建立一個確定的對應關系。這樣,不經過比較,一次讀取就能得到所查元素的查找方法。
散列表:采用散列技術將記錄存儲在一塊連續的存儲空間中,這塊連續的存儲空間稱為散列表。
散列函數:將關鍵碼映射為散列表中適當存儲位置的函數。
散列技術一般不適用于允許多個記錄有同樣關鍵碼的情況。散列方法也不適用于范圍查找,換言之,在散列表中,我們不可能找到最大或最小關鍵碼的記錄,也不可能找到在某一范圍內的記錄。
散列技術的關鍵問題:
⑴ 散列函數的設計。如何設計一個簡單、均勻、存儲利用率高的散列函數。
⑵ 沖突的處理。如何采取合適的處理沖突方法來解決沖突。
沖突:對于兩個不同關鍵碼ki≠kj,有H(ki)=H(kj),即兩個不同的記錄需要存放在同一個存儲位置,ki和kj相對于H稱做同義詞。
設計散列函數一般應遵循以下原則:
⑴ 計算簡單。散列函數不應該有很大的計算量,否則會降低查找效率。
⑵ 函數值即散列地址分布均勻。函數值要盡量均勻散布在地址空間,這樣才能保證存儲空間的有效利用并減少沖突。
總結
- 上一篇: IFI Claims:2018年中国企业
- 下一篇: AH快递单打印查询软件V3.68