數據結構49:順序查找算法


通過前面對靜態查找表的介紹,靜態查找表即為只做查找操作的查找表。

靜態查找表既可以使用順序表表示,也可以使用鏈表結構表示。雖然一個是數組、一個鏈表,但兩者在做查找操作時,基本上大同小異。

本節以靜態查找表的順序存儲結構為例做詳細的介紹。

順序查找的實現

靜態查找表用順序存儲結構表示時,順序查找的查找過程為:從表中的最后一個數據元素開始,逐個同記錄的關鍵字做比較,如果匹配成功,則查找成功;
反之,如果直到表中第一個關鍵字查找完也沒有成功匹配,則查找失敗。

順序查找的具體實現代碼為:
#include <stdio.h>
#include <stdlib.h>
#define keyType int
typedef struct
{ keyType key;  
//查找表中每個數據元素的值 //如果需要,還可以添加其他屬性 }ElemType; typedef struct
{ ElemType *elem;  // 存放查找表中數據元素的數組 int length;   // 記錄查找表中數據的總數量 }SSTable; // 創建查找表 void Create(SSTable **st, int length)
{ (
*st) = (SSTable*)malloc(sizeof(SSTable)); (*st)->length = length; printf("輸入表中的數據元素:\n"); // 根據查找表中數據元素的總長度,在存儲時,從數組下標為 1 的空間開始存儲數據 for (int i=1; i<=length; i++)
   { scanf(
"%d", &((*st)->elem[i].key)); } }
// 查找表查找的功能函數,其中key為關鍵字 int Search_seq(SSTable *st, keyType key)
{ st
->elem[0].key = key;  // 將關鍵字作為一個數據元素存放到查找表的第一個位置,起監視哨的作用 int i = st->length; // 從查找表的最后一個數據元素依次遍歷,一直遍歷到數組下標為0 while (st->elem[i].key != key)
  { i
--; } //如果 i=0,說明查找失敗;反之,返回的是含有關鍵字key的數據元素在查找表中的位置 return i; }
int main(int argc, const char * argv[])
{ SSTable
*st; Create(&st, 6); getchar(); printf("請輸入查找數據的關鍵字:\n"); int key; scanf("%d", &key); int location=Search_seq(st, key); if (location == 0)
   { printf(
"查找失敗"); }
   else
   { printf("數據在查找表中的位置為:%d", location); }
return 0; }
可運行代碼中設置了一個固定長度為
6 的順序表,例如在查找表為{1,2,3,4,5,6}找到關鍵字為 1 的數據元素的位置,則運行效果為: 輸入表中的數據元素: 1 2 3 4 5 6 請輸入查找數據的關鍵字: 2 數據在查找表中的位置為:2

 

同時,在程序中初始化創建查找表時,由於是順序存儲,所以將所有的數據元素存儲在數組中,但是把第一個位置留給了用戶用於查找的關鍵字。例如,在順序表 {1,2,3,4,5,6}中查找數據元素值為 7 的元素,則添加后的順序表為:

圖 1 順序表中的監視哨

順序表的一端添加用戶用於搜索的關鍵字,稱作“監視哨”。
圖 1 中監視哨的位置也可放在數據元素 6 的后面(這種情況下,整個查找的順序應有逆向查找改為順序查找)。
放置好監視哨之后,順序表遍歷從沒有監視哨的一端依次進行,如果查找表中有用戶需要的數據,則程序輸出該位置;反之,程序會運行至監視哨,此時匹配成功,程序停止運行,但是結果是查找失敗。

順序查找的性能分析

查找操作的性能分析主要考慮其時間復雜度,而整個查找過程其實大部分時間花費在關鍵字和查找表中的數據進行比較上。

所以查找算法衡量好壞的依據為:查找成功時,查找的關鍵字和查找表中的數據元素中進行過比較的個數的平均值,稱為平均查找長度(Average Search Length,用 ASL 表示)。

例如,對於具有 n 個數據元素的查找表,查找成功的平均查找長度的計算公式為:

P i 為第 i 個數據元素被查找的概率,所有元素被查找的概率的和為 1;C i 表示在查找到第 i 個數據元素之前已進行過比較的次數。若表中有 n 個數據元素,查找第一個元素時需要比較 n 次;查找最后一個元素時需要比較 1 次,所以有  Ci = n – i + 1
一般情況,表中各數據元素被查找的概率是未知的。假設含有 n 個數據元素的查找表中,各數據被查找的概率是相同的,則:

換算后,得:

如果對於查找表中各個數據元素有可能被查找的概率提前已知,就應該根據其查找概率的大小對查找表中的數據元素進行適當的調整:被查找概率越大,離查找出發點 i 越近;反之,越遠。這樣可以適當的減少查找操作中的比較次數。

上邊的平均查找長度是在假設查找算法每次都成功的前提下得出的。而對於查找算法來說,查找成功和查找失敗的概率是相同的。所以,查找算法的平均查找長度應該為查找成功時的平均查找長度加上查找失敗時的平均查找長度。

對於含有 n 個數據的表來說,每次查找失敗,比較的次數都是 n+1。所以查找算法的平均查找長度的計算公式為:

總結

本節主要介紹了靜態查找表的順序存儲的表示和查找算法的實現,其中使用監視哨對普通的順序表的遍歷算法做了改進,在數據量大的情況下,能夠有效提高算法的運行效率。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM