資料結構,資料結構與演算法

來源:互聯網
上載者:User

資料結構,資料結構與演算法
尋找

主要討論順序表、有序表、索引表和雜湊表尋找的各種實現方法,以及相應尋找方法在等機率情況下的平均尋找長度。

 尋找表(Search Table):相同類型的資料元素(對象)組成的集合,每個元素通常由若干資料項目構成。   關鍵字(Key,碼):資料元素中某個(或幾個)資料項目的值,它可以標識一個資料元素。若關鍵字能唯一標識一個資料元素,則關鍵字稱為主關鍵字(Primary Key) ;將能標識若干個資料元素的關鍵字稱為次關鍵字(Secondary Key) 。   尋找/檢索(Searching):根據給定的K值,在尋找表中確定一個關鍵字等於給定值的記錄或資料元素。

◆ 尋找表中存在滿足條件的記錄:尋找成功;結果:所查到的記錄資訊或記錄在尋找表中的位置。
◆ 尋找表中不存在滿足條件的記錄:尋找失敗。
根據尋找表的操作方式,分為靜態尋找表和動態尋找表。
靜態尋找表(Static Search): 只對尋找表進行如下操作:
(1)查看某個特定的資料元素是否在尋找表中,
(2)檢索某個特定元素和各種屬性。
動態尋找表(Dynamic Search):在尋找過程中,可進行如下操作:
(1)可以將尋找表中不存在的資料元素插入,
(2)從尋找表中刪除已存在的某個記錄。
為了提高尋找的效率,除了應用好的尋找演算法外,也會為尋找設立專門的資料結構來儲存資料,比如表、樹等等。
尋找表的儲存結構:
尋找表是一種非常靈活的資料結構,可以用多種方式來儲存。
根據儲存結構的不同,尋找方法可分為三大類:
① 順序表和鏈表的尋找:將給定的K值與尋找表中記錄的關鍵字進行比較, 找到要尋找的記錄;
② 散列表的尋找:根據給定的K值直接存取尋找表, 從而找到要尋找的記錄;
③ 索引尋找表的尋找:首先根據索引確定待尋找記錄所在的塊 ,然後再從塊中找到要尋找的記錄。
一般地,認為記錄的關鍵字是一些可以進行比較運算的類型,如整型、字元型、實型等,本章以後各節中討論所涉及的關鍵字、資料元素等的類型描述如下:
典型的關鍵字類型說明是:

typedef  float   KeyType ;       /*  實型  */typedef  int   KeyType ;       /*  整型  */typedef  char  KeyType ;       /*  字元型  */       資料元素類型的定義是:typedef  struct  RecType{  KeyType  key ;          /* 關鍵字碼  */┇ /* 其他域  */}RecType ;
靜態尋找
    靜態尋找表的抽象資料類型定義如下:

ADT Static_SearchTable{
資料對象D:D是具有相同特性的資料元素的集合,
各個資料元素有唯一標識的關鍵字。
資料關係R:資料元素同屬於一個集合。
基本操作P:
Create
Destroy
Search
Traverse
} ADT Static_SearchTable
線性表是尋找表最簡單的一種組織方式,本節介紹幾種主要的關於線性表的尋找方法。

順序尋找

適用場合:針對尋找表中的元素沒有按關鍵字進行排序(即無序線性表)
1 尋找思想
從表的一端(第一個或 最後一個)開始逐個將記錄的關鍵字和給定K值進行比較,若某個記錄的關鍵字和給定K值相等,尋找成功;否則,若掃描完整個表,仍然沒有找到相應的記錄,則尋找失敗。順序表的類型定義如下:

#define MAX_SIZE  100typedef  struct  SSTable{  RecType  elem[MAX_SIZE] ;    /*  順序表  */int  length ;     /*  實際元素個數  */}SSTable ;
int  Seq_Search ( SSTable  ST , KeyType key){   int i ;   ST. elem[0].key=key ;    /*  設定監視哨兵,失敗返回0  */for (i=ST.length; i>=1;i--)     if (ST. elem[i].key==key)            return i; return 0; } 
折半尋找

前提條件:尋找表中的所有記錄是按關鍵字有序(升序或降序) 。
尋找過程中,先確定待尋找記錄在表中的範圍,然後逐步縮小範圍(每次將待查記錄所在區間縮小一半),直到找到或找不到記錄為止。
1 尋找思想
用Low、High和Mid表示待尋找區間的下界、上界和中間位置指標,初值為Low=1,High=n。
⑴ 取中間位置Mid:Mid=(Low+High)/2 ;
⑵ 比較中間位置記錄的關鍵字與給定的K值:
① 相等: 尋找成功;
② 大於:待查記錄在區間的前半段,修改上界指標: High=Mid-1,轉⑴ ;
③ 小於:待查記錄在區間的後半段,修改下界指標:Low=Mid+1,轉⑴ ;
直到越界(Low>High),尋找失敗。

2  演算法實現int  Bin_Search(SSTable  ST , KeyType  key){    int  Low=1,High=ST.length, Mid ;while (Low<High){     Mid=(Low+High)/2 ;if  (ST. elem[Mid].key== key))      return(Mid) ; else if (ST. elem[Mid].key<key))             Low=Mid+1 ;       else   High=Mid-1 ;}return(0) ;      /*   尋找失敗  */ }
Fibonacci尋找
       Fibonacci尋找方法是根據Fibonacci數列的特點對尋找表進行分割。Fibonacci數列的定義是:        F(0)=0,F(1)=1,F(j)=F(j-1)+F(j-2) 。若共有20(F(8)-1)個數, j=8,則mid= low+F(7)-1 =13若key <a[13], 則low=1,high=12下一步:j=7, mid= low+F(6)-1 =8若key >a[13], 則low=14,high=20( F(8) -1)下一步:j=6, mid=low+F(5)-1=18

1 尋找思想
設尋找表中的記錄數比某個Fibonacci數小1,即設n=F(j)-1。用Low、High和Mid表示待尋找區間的下界、上界和分割位置,初值為Low=1,High=n。
⑴ 取分割位置Mid:Mid=low+F(j-1)-1;
⑵ 比較分割位置記錄的關鍵字與給定的K值:
① 相等: 尋找成功;
② 大於:待查記錄在區間的前半段(區間長度為F(j-1)-1),修改上界指標: High=Mid-1,轉⑴ ;
③ 小於:待查記錄在區間的後半段(區間長度為F(j-2)-1),修改下界指標:Low=Mid+1,轉⑴ ;
直到越界(Low>High),尋找失敗。
演算法實現
在演算法實現時,為了避免頻繁計算Fibonacci數,可用兩個變數f1和f2儲存當前相鄰的兩個Fibonacci數,這樣在以後的計算中可以依次遞推計算出。

int fib(int n){    int i, f , f0=0 , f1=1 ;if (n==0)  return(0) ;if (n==1)  return(1) ;for (i=2 ; i<=n ; i++ ){   f=f0+f1 ; f0=f1 ; f1=f ;   }return(f) ;}int Fib_search(RecType ST[] , KeyType key , int n)    /*  在有序表ST中用Fibonacci方法尋找關鍵字為key的記錄  */{    int Low=1, High, Mid, f1, f2 ;High=fib(n)-1 ; f1=fib(n-1) ; f2=fib(n-2) ;while (Low<=High){   Mid=Low+f1-1;                          if ( ST.[Mid].key==key )   return(Mid) ;                          else if ( key<ST.[Mid].key) )                                {   High=Mid-1 ; f2=f1-f2 ; f1=f1-f2 ;     }                                 else                                  {   Low=Mid+1 ;f1=f1-f2 ; f2=f2-f1 ;  }                      }      return(0) ; } 

Fibonacci尋找的時間複雜度也為O(logn)
平均效能,優於折半尋找;但在最壞情況下效能比折半尋找差。
折半尋找需進行加法和除法運算;但Fibonacci尋找只需進行加、減運算。

分塊尋找

分塊尋找(Blocking Search)又稱索引順序尋找,是前面兩種尋找方法的綜合。
1 尋找表的組織
① 將尋找表分成幾塊。塊間有序,即第i+1塊的所有記錄關鍵字均大於(或小於)第i塊記錄關鍵字;塊內無序。
② 在尋找表的基礎上附加一個索引表,索引表是按關鍵字有序的,索引表中記錄的構成是

應用
分塊索引兼顧了對細分塊不需要有序的情況下,大大增加了整體尋找速度,普遍應用於資料庫表尋找技術中。

演算法實現typedef struct IndexType{ keyType  maxkey ;     /*  塊中最大的關鍵字  */   int startpos ;     /*  塊的起始位置  */}Index;int Block_search(RecType ST[] , Index ind[] , KeyType key , int n , int b)      /*  在分塊索引表中尋找關鍵字為key的記錄 */         /*表長為n ,塊數為b */{          int i=0 , j , k ;while ((i<b)&&LT(ind[i].maxkey, key) )  i++  ;if (i>b) {  printf("\nNot found");   return(0);  }j=ind[i].startpos ;while ((j<n)&&LQ(ST[j].key, ind[i].maxkey) ){   if ( EQ(ST[j].key, key) )  break ;j++ ;}     /*  在塊內尋找  */           if (j>n||!EQ(ST[j].key, key) )               {  j=0; printf("\nNot found");  }          return(j); }

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.