順序查找又叫線性查找,是最基本的查找技術。算法
從表的一端開始(第一個或最後一個記錄),順序掃描線性表,依次將掃描到的結點關鍵宇和給定值K相比較。若當前掃描到的結點關鍵字與K相等,則查找成功;若掃描結束後,仍未找到關鍵字等於K的結點,則查找失敗。數組
順序查找方法既適用於線性表的順序存儲結構,也適用於線性表的鏈式存儲結構(使用單鏈表做存儲結構時,掃描必須從第一個結點開始)。數據結構
注意:單鏈表爲何從第一個掃描,而不是最後一個,這與其存儲結構有關,單鏈表名字即表示第一個第一個結點的地址,而不是最後一個結點的地址。spa
typedef struct{ KeyType key; InfoType otherinfo; //此類型依賴於應用 }NodeType; typedef NodeType SeqList[n+1]; //0號單元用做哨兵
/*順序查找,參數說明: a——數組; n——要查找的數組個數; key——要查找的關鍵字 */ int SeqSearch(int *a,int n,int key) //這裏是指針引用 { int i; for(i=1;i<=n;i++){ //缺陷:每次循環都須要對i是否越界,便是否小於等於n作判斷 if(a[i]=key) return i; } return 0; }
上述操做中,每次循環都須要對i是否越界,便是否小於等於n作判斷,咱們能夠設置一個哨兵,不須要每次i與n做比較,改進方案以下:指針
/*有哨兵的順序查找*/ int SeqSearch(int *a,int n,int key) //這裏是指針引用 { int i; a[0]=key; /*設置a[0]爲關鍵字值,咱們稱之爲「哨兵」,固然也能夠設置最後一個元素爲「哨兵」*/ int n; /*循環從數組尾部開始*/ while(a[i]!=key) { i--; } return i; /*返回0說明查找失敗*/ }
固然參數也能夠以下設置,把元素個數放在數據結構體中定義:code
int SeqSearch(Seqlist R,KeyType K) { //在順序表R[1..n]中順序查找關鍵字爲K的結點, //成功時返回找到的結點位置,失敗時返回0 int i; R[0].key=K; //設置哨兵 for(i=n;R[i].key!=K;i--); //從表後往前找 return i; //若i爲0,表示查找失敗,不然R[i]是要找的結點 }
① 算法中監視哨R[0]的做用ci
爲了在for循環中省去斷定防止下標越界的條件i≥1,從而節省比較的時間。for循環
② 成功時的順序查找的平均查找長度:class
在等機率狀況下,pi=1/n(1≤i≤n),故成功的平均查找長度爲效率
(n+…+2+1)/n=(n+1)/2
即查找成功時的平均比較次數約爲表長的一半。
若K值不在表中,則須進行n+1次比較以後才能肯定查找失敗。
③ 表中各結點的查找機率並不相等的ASL
【例】在由全校學生的病歷檔案組成的線性表中,體弱多病同窗的病歷的查找機率必然高於健康同窗的病歷,因爲上式的ASLsq在pn≥pn-1≥…≥p2≥p1時達到最小值。
若事先知道表中各結點的查找機率不相等和它們的分佈狀況,則應將表中結點按查找機率由小到大地存放,以便提升順序查找的效率。
爲了提升查找效率,對算法SeqSearch作以下修改:每當查找成功,就將找到的結點和其後繼(若存在)結點交換。這樣,使得查找機率大的結點在查找過程當中不斷日後移,便於在之後的查找中減小比較次數。
④ 順序查找的優勢
算法簡單,且對錶的結構無任何要求,不管是用向量仍是用鏈表來存放結點,也不管結點之間是否按關鍵字有序,它都一樣適用。
⑤ 順序查找的缺點
查找效率低,所以,當n較大時不宜採用順序查找。
⑥ 適用狀況
對那些查找少而又常常須要改動的線性表,可採用鏈表做存儲結構,進行順序查找。