思路分析:
1.首先需要確定該陣列的中間下標
2.讓需要查詢的數 findval 和 arr[mid] 比較
結束遞迴的條件:
1.找到就結束遞迴
2.遞迴完整個陣列,仍沒有找到,也需要結束遞迴,當left > right 就需要退出
**實現
第乙個方法適用於陣列中只有乙個待查詢的結果
第二個方法適用於陣列中有多個待查詢的結果(有重複值)
/**
* * @param arr 陣列
* @param left 左邊的索引
* @param right 右邊的索引
* @param findval 要查詢的值
* @return 如果找到就返回下標,如果沒有就返回-1
*/public
static
intbinarysearch
(int
arr,
int left,
int right,
int findval)
int mid =
(left + right)/2
;if(findval > arr[mid]
)else
if(findval < arr[mid]
)else
}//有序陣列種有多個相同的數值時,如何將所有的數值都查詢到
public
static list
binarysearch2
(int
arr,
int left,
int right,
int findval)
int mid =
(left + right)/2
;if(findval > arr[mid]
)else
if(findval < arr[mid]
)else
//否則,將temp放入到list中
list.
add(temp)
; temp -=1;
} list.
add(mid)
; temp = mid +1;
while
(true
)//否則,將temp放入到list中
list.
add(temp)
; temp +=1;
}return list;
}}
插值查詢原理介紹:插值查詢演算法類似於二分查詢,不同的是插值查詢每次從自適應 mid 處開始查詢
int mid = low + (high - low) * (key - arr[low]) / (arr[high] - arr[low]) ;插值索引
對應上面的**公式:
int mid = left + (right – left) * (findval – arr[left]) / (arr[right] – arr[left])
**實現
/**
* @param arr 陣列
* @param left 左邊索引
* @param right 右邊索引
* @param findval 查詢值
* @return 如果找到,就返回對應的下標,如果沒有找到,返回-1
*/public
static
intinsertvaluesearch
(int
arr,
int left,
int right,
int findval)
//求出mid 自適應
int mid = left +
(right - left)
*(findval - arr[left])/
(arr[right]
- arr[left]);
int midval = arr[mid];if
(findval > midval)
else
if(findval < midval)
else
}
插值查詢注意事項:對於資料量較大,關鍵字分布比較均勻的查詢表來說,採用插值查詢, 速度較快.
關鍵字分布不均勻的情況下,該方法不一定比折半查詢要好
斐波那契數列 發現斐波那契數列的兩個相鄰數 的比例,無限接近 **分割值0.618
斐波那契(**分割法)原理
斐波那契查詢原理與前兩種相似,僅僅改變了中間結點(mid)的位置,mid 不再是中間或插值得到,而是位於**分割點附近,即 mid=low+f(k-1)-1(f 代表斐波那契數列),如下圖所示
對 f(k-1)-1 的理解:
由斐波那契數列f[k]=f[k-1]+f[k-2]的性質,可以得到(f[k]-1)=(f[k-1]-1)+(f[k-2]-1)+1。該式說明: 只要順序表的長度為 f[k]-1,則可以將該錶分成長度為 f[k-1]-1 和 f[k-2]-1 的兩段,即如上圖所示。從而中間位置為 mid=low+f(k-1)-1
類似的,每一子段也可以用相同的方式分割
但順序表長度 n 不一定剛好等於 f[k]-1,所以需要將原來的順序表長度 n 增加至 f[k]-1。這裡的 k 值只要能使得 f[k]-1 恰好大於或等於 n 即可,由以下**得到,順序表長度增加後,新增的位置(從 n+1 到 f[k]-1 位置), 都賦為 n 位置的值即可。
**實現
//因為mid=low+f(k-1)-1,需要使用到fibonacci數列,因此需要先獲取到乙個斐波那契數列
//非遞迴方式得到乙個斐波那契數列
public
static
int[
]fib()
return f;
}//編寫斐波那契查詢演算法
/** * 非遞迴方式編寫
* @param a 陣列
* @param key 需要查詢的關鍵碼(值)
* @return 返回對應的下標,如果沒有返回-1
*/public
static
intfibsearch
(int
a,int key)
//因為f[k]的值可能大於a陣列的長度,我們使用arrays類,構造乙個新陣列,並指向temp
//不足的部分用0填充
int[
] temp = arrays.
copyof
(a, f[k]);
//實際上需要使用a陣列的最後的數填充temp
for(
int i = high +
1; i < temp.length; i++
)//使用while迴圈處理,找到我們的數key
while
(low <= high)
else
if(key > temp[mid]
)else
else}}
return-1
;}
查詢 四種查詢演算法
順序查詢 sequential search 又叫線性查詢,是最簡單直接暴力的查詢方法。就是從頭至尾挨個尋找,找到位置。當遍歷完沒找到就說明要找的資料不存在。它不要求資料有序。該演算法的時間複雜度為o n public static int seqsearch int arr,int value r...
最短路演算法(3種演算法)
最短路,顧名思義,最短的路徑。我們把邊帶有權值的圖稱為帶權圖。邊的權值可以理解為兩點之間的距離。一張圖中任意兩點之間會有不同的路徑相連。最短路徑就是指連線兩點的這些路徑中最短的一條。我們有四種演算法可以有效地解決最短路徑問題,但是當出現負邊權時,有些演算法不適用。for int k 1 k n k ...
五種查詢演算法總結
五種查詢演算法總結 一 順序查詢 條件 無序或有序佇列。原理 按順序比較每個元素,直到找到關鍵字為止。時間複雜度 o n 二 二分查詢 折半查詢 條件 有序陣列 原理 查詢過程從陣列的中間元素開始,如果中間元素正好是要查詢的元素,則搜素過程結束 如果某一特定元素大於或者小於中間元素,則在陣列大於或小...