陣列構成:
typedef struct lnode *list;
struct lnodelnode;
一. 順序查詢
由於不帶「哨兵」,陣列的第乙個位置(data[0])用於儲存資料,所以線性表的初始化中last是從-1開始的,表示表中暫無元素。
/*初始化1
*實現功能:建立空的線性表
*傳入形參:無
*返回值:線性表指標
*/list makeempty1()
相對應的查詢函式如下:
/*順序查詢 (無"哨兵")
*函式功能:在data[0]~data[n]中查詢關鍵字為x的資料元素
*傳入形參:線性表指標 ptrl, 關鍵字 x
*返回值:查詢成功返回所在單元下標,不成功返回 0
所謂「哨兵」就是用乙個特殊值來作為陣列的邊界,使用「哨兵」可以少用一條判斷語句,所以可以提高程式的效率。
這樣就可以將陣列的第乙個位置作為「哨位」,資料的儲存從data[1]開始。因此線性表的初始化中last是從0開始的,表示表中暫無元素。
/*初始化2
*實現功能:建立空的線性表
*傳入形參:無
*返回值:線性表指標
*/list makeempty2()
相對應的查詢函式如下:
/*順序查詢 (有"哨兵")
*函式功能:在data[1]~data[n]中查詢關鍵字為x的資料元素
*傳入形參:線性表指標 ptrl, 關鍵字 x
*返回值:查詢成功返回所在單元下標,不成功返回 0
*/int sequentialsearch2(list ptrl,elementtype x)
將哨兵賦值為關鍵字x,這樣判別條件便只有乙個。並且同樣當檢索完的時候,會滿足判別條件並返回「0」。
二. 二分查詢(帶哨兵)
二分查詢,所針對的是有序陣列,即資料在之前必須已經由小到大排序完成。
簡單來說即通過尋找中間數並比較大小,確定目標數所在區間,並且不斷通過這種方法縮小區間,直到找到目標數。
具體實現如下:
1. 通過last確定左(left)右(right)邊界,計算得出中間數字置(mid)。
2. 比較mid處的數與目標數x的大小,確定目標數所在區間(左半部分或右半部分或者該處就是x)。
3. (1)若x在左半部分,則將右邊界right左移到mid的左邊。再重新確定mid,重複1,2步驟。
(2)若x在右半部分,則將左邊界left左移到mid的右邊。再重新確定mid,重複1,2步驟。
(3)若x即為mid處的數,則返回mid的值。
該方法與「最大子列和」問題中「分而治之」的方法,有著異曲同工之妙。不同的是,在這個問題中,我們只需要要找到目標數的位置即可,所以通過「分」之後不需要兩邊都「治」,另一半部分直接捨棄。這樣做較之順序查詢的方法便可大大增加查詢效率。
下面通過乙個例子來說明:
假如要從下面的陣列中找數「55」
1. mid = (left + right)/2 = 14/2 = 7,此時mid位置上的數為 88 > 55. 55在左半部分,所以right = mid -1 = 6。
2. mid = (left + right)/2 = 7/2 = 3,此時mid位置上的數為34 < 55. 55在右半部分,所以left = mid + 1 = 4。
3. mid = (left + right)/2 = 10/2 = 5,此時mid位置上的數為68 > 55. 55在左半部分,所以right = mid - 1 = 4。
4. mid = (left + right)/2 = 8/2 = 4,此時mid位置上的數為55.成功找到目標數55的位置,返回mid的值。
那如果查詢的數不在該陣列內時,情況會如何呢?
如上例中如果我們要找的目標數為「42」,當進行到3時,mid位置上的數為55 > 42.
程式會判定42在左半部分,所以更改右邊界right的值,right = mid - 1 = 3
此時,left = 4;right = 3;右邊界(right)到了左邊界(left)的左邊,說明查詢完畢。沒找到42,返回 -1。
由此我們便可以知道,迴圈的截至條件為 left > right。
程式如下:
/*二分查詢 (有"哨兵")
*函式功能:在data[1]~data[n]中查詢關鍵字為x的資料元素
*傳入形參:線性表指標 ptrl, 關鍵字 x
*返回值:查詢成功返回所在單元下標,不成功返回 -1
*/int binarysearch(list ptrl,elementtype x)
return nofound;
}
測試主函式如下:
#include #include #define maxsize 100
typedef int elementtype;
typedef struct lnode *list;
struct lnodelnode;
int sequentialsearch1(list ptrl,elementtype x);
int sequentialsearch2(list ptrl,elementtype x);
list makeempty1();
list makeempty2();
int binarysearch(list ptrl,elementtype x);
int main()
while(1);
printf("輸入查詢的數:");
scanf("%d",&x);
printf("position:%d\n",sequentialsearch1(l,x));
free(l);
getch();
l = makeempty2();//帶哨兵的初始化
printf("輸入元素(遞增輸入):");
dowhile(1);
printf("帶哨兵的順序查詢\n");
printf("輸入查詢的數:");
scanf("%d",&x);
printf("position:%d\n",sequentialsearch1(l,x));
printf("二分查詢\n");
printf("輸入查詢的數:");
scanf("%d",&x);
printf("position:%d",binarysearch(l,x));
free(l);
}
測試結果如下:
測試環境:win10 使用軟體:dev_c++
順序查詢與二分查詢
先上 include void printarr int a,int n void bublesort int a,int n void swap int a,int b int binarysearch int a,int n,int k int normalsearch int a,int n,...
順序查詢 二分查詢
順序查詢 適用範圍 沒有進行排序的資料序列 缺點 速度非常慢,效率為o n cpp view plain copy 在code上檢視 片派生到我的 片 實現 template type sequencesearch type begin,type end,const type searchvalue...
順序查詢與二分查詢解析
非常簡單 示例1 在成績中查詢分數是100的第乙個分數 99 86 59 63 49 100 99 78 for int i 0 i示例2 在學生中查詢分數是100的第乙個學生 儲存結構可以是順序表,也可以是鍊錶。逐個比較查詢,如果找到,返回資料或者索引,如果到最後也沒有找到,返回null 可以是在...