6.1順序查找
順序查找
int seq_search(Table T,Elem key){//順序沒有可從前往後,從後往前 for(int i=0;key!=T[i];i++) //順序結構的Table;可鏈式結構 return i; }
平均查找長度
對於n個單元的表,給定key與表中第i個關鍵字相等,需比較i次;
ASL_success=1/n*(1+2+…+n)=n+1/2;
優點:對數據元素存儲的方式沒要求,順序或鏈式存儲結構;對錶中數據可以爲無序;
缺點:當n較大時,平均查找長度較大,效率低;
注:鏈表只能順序查找
6.2折半查找
折半查找&二分查找,只用於已排序序列。
int binary_search(SeqTable T,Elem key){ int low=0,high=T.len-1,mid; while(low < high){ mid = (low+high)/2; //向下取整 if(T[mid]<key) low=mid+1; else if(T[mid]>key) high=mid-1; else return mid; } }
折半查找的時間複雜度爲O(log_2{n}),平均情況比順序查找效率高;
平均查找長度:ASL=1/n(1x1+2x2+…+hx2^h-1)
平均查找成功長度和平均查找失敗長度(⭐️)
會畫折半查找的判定樹,王道p243.
n個元素的有序表,的判定樹的高度向上取整log_2{n+1}
注:二分查找的存儲結構必須具有隨機存取的特性,故只用於線性表的順序存儲結構,即只用於順序表,不適合鏈表。且要求有序,小到大,或大到小影響算法的mid移動。
6.3分塊查找(不考)
分塊查找又稱索引順序查找,集合了順序查找和折半查找,將表分塊,索引表順序存儲塊中最大或最小關鍵字,將塊有序排列;
分塊查找先在索引表折半查找找到指定塊,再在塊中順序查找指定關鍵字;
6.4 散列表(HashTable)
注:一篇博文,散列表的概念和實現,鏈接:https://blog.csdn.net/lin1094201572/article/details/89111958
散列表的查找的效率取決於比較的次數;
散列表中散列函數爲核心,用於將關鍵字映射到對應地址的函數,Hash(key)=address;
那麼問題來了,若兩個或以上關鍵字映射到相同地址呢,這種問題叫做衝突,衝突的關鍵字爲同義詞,衝突不可避免,故我們需要解決衝突;
解決衝突的辦法有:開放地址法、拉鍊法;
1.Hash函數的構造
散列函數應滿足1)包含所有關鍵字;2)地址等概率、均勻分佈;3)簡單,計算快;
常用散列函數:
1.直接定址法:H(key)=a*key+b;不會造成衝突,但造成存儲空間浪費;
2.除留餘數法:H(key)=key%p;p小於表長;
3.數字分析法;4.平方取中法;5.摺疊法;
2.處理衝突的方法
1.開放地址
1)線性探測法;2)平方探測法;3)再散列法;
2.拉鍊法
採用線性鏈表存儲所有關鍵字,每一鏈表由一地址標識;適用於經常插入和刪除的情況;
3.散列表查找及性能分析
決定散列表的查找效率的因素:散列函數、處理衝突的方法、裝填因子;
裝填因子:a=表中記錄數/表長;
散列表的平均查找長度依賴於裝填因子;還會受到堆積(聚集)現象的影響;