Fibonacci-Suche

Harshit Jindal 12 Oktober 2023
  1. Fibonacci-Suchalgorithmus
  2. Beispiel für die Fibonacci-Suche
  3. Implementierung des Fibonacci-Suchalgorithmus
  4. Komplexität des Fibonacci-Suchalgorithmus
Fibonacci-Suche

Die Fibonacci-Suche ist ein effizienter Intervall-Suchalgorithmus. Er ähnelt der Binären Suche in dem Sinne, dass er ebenfalls auf der Divide-and-Conquer-Strategie basiert und das Array ebenfalls sortiert werden muss. Außerdem ist die Zeitkomplexität für beide Algorithmen logarithmisch. Es wird Fibonacci-Suche genannt, weil es die Fibonacci-Reihe nutzt (Die aktuelle Zahl ist die Summe zweier Vorgänger F[i] = F[i-1] + F[i-2], F[0]=0 &F[1]=1 sind die ersten beiden Zahlen in der Reihe.) und das Array in zwei Teile mit der durch die Fibonacci-Zahlen gegebenen Größe unterteilt. Es ist eine rechenfreundliche Methode, die nur Additions- und Subtraktionsoperationen verwendet, im Vergleich zu Division, Multiplikation und Bit-Verschiebungen, die bei der binären Suche erforderlich sind.

Fibonacci-Suchalgorithmus

Nehmen wir an, wir haben ein unsortiertes Array A[], das n Elemente enthält, und wir wollen ein Element finden - X.

  • Finden Sie die kleinste Fibonacci-Zahl, die gerade größer oder gleich der Größe des Arrays n ist. Diese Zahl sei die mte Fibonacci-Zahl fib(m) und ihre Vorgänger fib(m-1) und fib(m-2).
  • Initialisiere Offset als -1.
  • Solange fib(m-2) größer als 0 ist, tun Sie Folgendes:
    • Vergleichen Sie X mit dem letzten durch fib(m-2) abgedeckten Element. Es ist gegeben durch A[min(offset + fib(m-2), n - 1)].
    • Wenn X gleich diesem Element ist, dann wird der Index zurückgegeben.
    • Andernfalls, wenn X kleiner als dieses Element ist, verwerfen wir die Hälfte nach diesem Element und verschieben die Fibonacci-Folge um zwei Schritte nach hinten. Außerdem wird der Offset aktualisiert, um den Startindex des Suchraums zu ändern. Diese Schritte verwerfen die hinteren zwei Drittel des Array-Suchraums.
    • Andernfalls, wenn X größer als dieses Element ist, verwerfen wir die Hälfte vor diesem Element und verschieben die Fibonacci-Sequenz einen Schritt nach hinten. Dieser Schritt verwirft das vordere Drittel des Array-Suchraums.
  • Wenn fib(m-1) gleich 1 ist, haben wir ein Element übrig, das wir mit X vergleichen. Wenn X gleich diesem Element ist, geben wir den Index zurück.
  • Wenn keines der Elemente übereinstimmt, dann wird -1 zurückgegeben.

Beispiel für die Fibonacci-Suche

Angenommen, wir haben das Array: (1, 2, 3, 4, 5, 6, 7). Wir müssen nach dem Element X = 6 suchen.

Das Array hat 7 Elemente. Also ist n = 7. Die kleinste Fibonacci-Zahl, die größer als n ist, ist 8.

  • Wir erhalten fib(m) = 8 , fib(m-1) = 5 und fib(m-2) = 3.
  • Erste Iteration
    • Wir berechnen den Index des Elements als min(-1 + 3, 6), was uns das Element als A[2] = 3 ergibt.
    • 3 < 6, d.h. A[2] < X, daher verwerfen wir A[0....2] und setzen Offset auf 2.
    • Wir aktualisieren auch die Fibonacci-Folge, um fib(m-2) auf 2, fib(m-1) auf 3 und fib(m) auf 5 zu verschieben.
  • Zweite Iteration
    • Wir berechnen den Index des Elements als min(2 + 2, 6), was uns das Element als A[4] = 5 ergibt.
    • 5 < 6, d.h. A[4] < X, daher verwerfen wir A[2 .... 4] und setzen Offset auf 4.
    • Wir aktualisieren auch die Fibonacci-Folge, um fib(m-2) auf 1, fib(m-1) auf 2 und fib(m) auf 3 zu setzen.
  • Dritte Iteration
    • Wir berechnen den Index des Elements als min(4 + 1, 6), was uns das Element als A[5] = 6 ergibt.
    • Wenn 6 == 6 ist, d.h. A[5] == X, geben wir den Index 5 zurück.

Implementierung des Fibonacci-Suchalgorithmus

#include <bits/stdc++.h>
using namespace std;

int fibonacciSearch(int A[], int x, int n) {
  int fbM2 = 0;
  int fbM1 = 1;
  int fbM = fbM2 + fbM1;
  int offset = -1;
  while (fbM < n) {
    fbM2 = fbM1;
    fbM1 = fbM;
    fbM = fbM2 + fbM1;
  }
  while (fbM > 1) {
    int i = min(offset + fbM2, n - 1);
    if (A[i] < x) {
      fbM = fbM1;
      fbM1 = fbM2;
      fbM2 = fbM - fbM1;
      offset = i;
    } else if (A[i] > x) {
      fbM = fbM2;
      fbM1 = fbM1 - fbM2;
      fbM2 = fbM - fbM1;
    } else
      return i;
  }
  if (fbM1 && A[offset + 1] == x) return offset + 1;

  return -1;
}

int main() {
  int n = 9;
  int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
  int x = 8;
  int result = fibonacciSearch(arr, x, n);
  if (result == -1) {
    cout << "Element not found !!";
  } else
    cout << "Element found at index " << result;
  return 0;
}

Komplexität des Fibonacci-Suchalgorithmus

Zeitkomplexität

  • Durchschnittlicher Fall

Wir reduzieren den Suchraum in jeder Iteration um ein Drittel / zwei Drittel, daher hat der Algorithmus eine logarithmische Komplexität. Die Zeitkomplexität des Fibonacci-Suchalgorithmus ist O(logn).

  • Bester Fall

Die Zeitkomplexität im besten Fall ist O(1). Sie tritt auf, wenn das zu suchende Element das erste Element ist, das wir vergleichen.

  • Schlechtester Fall

Der ungünstigste Fall tritt ein, wenn das Zielelement X immer in dem größeren Subarray vorhanden ist. Die Zeitkomplexität im schlimmsten Fall ist O(logn). Sie ist identisch mit der Zeitkomplexität im mittleren Fall.

Raumkomplexität

Die Platzkomplexität dieses Algorithmus ist O(1), da außer temporären Variablen kein weiterer Platz benötigt wird.

Harshit Jindal avatar Harshit Jindal avatar

Harshit Jindal has done his Bachelors in Computer Science Engineering(2021) from DTU. He has always been a problem solver and now turned that into his profession. Currently working at M365 Cloud Security team(Torus) on Cloud Security Services and Datacenter Buildout Automation.

LinkedIn

Verwandter Artikel - Search Algorithm