Linear Search (חיפוש ליניארי)
עודכן לאחרונה
חיפוש ליניארי (שנקרא גם חיפוש סדרתי) הוא אלגוריתם החיפוש הפשוט ביותר: מתחילים באיבר הראשון ומשווים כל איבר למטרה עד שמוצאים התאמה או שהאיברים נגמרים. הוא לא מניח שום דבר על הנתונים, ולכן המערך יכול להיות לא ממוין, והאיברים יכולים להיות כל דבר שאפשר להשוות לשוויון.
האנימציה למעלה מדגישה כל השוואה בזמן שהסריקה נעה משמאל לימין, ועוצרת ברגע שהמטרה מופיעה. הפשטות באה על חשבון המהירות: במקרה הגרוע בודקים כל איבר, ולכן הוא רץ ב-O(n). כשהנתונים ממוינים, חיפוש בינארי מוצא את אותה תשובה ב-O(log n), ואם צריך קודם נתונים ממוינים, ראו מיון מיזוג.
סיבוכיות זמן וזיכרון
| מקרה | סיבוכיות | הערות |
|---|---|---|
| המקרה הטוב | O(1) | האיבר הראשון הוא המטרה. |
| המקרה הממוצע | O(n) | בממוצע בודקים חצי מהאיברים לפני שמוצאים. |
| המקרה הגרוע | O(n) | המטרה אחרונה, או שהיא בכלל לא קיימת. |
| זיכרון | O(1) | שומרים רק את האינדקס הנוכחי. |
צעד אחר צעד
| צעד | מה קורה |
|---|---|
| 1 | מתחילים באינדקס 0, האיבר הראשון במערך. |
| 2 | משווים את האיבר הנוכחי לערך המטרה. |
| 3 | אם הם שווים, מחזירים את האינדקס הנוכחי (נמצא). |
| 4 | אחרת זזים מקום אחד ימינה וחוזרים על הבדיקה. |
| 5 | אם מגיעים לסוף המערך בלי התאמה, המטרה לא קיימת (מחזירים -1). |
דוגמה מפורטת
חיפוש של 5 ב-[7, 3, 9, 1, 5, 8, 2]:
| השוואה | אינדקס | איבר | תוצאה |
|---|---|---|---|
| 1 | 0 | 7 | 7 ≠ 5: ממשיכים לסרוק. |
| 2 | 1 | 3 | 3 ≠ 5: ממשיכים לסרוק. |
| 3 | 2 | 9 | 9 ≠ 5: ממשיכים לסרוק. |
| 4 | 3 | 1 | 1 ≠ 5: ממשיכים לסרוק. |
| 5 | 4 | 5 | 5 = 5: נמצא באינדקס 4. |
מתי להשתמש בחיפוש ליניארי
| השתמשו בו כאשר | הימנעו ממנו כאשר |
|---|---|
| הנתונים לא ממוינים או משתנים כל הזמן | הנתונים ממוינים, ולכן חיפוש בינארי מהיר ממנו באופן אקספוננציאלי |
| האוסף קטן, ולכן הפשטות מנצחת | כמות הנתונים גדולה ומחפשים בה שוב ושוב |
| יש רק גישה סדרתית (זרמים, רשימות מקושרות) | אפשר להרשות לעצמכם אינדקס או טבלת גיבוב לחיפושים של O(1) |
קוד Linear Search
מימוש נקי של Linear Search שאפשר להריץ, ב-Python, JavaScript, Java, C++, C, Pseudocode. בחרו שפה, העתיקו את הקוד, או פתחו אותו טעון מראש בעורך האונליין של Coddy.
קוד Linear Search ב-Python
1def linear_search(a, target):2 # Scan left to right until the target appears3 for i in range(len(a)):4 if a[i] == target:5 return i6 return -17
8
9nums = [7, 3, 9, 1, 5, 8, 2]10print("Index of 5:", linear_search(nums, 5))11print("Index of 4:", linear_search(nums, 4))קוד Linear Search ב-JavaScript
1function linearSearch(a, target) {2 // Scan left to right until the target appears3 for (let i = 0; i < a.length; i++) {4 if (a[i] === target) return i;5 }6 return -1;7}8
9const nums = [7, 3, 9, 1, 5, 8, 2];10console.log("Index of 5:", linearSearch(nums, 5));11console.log("Index of 4:", linearSearch(nums, 4));קוד Linear Search ב-Java
1public class Main {2 static int linearSearch(int[] a, int target) {3 // Scan left to right until the target appears4 for (int i = 0; i < a.length; i++) {5 if (a[i] == target) return i;6 }7 return -1;8 }9
10 public static void main(String[] args) {11 int[] nums = {7, 3, 9, 1, 5, 8, 2};12 System.out.println("Index of 5: " + linearSearch(nums, 5));13 System.out.println("Index of 4: " + linearSearch(nums, 4));14 }15}קוד Linear Search ב-C++
1#include <iostream>2#include <vector>3
4int linearSearch(const std::vector<int>& a, int target) {5 // Scan left to right until the target appears6 for (std::size_t i = 0; i < a.size(); i++) {7 if (a[i] == target) return static_cast<int>(i);8 }9 return -1;10}11
12int main() {13 std::vector<int> nums = {7, 3, 9, 1, 5, 8, 2};14 std::cout << "Index of 5: " << linearSearch(nums, 5) << "\n";15 std::cout << "Index of 4: " << linearSearch(nums, 4) << "\n";16 return 0;17}קוד Linear Search ב-C
1#include <stdio.h>2
3int linear_search(const int a[], int n, int target) {4 /* Scan left to right until the target appears */5 for (int i = 0; i < n; i++) {6 if (a[i] == target) return i;7 }8 return -1;9}10
11int main(void) {12 int nums[] = {7, 3, 9, 1, 5, 8, 2};13 int n = sizeof(nums) / sizeof(nums[0]);14 printf("Index of 5: %d\n", linear_search(nums, n, 5));15 printf("Index of 4: %d\n", linear_search(nums, n, 4));16 return 0;17}קוד Linear Search ב-Pseudocode
1DECLARE nums : ARRAY[1:7] OF INTEGER2DECLARE n : INTEGER3n ← 74nums[1] ← 75nums[2] ← 36nums[3] ← 97nums[4] ← 18nums[5] ← 59nums[6] ← 810nums[7] ← 211
12FUNCTION linearSearch(target : INTEGER) RETURNS INTEGER13 DECLARE i : INTEGER14 // Scan left to right until the target appears15 FOR i ← 1 TO n16 IF nums[i] = target THEN17 RETURN i18 ENDIF19 NEXT i20 RETURN -121ENDFUNCTION22
23OUTPUT "Index of 5 is ", linearSearch(5)24OUTPUT "Index of 4 is ", linearSearch(4)שאלות נפוצות על חיפוש ליניארי
מהי סיבוכיות הזמן של חיפוש ליניארי?
O(n) במקרה הממוצע ובמקרה הגרוע (ייתכן שהסריקה תצטרך לבקר בכל איבר) ו-O(1) במקרה הטוב, כשהאיבר הראשון הוא המטרה. הוא משתמש ב-O(1) זיכרון נוסף.האם חיפוש ליניארי צריך נתונים ממוינים?
מתי חיפוש ליניארי עדיף על חיפוש בינארי?
O(n log n)), כשהאוסף זעיר, או כשיש רק גישה סדרתית, כמו זרם או רשימה מקושרת. לחיפושים חוזרים במערכים ממוינים, חיפוש בינארי מנצח.האם חיפוש ליניארי זהה לחיפוש סדרתי?
כמה השוואות חיפוש ליניארי מבצע בממוצע?
n/2 השוואות בממוצע; אם המטרה לא קיימת, בדיוק n. הגדילה הליניארית הזו היא הסיבה שהוא נקרא חיפוש ליניארי.