mirror of
https://github.moeyy.xyz/https://github.com/trekhleb/javascript-algorithms.git
synced 2024-11-10 11:09:43 +08:00
Add the Fibonacci Search Algortihm
implemented fibonacci search with its test
This commit is contained in:
parent
94abfec91d
commit
9e45560379
27
src/algorithms/search/fibonacci-search/README.md
Normal file
27
src/algorithms/search/fibonacci-search/README.md
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# Fibonacci Search Algorithm
|
||||||
|
Let k be defined as an element in F, the array of Fibonacci numbers. n = Fm is the array size. If n is not a Fibonacci number, let Fm be the smallest number in F that is greater than n.
|
||||||
|
|
||||||
|
The array of Fibonacci numbers is defined where Fk+2 = Fk+1 + Fk, when k ≥ 0, F1 = 1, and F0 = 0.
|
||||||
|
|
||||||
|
To test whether an item is in the list of ordered numbers, follow these steps:
|
||||||
|
```sh
|
||||||
|
Set k = m.
|
||||||
|
If k = 0, stop. There is no match; the item is not in the array.
|
||||||
|
Compare the item against element in Fk−1.
|
||||||
|
If the item matches, stop.
|
||||||
|
If the item is less than entry Fk−1, discard the elements from positions Fk−1 + 1 to n. Set k = k − 1 and return to step 2.
|
||||||
|
If the item is greater than entry Fk−1, discard the elements from positions 1 to Fk−1. Renumber the remaining elements from 1 to Fk−2, set k = k − 2, and return to step 2.
|
||||||
|
Alternative implementation (from "Sorting and Searching" by Knuth[4]):
|
||||||
|
|
||||||
|
Given a table of records R1, R2, ..., RN whose keys are in increasing order K1 < K2 < ... < KN, the algorithm searches for a given argument K. Assume N+1 = Fk+1
|
||||||
|
|
||||||
|
Step 1. [Initialize] i ← Fk, p ← Fk-1, q ← Fk-2 (throughout the algorithm, p and q will be consecutive Fibonacci numbers)
|
||||||
|
|
||||||
|
Step 2. [Compare] If K < Ki, go to Step 3; if K > Ki go to Step 4; and if K = Ki, the algorithm terminates successfully.
|
||||||
|
|
||||||
|
Step 3. [Decrease i] If q=0, the algorithm terminates unsuccessfully. Otherwise set (i, p, q) ← (p, q, p - q) (which moves p and q one position back in the Fibonacci sequence); then return to Step 2
|
||||||
|
|
||||||
|
Step 4. [Increase i] If p=1, the algorithm terminates unsuccessfully. Otherwise set (i,p,q) ← (i + q, p - q, 2q - p) (which moves p and q two positions back in the Fibonacci sequence); and return to Step 2
|
||||||
|
```
|
||||||
|
The two variants of the algorithm presented above always divide the current interval into a larger and a smaller subinterval. The original algorithm,[1] however, would divide the new interval into a smaller and a larger subinterval in Step 4. This has the advantage that the new i is closer to the old i and is more suitable for accelerating searching on magnetic tape.
|
||||||
|
|
@ -0,0 +1,15 @@
|
|||||||
|
import fibonacciSearch from '../fibonacciSearch';
|
||||||
|
|
||||||
|
describe('fibonacciSearch', () => {
|
||||||
|
it('should search number in sorted array', () => {
|
||||||
|
expect(fibonacciSearch([], 1)).toBe(-1);
|
||||||
|
expect(fibonacciSearch([1], 1)).toBe(0);
|
||||||
|
expect(fibonacciSearch([1, 2], 1)).toBe(0);
|
||||||
|
expect(fibonacciSearch([1, 2], 2)).toBe(1);
|
||||||
|
expect(fibonacciSearch([1, 5, 10, 12], 1)).toBe(0);
|
||||||
|
expect(fibonacciSearch([1, 5, 10, 12, 14, 17, 22, 100], 17)).toBe(5);
|
||||||
|
expect(fibonacciSearch([1, 5, 10, 12, 14, 17, 22, 100], 1)).toBe(0);
|
||||||
|
expect(fibonacciSearch([1, 5, 10, 12, 14, 17, 22, 100], 100)).toBe(7);
|
||||||
|
expect(fibonacciSearch([1, 5, 10, 12, 14, 17, 22, 100], 0)).toBe(-1);
|
||||||
|
});
|
||||||
|
});
|
51
src/algorithms/search/fibonacci-search/fibonacciSearch.js
Normal file
51
src/algorithms/search/fibonacci-search/fibonacciSearch.js
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/** Author Slim Gharbi
|
||||||
|
* Fibonacci search implementation.
|
||||||
|
*
|
||||||
|
* @param {*[]} integers
|
||||||
|
* @param {*} elementToSearch
|
||||||
|
* @return {number}
|
||||||
|
*/
|
||||||
|
export default function fibonacciSearch(integers, elementToSearch) {
|
||||||
|
let i;
|
||||||
|
|
||||||
|
/* Initialize fibonacci numbers */
|
||||||
|
let fibonacciMinus2 = 0;// (m-2)'th Fibonacci No.
|
||||||
|
let fibonacciMinus1 = 1;// (m-1)'th Fibonacci No.
|
||||||
|
let fibonacciNumber = fibonacciMinus2 + fibonacciMinus1; // m'th Fibonacci
|
||||||
|
/* fibonacciNumber is going to store the smallest
|
||||||
|
Fibonacci Number greater than or equal to the length of the array */
|
||||||
|
while (fibonacciNumber < integers.length) {
|
||||||
|
fibonacciMinus2 = fibonacciMinus1;
|
||||||
|
fibonacciMinus1 = fibonacciNumber;
|
||||||
|
fibonacciNumber = fibonacciMinus2 + fibonacciMinus1;
|
||||||
|
}
|
||||||
|
// Marks the eliminated range from front
|
||||||
|
let offset = -1;
|
||||||
|
/* while there are elements to be inspected.
|
||||||
|
Note that we compare integers[fibonacciMinus2] with elementToSearch.
|
||||||
|
When fibonacciNumber becomes 1, fibonacciMinus2 becomes 0 */
|
||||||
|
while (fibonacciNumber > 1) {
|
||||||
|
// Check if fibonacciMinus2 is a valid location
|
||||||
|
i = Math.min((offset + fibonacciMinus2), (integers.length - 1));
|
||||||
|
/* If elementToSearch is greater than the value at
|
||||||
|
index fibonacciMinus2, cut the subarray array
|
||||||
|
from offset to i */
|
||||||
|
if (integers[i] < elementToSearch) {
|
||||||
|
fibonacciNumber = fibonacciMinus1;
|
||||||
|
fibonacciMinus1 = fibonacciMinus2;
|
||||||
|
fibonacciMinus2 = fibonacciNumber - fibonacciMinus1;
|
||||||
|
offset = i;
|
||||||
|
} else if (integers[i] > elementToSearch) {
|
||||||
|
fibonacciNumber = fibonacciMinus2;
|
||||||
|
fibonacciMinus1 -= fibonacciMinus2;
|
||||||
|
fibonacciMinus2 = fibonacciNumber - fibonacciMinus1;
|
||||||
|
/* If elementToSearch is greater than the value at index
|
||||||
|
fibonacciMinus2, cut the subarray after i+1 */
|
||||||
|
} else return i;
|
||||||
|
// element found. return index
|
||||||
|
}
|
||||||
|
// comparing the last element with elementToSearch
|
||||||
|
if (fibonacciMinus1 === 1 && integers[offset + 1] === elementToSearch) return offset + 1;
|
||||||
|
// element not found. return -1
|
||||||
|
return -1;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user