שיעור עשירי: מיונים, חיפושים, וקצת סיבוכיות חישוב

Slides:



Advertisements
Similar presentations
ממיבחניםC שאלות ++.
Advertisements

מבוא למדעי המחשב לתעשייה וניהול
Pointers הרצאה קריטית. השאלות הפתוחות מה זה ה- & שמופיע ב scanf מדוע כשמעבירים מחרוזת ל scanf אין צורך ב & האם ניתן להכריז על מערך שגדלו אינו ידוע בתחילת.
מיון (Sorting) קלט : מערך בן n מספרים. פלט : מערך ובו המספרים אותם מאוחסנים בסדר עולה
רקורסיות נושאי השיעור פתרון משוואות רקורסיביות שיטת ההצבה
מסדי נתונים תשס " ג 1 תכנון סכמות (Design Theory) מסדי נתונים.
תכנות תרגול 6 שבוע : חישוב e זוהי הנוסחא לחישוב e נראה כיצד לתרגם אותה לפונקציה n n.
תרגול 5 רקורסיות. רקורסיה קריאה של פונקציה לעצמה –באופן ישיר או באופן עקיף היתרון : תכנות של דברים מסובכים נעשה ברור ונוח יותר, מכיוון שזו למעשה צורת.
מה החומר למבחן ? כל החומר שנלמד בהרצאות ובתרגולים. לגבי backtracking: לא תידרשו לממש אלגוריתם, אך כן להבין או להשלים מימוש נתון. אחת משאלות המבחן מבוססת.
תכנות תרגול 4 שבוע : לולאות while לולאות while while (condition) { loop body } במקרה של קיום התנאי מתבצע גוף הלולאה ברגע שהתנאי לא מתקיים נצא.
מבוא לשפת C חידות ונקודות חשובות נכתב על-ידי יורי פקלני. © כל הזכויות שמורות לטכניון – מכון טכנולוגי לישראל.
מבוא כללי למדעי המחשב תרגול. הבית האדום כתובת : רחוב קוקוריקו 2 הבית הירוק כתובת : רחוב קוקוריקו 4 הבית הצהוב כתובת : רחוב קוקוריקו 1 הבית הורוד כתובת.
תכנות תרגול 9 שבוע : מערכים int a; a=5; int a[10]; a[2] = 5; 5 a a[0] a[1] a[2] a[9]  5 משתנה בודד מערך גישה למשתנה השלישי במערך.
בהסתברות לפחות למצא בעיה במודל PAC עבור בהסתברות ε הפונקציה f טועה מודל ONLINE 1. אחרי כל טעות הפונקציה משתפרת 2. מספר הטעיות קטן.
11 Introduction to Programming in C - Fall 2010 – Erez Sharvit, Amir Menczel 1 Introduction to Programming in C תרגול
רקורסיות 18 יוני יוני יוני 1518 יוני יוני יוני 1518 יוני יוני יוני 151.
תכנות תרגול 6 שבוע : תרגיל שורש של מספר מחושב לפי הסדרה הבאה : root 0 = 1 root n = root n-1 + a / root n-1 2 כאשר האיבר ה n של הסדרה הוא קירוב.
11 Introduction to Programming in C - Fall 2010 – Erez Sharvit, Amir Menczel 1 Introduction to Programming in C תרגול
ערמות ; מבני נתונים 09 מבוסס על מצגות של ליאור שפירא, חיים קפלן, דני פלדמן וחברים.
תכנות תרגול 6 שבוע : הגדרת פונקציות return-value-type function-name(parameter1, parameter2, …) הגדרת סוג הערכים שהפונקציה מחזירה שם הפונקציהרשימת.
תכנות – שיעור 7. חזרה -מערכים נגדיר בעזרתו קבוצת משתנים כאשר יהיה לנו מספר רב של משתנים זהים נגדיר בעזרתו קבוצת משתנים כאשר יהיה לנו מספר רב של משתנים.
מודל ONLINE לומדמורה 1. כל ניתן לחישוב בזמן פולינומיאלי 2. אחרי מספר פולינומיאלי של טעיות ( ) הלומד לא טועה ז"א שווה ל- Littlestone 1988.
תכנות תרגול 14 שבוע:
תכנות תרגול 10 שבוע : הקשר בין מערכים למצביעים נרצה לעמוד על הקשר בין מערך למצביע מאחר ומערכים הם הכללה של משתנים הרי שברור שלמערך ולכל אחד מאיבריו.
מבוא כללי למדעי המחשב תרגול 3. לולאות while לולאות while while (condition) { loop body } במקרה של קיום התנאי מתבצע גוף הלולאה ברגע שהתנאי לא מתקיים נצא.
קורס תכנות – סימסטר ב ' תשס " ח שיעור שישי: מערכים
Data Structures, CS, TAU, Perfect Hashing 1 Perfect Hashing בעיה : נתונה קבוצה S של n מפתחות מתחום U השוואה ל - Hash : * טבלה קבועה (Hash רגיל - דינאמי.
1 Data Structures, CS, TAU, Perfect Hashing בעיה: נתונה קבוצה S של n מפתחות מתחום U השוואה ל- Hash : * טבלה קבועה (Hash רגיל - דינאמי) * רוצים זמן קבוע.
מערכים עד היום כדי לייצג 20 סטודנטים נאלצנו להגדיר עד היום כדי לייצג 20 סטודנטים נאלצנו להגדיר int grade1, grade2, …, grade20; int grade1, grade2, …, grade20;
מודל הלמידה מדוגמאות Learning from Examples קלט: אוסף של דוגמאות פלט: קונסיסטנטי עם פונקציה f ב- C ז"א קונסיסטנטי עם S ז"א מודל הלמידה מדוגמאות Learning.
עקרון ההכלה וההדחה.
תכנות מונחה עצמים Object Oriented Programming (OOP) אתגר מחזור ב' Templates תבניות.
מבוא למדעי המחשב תרגול 3 שעת קבלה : יום שני 11:00-12:00 דוא " ל :
מיון (Sorting) קלט : מערך בן n מספרים. פלט : מערך ובו המספרים אותם מאוחסנים בסדר עולה
מודל הלמידה מדוגמאות Learning from Examples קלט: אוסף של דוגמאות פלט: קונסיסטנטי עם פונקציה f ב- C ז"א קונסיסטנטי עם S ז"א.
עצים בינאריים - תזכורת דרגת צומת שורש עלה צומת פנימי מרחק בין 2 צמתים
1 מבוא למדעי המחשב סיבוכיות. 2 סיבוכיות - מוטיבציה סידרת פיבונאצ'י: long fibonacci (int n) { if (n == 1 || n == 2) return 1; else return (fibonacci(n-1)
תכנות תרגול 8 שבוע : מערכים עד היום התוכניות שלנו לא ידעו לשמור כמות גדולה של מידע ללא הגדרת כמות גדולה של משתנים. עד היום התוכניות שלנו לא.
- אמיר רובינשטיין מיונים - Sorting משפט : חסם תחתון על מיון ( המבוסס על השוואות בלבד ) של n מפתחות הינו Ω(nlogn) במקרה הגרוע ובממוצע. ניתן לפעמים.
Structure. מה לומדים היום ? דרך לבנות מבנה נתונים בסיסי – Structure מייצר " טיפוס " חדש מתאים כאשר רוצים לאגד כמה משתנים יחד דוגמאות : עובד : שם, טלפון,
מבוא למדעי המחשב הרצאה 11: תכנות רקורסיבי 4 כולל מיון רקורסיבי 1.
מבנה נתונים ואלגוריתמים ) לשעבר - עיבוד מידע( ד"ר אבי רוזנפלד ד"ר אריאלה ריכרדסון.
קורס תכנות שיעור עשירי: מיונים, חיפושים, וקצת סיבוכיות חישוב.
מבוא למדעי המחשב לתעשייה וניהול הרצאה 12. ספריות.
1 Programming for Engineers in Python Autumn Lecture 9: Sorting, Searching and Time Complexity Analysis.
מבוא למדעי המחשב לתעשייה וניהול הרצאה 6. מפעל השעווה – לולאות  עד עכשיו  טיפלנו בייצור נרות מסוג אחד, במחיר אחיד  למדנו להתמודד עם טיפול במקרים שונים.
מבנה נתונים ואלגוריתמים ) לשעבר - עיבוד מידע( ד"ר אבי רוזנפלד ד"ר אריאלה ריכרדסון.
1 מבוא למדעי המחשב הרצאה 5: פונקציות. 2 מבוא לפונקציות חלוקה של אלגוריתם לתת משימות: משימה - פונקציה: דוגמאות מציאת המקסימלי מבין שני איברים האינדקס של.
מספרים אקראיים ניתן לייצר מספרים אקראיים ע"י הפונקציה int rand(void);
Programming Arrays.
Tirgul 12 Trees 1.
Computer Architecture and Assembly Language
שיעור עשירי: מיונים, חיפושים, וקצת סיבוכיות חישוב
מבוא למדעי המחשב סיבוכיות.
מיונים וחיפושים קרן כליף.
מבוא למדעי המחשב – סמסטר א' תשע"ב
ניתוח זמן ריצה (על קצה המזלג)
מצביעים קרן כליף.
קורס תכנות שיעור עשירי: מיונים, חיפושים, קצת ניתוח זמני ריצה, קצת תיקון טעויות ועוד על רשימות.
תירגול 14: מבני נתונים דינאמיים
שיעור שישי: מחרוזות, מצביעים
ניתוח זמן ריצה (על קצה המזלג)
מבוא למדעי המחשב הרצאה 6: מיונים.
בעיות נוספות ב-NPC.
ניתוח זמן ריצה (על קצה המזלג)
מבוא כללי למדעי המחשב תרגול 6
מערכים של מצביעים הקצאה דינאמית
Computer Programming תרגול 3 Summer 2016
Engineering Programming A
Computer Architecture and Assembly Language
Presentation transcript:

שיעור עשירי: מיונים, חיפושים, וקצת סיבוכיות חישוב קורס תכנות שיעור עשירי: מיונים, חיפושים, וקצת סיבוכיות חישוב

משתנים, מצביעים וכתובות משתנה מוגדר ע"י type name משתנה מצביע מוגדר ע"י type * name & - אופרטור שמחזיר כתובת של משתנה * - אופרטור שמקבל מצביע מחזיר הערך

מערכים ומצביעים מצביע מכיל כתובת, שם המערך הוא כתובת ניתן לבצע השמה בין המערך ומצביע לאחר ההשמה ניתן להשתמש במצביע כאילו היה שם המערך ניתן להשתמש במערך כאילו היה מצביע int *ptr; int array[10]; ptr = array; ptr[2] = 25; *array = 4;

למה צריך מצביעים?✝ משתנה מצביע ניתן לשנות את ערכו אך ורק בפונקציה בה הוגדר מצביע נותן לנו גישה אל משתנים שהוגדרו בפונקציות אחרות דוגמא: הפונקציה scanf משנה ערכים של משתנים פונקציה יכולה לחשב מספר ערכים ולשמור אותם בכתובות שהועברו אליה (כמו להחזיר מספר ערכים מפונקציה) ✝עוד סיבות בהמשך

הפונקציה strstr printf(“res=%p\n”,res); printf(“res=%s\n”,res); char str[] = “Ding Dong”; char *res = strstr(str,”Don”); D i n g o \0 6500 str res printf(“res=%p\n”,res); printf(“res=%s\n”,res); res=6505 res=Dong

דוגמא – כמה פעמים מופיעה מילה בשיר int main() { const char rhyme[] = "Humpty Dumpty sat on a wall,\n " "Humpty Dumpty had a great fall.\n " "All the king's horses,\n" "And all the king's men,\n" "Couldn't put Humpty together again.\n"; const char humpty[] = "Humpty"; char *ptr = NULL; int count = 0; for (ptr = strstr(rhyme, humpty); ptr != NULL; ptr = strstr(ptr + 1, humpty)) { count++; } printf("The string %s appears %d times\n", humpty, count); return 0;

הנושאים להיום סוגי מידע החשיבות של גישה מהירה למידע איך ניתן לעשות זאת? עיבוד מוקדם של המידע יאפשר גישה מהירה למידע שמעניין אותנו. מבנה הנתונים הבסיסי ביותר: מערך עיבוד מוקדם  מיון גישה מהירה  חיפוש סיבוכיות זמן ריצה 7

סוגי מידע קיימים כ-20,000,000,000 אתרים באינטרנט... 8 8

מיון מערך ממויין הוא מערך שערכיו מסודרים בסדר עולה/יורד. אחד השימושים הכי נפוצים במערכים הוא לצורך מיון של מספרים. דוגמא למערך ממויין: 1 2 5 67 8 13 9

למה צריך למיין מידע? כדי למצוא ערך, ומהר! בהינתן מערך בגודל N נרצה לחפש בו כמה מספרים מסויימים כדי לדעת האם הם נמצאים בו ואיפה? פתרון נאיבי: בהינתן מספר שברצוננו למצוא, נסרוק את המערך מההתחלה ונחפש את המספר. הפתרון לא יעיל, כל חיפוש ידרוש בממוצע כ- N/2 פעולות. פתרון יעיל יותר: נמיין את המערך פעם אחת ואז ניתן לבצע בו חיפוש הרבה יותר מהר!

חיפוש נאיבי במערך לא ממויין נרצה לדעת האם ערך כלשהו (value) נמצא במערך ואיפה אפשרות א': חיפוש "רגיל" – מעבר על כל ערכי המערך int regular_serach(int array[], int size, int value) { int i; for (i = 0; i < size; i++) if (array[i] == value) return 1; } return -1;

חיפוש בינארי (דורש מערך ממוין) קלט: מערך ממויין של מספרים שלמים A מספר שלם שברצוננו לחפש q פלט: 1- אם q לא נמצא ב- A אחרת, את האינדקס במערך A שבו נמצא q. האלגוריתם: בדוק את האיבר האמצעי במערך A אם הוא שווה ל- q החזר את האינדקס אם האיבר האמצעי קטן מ- q, חפש את q ב- A[0, … , middle-1] אם האיבר האמצעי גדול מ- q, חפש את q ב- A[middle+1, …, end]

דוגמא נחפש את 56... index 2 3 4 5 1 6 7 8 9 value -5 -3 4 8 11 22 56 57 97

דוגמא נחפש את 4... index 2 3 4 5 1 6 7 8 9 value -5 -3 4 8 11 22 56 57 97

Code – Binary Search int binarySearchRec(int arr[], int quary, int start, int end) { int middle; if (start > end) return -1; middle = start + (end-start) / 2; if (arr[middle] == quary) return middle; if (arr[middle] > quary) return binarySearchRec(arr,quary,start,middle-1); else return binarySearchRec(arr,quary,middle+1,end); }

Code – Main int a [] = {-5,-3,0,4,8,11,22,56,57,97};   printf("%d\n",binarySearch(a,SIZE,0)); printf("%d\n",binarySearch(a,SIZE,-4)); printf("%d\n",binarySearch(a,SIZE,8)); printf("%d\n",binarySearch(a,SIZE,1)); printf("%d\n",binarySearch(a,SIZE,-5)); printf("%d\n",binarySearch(a,SIZE,9)); printf("%d\n",binarySearch(a,SIZE,7)); int binarySearch(int arr[], int size, int quary) { return binarySearchRec(arr,quary,0,size-1); }

Output int a [] = {-5,-3,0,4,8,11,22,56,57,97};   printf("%d\n",binarySearch(a,SIZE,0)); printf("%d\n",binarySearch(a,SIZE,-4)); printf("%d\n",binarySearch(a,SIZE,8)); printf("%d\n",binarySearch(a,SIZE,1)); printf("%d\n",binarySearch(a,SIZE,-5)); printf("%d\n",binarySearch(a,SIZE,9)); printf("%d\n",binarySearch(a,SIZE,7));

אז... כמה זמן לוקח לעשות חיפוש בינארי? חישוב סיבוכיות זמן ריצה: נחשוב על המקרה הגרוע ביותר גודל המערך שבו אנו מחפשים הולך וקטן בכל קריאה רקורסיבית n  n/2  n/4  …..  1 כל צעד באלגוריתם הוא מאוד מהיר (מספר קבוע וקטן של פעולות = c) יש log2(n) צעדים לכל היותר. לכן סה"כ האלגוריתם יבצע c*log2(n) פעולות, שזה בקירוב log2(n). אם n = 1,000,000 חיפוש בינארי יבצע כ-20 צעדים בלבד! הרבה יותר מהיר מהאלגוריתם הנאיבי שמבצע כ-n פעולות

סיבוכיות זמן ריצה על רגל אחת... מודדים סיבוכיות של אלגוריתם עפ"י מדד של מקום (כמות זיכרון) ומדד של זמן ריצה. הערכת הסיבוכיות נעשית בכלליות, ללא התחשבות בפעולות קצרות שמספרם קבוע (כלומר לא תלוי בגודל הקלט). מעריכים את זמן הריצה בסדרי גודל – מסומן ב- O. לדוגמא, נניח שאנו עובדים על מערך בגודל n = 1,000,000 O(n2) = constant * trillion (Tera) O(n) = constant * million (Mega) O(log(n)) = constant * 20

הבדלים מספריים n lg n n lg n n2 1 16 4 64 256 8 2,048 65,536 4,096 12 16 4 64 256 8 2,048 65,536 4,096 12 49,152 16,777,216 1,048,565 4,294,967,296 1,048,576 20 20,971,520 1,099,511,627,776 24 402,653,183 281,474,976,710,656 20

השוואה גרפית

חיפוש בינארי עם מצביעים int * binarySearch (int arr [ ], int size, int quary) { int * middle; if (size == 0) return NULL; middle = arr + size/ 2; if (*middle == quary) return middle; if (*middle > quary) return binarySearch(arr, size/2, quary); else return binarySearch(arr+size/2+1, size-size/2-1, quary); } 23

Main & Output int a [] = {-5,-3,0,4,8,11,22,56,57,97}; int * ind = binarySearch(a,SIZE,0); if (ind != NULL) printf("%d\n",ind - a); 24

חיפוש בינארי איטרטיבי int binarySearch(int arr [], int size, int quary) { int start= 0, end = size - 1; int middle; while (start <= end) { middle = (start + end) / 2; if (quary == arr [middle]) return middle; if (quary < arr [middle]) end = middle - 1; if (quary > arr [middle]) start = middle + 1; } return -1;

הוספת מספר למערך ממויין קלט: מערך ממויין והערך 10 צעד אחר צעד: 1 2 5 67 8 13 9 1 2 5 8 9 13 10 67 13 67 ?10< ?10< ?10< ?10< ?10< ?10< 26 26

הוספת מספר למערך ממויין /* * Requires: * 1. The elements of the array are sorted in ascending order. * 2. length < capacity * length is the current number of elements in the array * capacity is the maximum number of elements array */ void array_add(int array[], int length, int value) { int i, j; for (i = 0; i < length && array[i] <= value; i++); for (j = length; j > i; j--) array[j] = array[j - 1]; array[i] = value;

יתרונות וחסרונות של שימוש במערכים יתרונות: גישה ישירה ומיידית ע"י אינדקסים חיפוש מהיר (כאשר המערך ממויין) חסרונות: לא יעיל עבור שינויים דינמיים במערך כגון: הוספת איבר באמצע המערך מחיקת איבר (צמצום רווחים) שינוי מיקום של איבר במערך בהמשך הקורס נלמד מבנה נתונים נוסף שמאפשר ביצוע שינויים דינמיים כאלה ביעילות (רשימה מקושרת).

איך נמיין מערך קיים ביעילות? עד עכשיו הנחנו שהמערך ממויין... איך נמיין מערך קיים ביעילות?

מיון בועות - Bubble Sort נסרוק את המערך ונשווה כל זוג ערכים שכנים נחליף ביניהם אם הם בסדר הפוך נחזור על התהליך עד שלא צריך לבצע יותר החלפות (המערך ממויין) למה בועות? האלגוריתם "מבעבע" בכל סריקה את האיבר הגדול ביותר למקומו הנכון בסוף המערך. 30 30

Bubble Sort Example 7 2 8 5 4 2 7 5 4 8 2 5 4 7 8 2 4 5 7 8 2 7 8 5 4 2 7 5 4 8 2 5 4 7 8 2 4 5 7 8 2 7 8 5 4 2 5 7 4 8 2 4 5 7 8 (done) 2 7 5 8 4 2 5 4 7 8 2 7 5 4 8

Bubble Sort Code void bubbleSort(int arr[], int size) { int i,j,tmp; for (i = size - 1; i > 0; --i) for (j = 0; j < i; ++j) if (arr[j] > arr[j+1]) { // swap tmp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = tmp; }

Bubble Sort Code int main() { int i, a [] = {7,2,8,5,4}; bubbleSort(a,SIZE); for (i = 0; i < SIZE; ++i) printf("%d ",a[i]); printf("\n"); return 0; }

מיון בועות – ניתוח סיבוכיות זמן ריצה עבור מערך בגודל n void bubbleSort(int arr[], int size) { int i,j; for (i = size - 1; i > 0; --i) for (j = 0; j < i; ++j) if (arr[j] > arr[j+1]) { // swap tmp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = tmp; } } n iterations i iterations constant (n-1 + n-2 + n-3 + …. + 1) * const ~ ½ * n2 34

דוגמאות לחישוב סיבוכיות זמן ריצה מצא ערך מקסימלי במערך לא ממויין מצא ערך מקסימלי במערך ממויין מצא את הערך החמישי הכי גדול במערך ממויין מצא ערך מסויים במערך לא ממויין מצא ערך מסויים במערך ממויין ענה על n "שאלות פיבונאצ'י" שאלת פיבונאצ'י: מהו הערך ה-K בסדרת פיבונאצ'י? נניח ש-K מוגבל להיות קטן מ-MAX 35

MERGE SORT כן! ראינו שאפשר למיין מערך ב- O(n2), האם אפשר למיין מהר יותר? כן! MERGE SORT

Merge Sort - העקרונות ניתן למיין מערך קצר הרבה יותר מהר מאשר מערך ארוך בהנתן 2 מערכים ממויינים, ניתן לאחד אותם למערך ממויין אחד די מהר – O(n).

איחוד 2 מערכים ממויינים p p p p p p q q q q q 9 7 5 2 1 10 8 6 4 3 u u

Merge Sort - אלגוריתם אם המערך בגודל 1 או 0 אז הוא כבר ממויין. אחרת... חלק את המערך ל-2 חצאים מיין כל תת-מערך רקורסיבית (ע"י קריאה ל-MergeSort) אחד את שני תתי-המערכים הממויינים למערך ממויין אחד.

Merge Sort (partial) Code void mergeSortRec(int arr[], int start, int end) { int middle = (end - start) / 2; if ((end - start) < 2) return; mergeSortRec(arr,start,middle); mergeSortRec(arr,middle+1,end); mergeArrays(arr,start,middle,middle+1,end); } void mergeSort(int arr [], int size) { return mergeSortRec(arr,0,size-1); 40

Merge Sort - דוגמא 41

Merge Sort – ניתוח סיבוכיות זמן ריצה אם המערך בגודל 1 או 0 אז הוא כבר ממויין. אחרת... חלק את המערך ל-2 חצאים מיין כל תת-מערך רקורסיבית (ע"י קריאה ל-MergeSort) אחד את שני תתי-המערכים הממויינים למערך ממויין אחד. n + 2 * (n/2) + 22 * n/22 + 23 * n/23 + … + 2log(n) * n/2log(n) = n + n + … + n = (n+1) * log(n) log(n) +1

השוואה גרפית

Bucket sort לפעמים... ראינו שאפשר למיין מערך ב- O(n log(n)), האם אפשר למיין מהר יותר? לפעמים... Bucket sort

Bucket Sort אלגוריתם בזמן לינארי : O(n) אבל... מוגבל למספרים שלמים, חסומים בטווח. 45

Bucket Sort 46

מיון מחרוזות עד כה מיינו מספרים איך נמיין מחרוזות? בסדר לקסיקוגרפי (מילוני) פרטים בתרגול...

מיון גנרי נרצה למיין מערך של int / long / double / float / char בסדר עולה / יורד מה ההבדל בין המקרים? האלגוריתם זהה! האם נהיה חייבים לשכפל קוד עבור כל מקרה?

הרעיון של מיון גנרי נכתוב פונקציה אחת שתוכל למיין מערכים של int / long / double / float / char בסדר עולה או יורד. מה יהיו הפרמטרים? מצביע למערך מצביע לפונקציית השוואה 49

הרעיון של מיון גנרי ב-C אפשר להעביר לפונקציה מצביע למערך כללי (void *) וניתן להעביר לפונקציה מצביע לפונקציית ההשוואה. לא נכנס לפרטים במסגרת קורס זה... Comperator code array Memory 50