1,順序查找
順序查找又稱線性查找,它對順序表和鏈表都適用。
(1)以下給出相關函數
1 typedef struct{ 2 ElemType *elem; //元素存儲空間地址,建表時按實際長度分配,0號單元留空 3 int TableLen; //表的長度 4 }SSTable; 5 int Search_Seq(SSTable ST,ElemType key) 6 { 7 ST.elem[0]=key; //把要查找的關鍵字放在0號位置,稱“哨兵” 8 for(int i=ST.TableLen;ST.elem!=key;i--) //從后往前找 9 { 10 return i; //若表中不存在關鍵字為key的元素,將查找i=0時退出循環 11 } 12 }
在上述算法中,將ST.elem[0]稱為“哨兵”。引入它的目的是使得Search_Seq內的循環不必判斷數組是否會越界。因為滿足i=0時,循環一定會跳出。除此之外,引入“哨兵”可以避免很多不必要的判斷語句,從而提高算法的執行效率。
(2)算法效率分析
當每個元素查找概率相同時,平均查找長度ASL=(n+1)/2, 查找不成功時,需要比較整個順序表,所以比較次數時(n+1)次,從而順序查找不成功的平均查找長度為(n+1)。
2.有序表的順序查找(假設從小到大排列)
有序表的順序查找成功的平均查找長度與一般的線性表一樣,即(n+1)/2.
當查找失敗時,待查找的元素為key,當查找第i個元素時,發現第i個元素的對應的關鍵字小於key,但第i+1個元素對應的關鍵字大於key,這時就可以返回查找失敗的信息。
查找失敗的平均查找長度為ASL=n/2+n/(n+1).
3.折半查找
前提:折半查找僅適用於有序的順序表。
折半查找原理:將給定的key與中間元素比較,直到查到要找的元素。
以下是相關函數
1 int Binary_Search(SeqList L,ElemType key){ 2 int low=0,high=L.TableLen-1,mid;//low指向表頭,high指向表尾,mid中間值 3 while(low<=high) 4 { 5 mid=(low+high)/2; 6 if(L.elem[mid]==key) //中間值等於要查找元素 7 return mid; 8 else if(L.elem[mid]<key) //要查找元素在中間值右邊 9 low=mid+1; 10 else 11 hign=mid-1; //要查找元素在中間值左邊 12 } 13 }
查找成功的時間復雜度為log2n,平均情況下比順序查找效率高一些。
引入一個思考題,我們已經知道順序查找成功的時間復雜度為(n+1)/2,折半查找的時間復雜度為,log2n那么折半查找的效率一定比順序查找高嗎?
答案是否定的,假設我們查找的元素在順序表的第一個位置,那么順序查找只需要查找1次就可以,二折半查找需要很多次,時間復雜度只是查找的平均時間復雜度的反映。