演算法與資料結構 查詢演算法語義約定及二分查詢

2021-09-28 00:12:07 字數 3583 閱讀 3164

對於有序陣列,通常用二分查詢(包括改進型的 fibonacci 查詢和插值查詢)。

一般簡單的查詢演算法,可以在查詢失敗時直接返回 -1。但為了讓函式更具有通用性(例如對於插入操作,需要定位到精確的位置),通常約定的語義為(假設陣列a[lo,hi),要查詢元素e):返回不大於 e 的最大的下標,幾種特殊情況:

例如,對於陣列 [3, 6, 8, 19],分析如下:

例如,對於陣列 [3, 3, 8, 8],分析如下:

二分查詢的思想很簡單:

#include

#include

intbinsearcha

(int arr,

int lo,

int hi,

int e)

else

if(arr[mi]

< e)

else

}return-1

;}void searchtest (),

0,0,

1)==-

1);assert

(binsearcha((

int)

,0,1

,1)==

0);assert

(binsearcha((

int)

,0,1

,0)==

-1);

assert

(binsearcha((

int)

,0,1

,2)==

-1);

assert

(binsearcha((

int)

,0,2

,1)==

0);assert

(binsearcha((

int)

,0,2

,3)==

1);printf

("pass test");

}int

main

(void

)

對於第一版的二分查詢,轉向左子區間只需要做一次判斷,而轉向右子區間則需要兩次。所以,如果查詢時能更多的左轉,查詢效率會提公升。

二分查詢是每次取中點,而 fib 查詢和插值查詢都優化了取中點的策略。

fibonacci 數列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89。。。(從第三項開始,每一項都是前兩項之和)。數列越靠後,前後兩項的比值越接近 0.618 **分隔點。

遞迴版效率很低,按照現在計算機的效能,大概計算到 50 左右就能明顯感受到延時了。

#include

intfib

(int n)

return

fib(n -1)

+fib

(n -2)

;}intmain

(void

)

迭代可以分為兩種情況:

#include

intfib

(int n)

return i;

}int

main

(void

)

更簡化版的**:

int

fib(

int n)

return i;

}

#include

#include

intfib

(int n)

int*arr =

(int*)

malloc

(sizeof

(int)*

(n +1)

);int count =1;

int tmp;

arr[0]

=0; arr[1]

=1;while

(count < n)

tmp = arr[n]

;free

(arr)

;return tmp;

}int

main

(void

)

每次確定 fibonacci 查詢的中點時,需要先建立 fibonacci 陣列。例如要在區間 a[0, 10) 中查詢時,因為 fib(6) = 8,fib(7) = 13,所以陣列中有 7 個元素,分別放 fibonacci 數列前 7 個值。

#include #include int fib(int n) 

return i;

}int fibsearch(int arr, int lo, int hi, int e)

}while (lo < hi) else if (arr[mi] < e) else

}return -1;

}void searchtest () , 0, 0, 1) == -1);

assert(fibsearch((int), 0, 1, 1) == 0);

assert(fibsearch((int), 0, 1, 0) == -1);

assert(fibsearch((int), 0, 1, 2) == -1);

assert(fibsearch((int), 0, 2, 1) == 0);

assert(fibsearch((int), 0, 2, 3) == 1);

assert(fibsearch((int), 0, 5, 3) == 1);

printf("pass test");

}int main(void)

#include

#include

#include

intbinsearch

(int arr,

int lo,

int hi,

int e)

else

}return

--lo;

}void searchtest (),

0,0,

1)==-

1);assert

(binsearch((

int)

,0,1

,1)==

0);assert

(binsearch((

int)

,0,1

,0)==

-1);

assert

(binsearch((

int)

,0,1

,2)==

0);assert

(binsearch((

int)

,0,2

,1)==

0);assert

(binsearch((

int)

,0,2

,3)==

1);assert

(binsearch((

int)

,0,5

,3)==

2);printf

("pass test");

}int

main

(void

)

資料結構與演算法 查詢演算法

1.線性查詢,從頭到尾去遍歷,找到符合的則返回 2.二分法查詢 前提 目標陣列有序 package math public class dichotomy int k new dichotomy show arr,8 system.out.println k public int show int ...

資料結構與演算法 查詢演算法

第二章 查詢和排序演算法 課時1 列表查詢 1 列表查詢的含義 從物件中查詢某乙個特定的元素 2 列表查詢的方式包含兩種 順序查詢和二分查詢 3 順序查詢演算法 從開始一直搜尋到最後乙個元素進行查詢,for迴圈,時間複雜度為o n 4 二分查詢針對有效的列表直接進行首尾二分查詢,不斷使得候選區減半,...

資料結構與演算法(查詢)

1 查詢表 用於查詢的資料集合,由同一型別的資料元素組成,經常進行的操作 2 靜態查詢表 無需動態修改查詢表的操作,都是靜態查詢表。適合的查詢方法有順序查詢 折半查詢 雜湊查詢。3 動態查詢表 需要動態插入或刪除的操作。適合的查詢方法有二叉排序樹查詢 雜湊查詢。4 關鍵字 資料元素中唯一表示該元素的...