logo

القفز على البحث

يحب البحث الثنائي Jump Search عبارة عن خوارزمية بحث عن المصفوفات المصنفة. الفكرة الأساسية هي التحقق من عدد أقل من العناصر (من البحث الخطي ) من خلال القفز للأمام بخطوات ثابتة أو تخطي بعض العناصر بدلاً من البحث في جميع العناصر.
على سبيل المثال، لنفترض أن لدينا مصفوفة arr[] بالحجم n وكتلة (سيتم القفز عليها) بالحجم m. ثم نبحث في الفهارس arr[0] arr[m] arr[2m].....arr[km] وهكذا. بمجرد أن نجد الفاصل الزمني (arr[km]< x < arr[(k+1)m]) we perform a linear search operation from the index km to find the element x.
لنفكر في المصفوفة التالية: (0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610). طول المصفوفة هو 16. سيجد بحث Jump القيمة 55 مع الخطوات التالية على افتراض أن حجم الكتلة المراد القفز إليها هو 4. 
الخطوة 1: الانتقال من الفهرس 0 إلى الفهرس 4؛ 
الخطوة 2: الانتقال من الفهرس 4 إلى الفهرس 8؛ 
الخطوة 3: الانتقال من الفهرس 8 إلى الفهرس 12؛ 
الخطوة 4: بما أن العنصر الموجود في الفهرس 12 أكبر من 55، فسنعود خطوة للوراء للوصول إلى الفهرس 8. 
الخطوة 5: قم بإجراء بحث خطي من الفهرس 8 للحصول على العنصر 55.

الأداء بالمقارنة مع البحث الخطي والثنائي:

إذا قارناه بالبحث الخطي والثنائي فظهر أنه أفضل من البحث الخطي ولكن ليس أفضل من البحث الثنائي.



الترتيب المتزايد للأداء هو:

البحث الخطي  <  jump search  <  binary search


ما هو حجم الكتلة الأمثل الذي يجب تخطيه؟  
في أسوأ الحالات، يتعين علينا إجراء قفزات n/m وإذا كانت آخر قيمة تم التحقق منها أكبر من العنصر المطلوب البحث عنه، فإننا نقوم بإجراء مقارنات m-1 أكثر للبحث الخطي. وبالتالي فإن إجمالي عدد المقارنات في أسوأ الحالات سيكون ((n/m) + m-1). قيمة الدالة ((n/m) + m-1) ستكون الحد الأدنى عندما تكون m = √n. وبالتالي فإن أفضل حجم للخطوة هو m = √ ن.



خطوات الخوارزمية

  • Jump Search عبارة عن خوارزمية للعثور على قيمة محددة في مصفوفة مرتبة من خلال الانتقال خلال خطوات معينة في المصفوفة.
  • يتم تحديد الخطوات بواسطة sqrt لطول المصفوفة. 
  • فيما يلي خوارزمية خطوة بخطوة للبحث السريع:
  • حدد حجم الخطوة m عن طريق أخذ sqrt لطول المصفوفة n.
  • ابدأ من العنصر الأول في المصفوفة، ثم انتقل إلى خطوات m حتى تصبح القيمة عند هذا الموضع أكبر من القيمة المستهدفة.
    بمجرد العثور على قيمة أكبر من الهدف، قم بإجراء بحث خطي بدءًا من الخطوة السابقة حتى يتم العثور على الهدف أو يكون من الواضح أن الهدف غير موجود في المصفوفة.
    إذا تم العثور على الهدف قم بإرجاع فهرسه. إذا لم يتم إرجاع -1 للإشارة إلى أنه لم يتم العثور على الهدف في المصفوفة. 

مثال 1 :

C++
// C++ program to implement Jump Search #include    using namespace std; int jumpSearch(int arr[] int x int n) {  // Finding block size to be jumped  int step = sqrt(n);  // Finding the block where element is  // present (if it is present)  int prev = 0;  while (arr[min(step n)-1] < x)  {  prev = step;  step += sqrt(n);  if (prev >= n)  return -1;  }  // Doing a linear search for x in block  // beginning with prev.  while (arr[prev] < x)  {  prev++;  // If we reached next block or end of  // array element is not present.  if (prev == min(step n))  return -1;  }  // If element is found  if (arr[prev] == x)  return prev;  return -1; } // Driver program to test function int main() {  int arr[] = { 0 1 1 2 3 5 8 13 21  34 55 89 144 233 377 610 };  int x = 55;  int n = sizeof(arr) / sizeof(arr[0]);    // Find the index of 'x' using Jump Search  int index = jumpSearch(arr x n);  // Print the index where 'x' is located  cout << 'nNumber ' << x << ' is at index ' << index;  return 0; } // Contributed by nuclode 
C
#include #include int min(int a int b){  if(b>a)  return a;  else  return b; } int jumpsearch(int arr[] int x int n) {  // Finding block size to be jumped  int step = sqrt(n);  // Finding the block where element is  // present (if it is present)  int prev = 0;  while (arr[min(step n)-1] < x)  {  prev = step;  step += sqrt(n);  if (prev >= n)  return -1;  }  // Doing a linear search for x in block  // beginning with prev.  while (arr[prev] < x)  {  prev++;  // If we reached next block or end of  // array element is not present.  if (prev == min(step n))  return -1;  }  // If element is found  if (arr[prev] == x)  return prev;  return -1; } int main() {  int arr[] = { 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610};  int x = 55;  int n = sizeof(arr)/sizeof(arr[0]);  int index = jumpsearch(arr x n);  if(index >= 0)  printf('Number is at %d index'index);  else  printf('Number is not exist in the array');  return 0; } // This code is contributed by Susobhan Akhuli 
Java
// Java program to implement Jump Search. public class JumpSearch {  public static int jumpSearch(int[] arr int x)  {  int n = arr.length;  // Finding block size to be jumped  int step = (int)Math.floor(Math.sqrt(n));  // Finding the block where element is  // present (if it is present)  int prev = 0;  for (int minStep = Math.min(step n)-1; arr[minStep] < x; minStep = Math.min(step n)-1)  {  prev = step;  step += (int)Math.floor(Math.sqrt(n));  if (prev >= n)  return -1;  }  // Doing a linear search for x in block  // beginning with prev.  while (arr[prev] < x)  {  prev++;  // If we reached next block or end of  // array element is not present.  if (prev == Math.min(step n))  return -1;  }  // If element is found  if (arr[prev] == x)  return prev;  return -1;  }  // Driver program to test function  public static void main(String [ ] args)  {  int arr[] = { 0 1 1 2 3 5 8 13 21  34 55 89 144 233 377 610};  int x = 55;  // Find the index of 'x' using Jump Search  int index = jumpSearch(arr x);  // Print the index where 'x' is located  System.out.println('nNumber ' + x +  ' is at index ' + index);  } } 
Python
# Python3 code to implement Jump Search import math def jumpSearch( arr  x  n ): # Finding block size to be jumped step = math.sqrt(n) # Finding the block where element is # present (if it is present) prev = 0 while arr[int(min(step n)-1)] < x: prev = step step += math.sqrt(n) if prev >= n: return -1 # Doing a linear search for x in  # block beginning with prev. while arr[int(prev)] < x: prev += 1 # If we reached next block or end  # of array element is not present. if prev == min(step n): return -1 # If element is found if arr[int(prev)] == x: return prev return -1 # Driver code to test function arr = [ 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 ] x = 55 n = len(arr) # Find the index of 'x' using Jump Search index = jumpSearch(arr x n) # Print the index where 'x' is located print('Number'  x 'is at index' '%.0f'%index) # This code is contributed by 'Sharad_Bhardwaj'. 
C#
// C# program to implement Jump Search. using System; public class JumpSearch {  public static int jumpSearch(int[] arr int x)  {  int n = arr.Length;  // Finding block size to be jumped  int step = (int)Math.Sqrt(n);  // Finding the block where the element is  // present (if it is present)  int prev = 0;  for (int minStep = Math.Min(step n)-1; arr[minStep] < x; minStep = Math.Min(step n)-1)  {  prev = step;  step += (int)Math.Sqrt(n);  if (prev >= n)  return -1;  }  // Doing a linear search for x in block  // beginning with prev.  while (arr[prev] < x)  {  prev++;  // If we reached next block or end of  // array element is not present.  if (prev == Math.Min(step n))  return -1;  }  // If element is found  if (arr[prev] == x)  return prev;  return -1;  }  // Driver program to test function  public static void Main()  {  int[] arr = { 0 1 1 2 3 5 8 13 21  34 55 89 144 233 377 610};  int x = 55;  // Find the index of 'x' using Jump Search  int index = jumpSearch(arr x);  // Print the index where 'x' is located  Console.Write('Number ' + x +  ' is at index ' + index);  } } 
JavaScript
<script> // Javascript program to implement Jump Search function jumpSearch(arr x n)  {   // Finding block size to be jumped   let step = Math.sqrt(n);     // Finding the block where element is   // present (if it is present)   let prev = 0;   for (int minStep = Math.Min(step n)-1; arr[minStep] < x; minStep = Math.Min(step n)-1)  {   prev = step;   step += Math.sqrt(n);   if (prev >= n)   return -1;   }     // Doing a linear search for x in block   // beginning with prev.   while (arr[prev] < x)   {   prev++;     // If we reached next block or end of   // array element is not present.   if (prev == Math.min(step n))   return -1;   }   // If element is found   if (arr[prev] == x)   return prev;     return -1;  }  // Driver program to test function  let arr = [0 1 1 2 3 5 8 13 21   34 55 89 144 233 377 610];  let x = 55;  let n = arr.length;    // Find the index of 'x' using Jump Search  let index = jumpSearch(arr x n);    // Print the index where 'x' is located  document.write(`Number ${x} is at index ${index}`);    // This code is contributed by _saurabh_jaiswal </script> 
PHP
 // PHP program to implement Jump Search function jumpSearch($arr $x $n) { // Finding block size to be jumped $step = sqrt($n); // Finding the block where element is // present (if it is present) $prev = 0; while ($arr[min($step $n)-1] < $x) { $prev = $step; $step += sqrt($n); if ($prev >= $n) return -1; } // Doing a linear search for x in block // beginning with prev. while ($arr[$prev] < $x) { $prev++; // If we reached next block or end of // array element is not present. if ($prev == min($step $n)) return -1; } // If element is found if ($arr[$prev] == $x) return $prev; return -1; } // Driver program to test function $arr = array( 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 ); $x = 55; $n = sizeof($arr) / sizeof($arr[0]); // Find the index of '$x' using Jump Search $index = jumpSearch($arr $x $n); // Print the index where '$x' is located echo 'Number '.$x.' is at index ' .$index; return 0; ?> 

الإخراج: 
 

Number 55 is at index 10  


تعقيد الوقت : O(?n) 
المساحة المساعدة : O(1)

مزايا البحث السريع:

  1. أفضل من البحث الخطي عن المصفوفات حيث يتم توزيع العناصر بشكل موحد.
  2. يتميز البحث السريع بتعقيد زمني أقل مقارنة بالبحث الخطي للمصفوفات الكبيرة.
  3. يتناسب عدد الخطوات المتخذة في البحث السريع مع الجذر التربيعي لحجم المصفوفة مما يجعلها أكثر كفاءة للمصفوفات الكبيرة.
  4. إنه أسهل في التنفيذ مقارنة بخوارزميات البحث الأخرى مثل البحث الثنائي أو البحث الثلاثي.
  5. يعمل البحث السريع بشكل جيد مع المصفوفات حيث تكون العناصر مرتبة وموزعة بشكل موحد حيث يمكنها الانتقال إلى موضع أقرب في المصفوفة مع كل تكرار.

نقاط مهمة:  
 



  • يعمل فقط مع المصفوفات التي تم فرزها.
  • الحجم الأمثل للكتلة المراد القفز عليها هو (؟ ن). وهذا يجعل التعقيد الزمني لـ Jump Search O(?n).
  • يقع التعقيد الزمني للبحث السريع بين البحث الخطي ((O(n)) والبحث الثنائي (O(Log n)).
  • يعد البحث الثنائي أفضل من Jump Search ولكن يتميز Jump Search بأنه يمكننا الرجوع للخلف مرة واحدة فقط (قد يتطلب البحث الثنائي ما يصل إلى O(Log n) من القفزات، مع الأخذ في الاعتبار الموقف الذي يكون فيه العنصر المطلوب البحث فيه هو أصغر عنصر أو أكبر من الأصغر). لذلك، في النظام الذي يكون فيه البحث الثنائي مكلفًا، نستخدم Jump Search.


مراجع:  
https://en.wikipedia.org/wiki/Jump_search
إذا كنت تحب GeeksforGeeks وترغب في المساهمة، يمكنك أيضًا كتابة مقال باستخدام write.geeksforgeeks.org أو أرسل مقالتك بالبريد إلى [email protected]. راجع مقالتك التي تظهر على صفحة GeeksforGeeks الرئيسية وساعد Geeks الآخرين. يرجى كتابة التعليقات إذا وجدت أي شيء غير صحيح أو كنت ترغب في مشاركة المزيد من المعلومات حول الموضوع الذي تمت مناقشته أعلاه.