קורס תכנות

Post on 04-Jan-2016

53 Views

Category:

Documents

9 Downloads

Preview:

Click to see full reader

DESCRIPTION

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

TRANSCRIPT

קורס תכנות

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

משתנים, מצביעים וכתובות

type nameמוגדר ע"י משתנה •

type * nameמוגדר ע"י משתנה מצביע •

- אופרטור שמחזיר כתובת של משתנה &•

- אופרטור שמקבל מצביע מחזיר הערך *•

מערכים ומצביעים

מצביע מכיל כתובת, שם המערך הוא כתובת•

ניתן לבצע השמה בין המערך ומצביע•

לאחר ההשמה ניתן להשתמש במצביע כאילו היה שם •המערך

ניתן להשתמש במערך כאילו היה מצביע•

int *ptr;int array[10];

ptr = array;

ptr[2] = 25;

*array = 4;

✝למה צריך מצביעים?

משתנה•ניתן לשנות את ערכו אך ורק בפונקציה בה הוגדר•

מצביע•נותן לנו גישה אל משתנים שהוגדרו בפונקציות •

אחרות משנה ערכים של משתניםscanfהפונקציה דוגמא:•

פונקציה יכולה לחשב מספר ערכים ולשמור אותם •בכתובות שהועברו אליה )כמו להחזיר מספר

ערכים מפונקציה(עוד סיבות בהמשך✝

strstrהפונקציה

char str[] = “Ding Dong”;

char *res = strstr(str,”Don”);

res

printf(“res=%p\n”,res);printf(“res=%s\n”,res);

res=6505res=Dong

D i n g D o n g \06500

6500str

דוגמא – כמה פעמים מופיעה מילה בשיר

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באינטרנט...

מיון

מערך ממויין הוא מערך שערכיו מסודרים בסדר •עולה/יורד.

אחד השימושים הכי נפוצים במערכים הוא לצורך מיון של •מספרים.

דוגמא למערך ממויין:•

1 2 5 678 139

9

למה צריך למיין מידע?

כדי למצוא ערך, ומהר!•

נרצה לחפש בו כמה מספרים Nבהינתן מערך בגודל •מסויימים כדי לדעת האם הם נמצאים בו ואיפה?

בהינתן מספר שברצוננו למצוא, נסרוק את פתרון נאיבי:•המערך מההתחלה ונחפש את המספר.

N/2הפתרון לא יעיל, כל חיפוש ידרוש בממוצע כ- •פעולות.

פתרון יעיל יותר:•

נמיין את המערך פעם אחת ואז ניתן לבצע בו חיפוש •הרבה יותר מהר!

10

חיפוש נאיבי במערך לא ממויין

( נמצא במערך 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;{

12

חיפוש בינארי )דורש מערך ממוין(

:קלט•Aמערך ממויין של מספרים שלמים •

qמספר שלם שברצוננו לחפש •

:פלט•A לא נמצא ב- q- אם 1•

.q שבו נמצא Aאחרת, את האינדקס במערך •:האלגוריתם•

Aבדוק את האיבר האמצעי במערך •

החזר את האינדקסq אם הוא שווה ל-•A[0, … , middle-1] ב- q, חפש את q אם האיבר האמצעי קטן מ-•

,… ,A[middle+1 ב- q, חפש את q אם האיבר האמצעי גדול מ-•end]

13

דוגמא

-5-30481122565797value

index 0 2 3 4 51 6 7 8 9

...56נחפש את

14

דוגמא

-5-30481122565797value

index 0 2 3 4 51 6 7 8 9

...4נחפש את

15

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);

elsereturn

binarySearchRec(arr,quary,middle+1,end);}

16

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);}

17

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));

18

אז... כמה זמן לוקח לעשות חיפוש בינארי?

חישוב סיבוכיות זמן ריצה:

נחשוב על המקרה הגרוע ביותר•

גודל המערך שבו אנו מחפשים הולך וקטן בכל קריאה רקורסיבית•n n/2 n/4 ….. 1

כל צעד באלגוריתם הוא מאוד מהיר •(c)מספר קבוע וקטן של פעולות =

צעדים לכל היותר. log2(n)יש •

פעולות, שזה בקירוב c*log2(n)לכן סה"כ האלגוריתם יבצע •log2(n).

צעדים בלבד!20 חיפוש בינארי יבצע כ- n = 1,000,000אם •

פעולותnהרבה יותר מהיר מהאלגוריתם הנאיבי שמבצע כ-•

על רגל אחת...סיבוכיות זמן ריצה

מודדים סיבוכיות של אלגוריתם עפ"י •.זמן ריצה )כמות זיכרון( ומדד של מקוםמדד של

, ללא התחשבות בפעולות בכלליותהערכת הסיבוכיות נעשית •קצרות שמספרם קבוע )כלומר לא תלוי בגודל הקלט(.

.O– מסומן ב- בסדרי גודל מעריכים את זמן הריצה •

n = 1,000,000לדוגמא, נניח שאנו עובדים על מערך בגודל •

• O(n2) = constant * trillion (Tera)

• O(n) = constant * million (Mega)

• O(log(n)) = constant * 20

19

20

הבדלים מספריים

nlg nn lg nn2

1001

16464256

25682,04865,536

4,0961249,15216,777,216

65,536161,048,5654,294,967,296

1,048,5762020,971,5201,099,511,627,776

16,777,21624402,653,183281,474,976,710,656

השוואה גרפית

21

23

חיפוש בינארי עם מצביעים

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(;}

24

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);

חיפוש בינארי איטרטיבי

25

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 678 139

?10< ?10< ?10< ?10< ?10< ?10<

671310

1 2 5 678 139

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;{

27

יתרונות וחסרונות של שימוש במערכים

28

יתרונות:•

גישה ישירה ומיידית ע"י אינדקסים•

חיפוש מהיר )כאשר המערך ממויין(•

חסרונות: •

לא יעיל עבור שינויים דינמיים במערך כגון:•

הוספת איבר באמצע המערך•

מחיקת איבר )צמצום רווחים(•

שינוי מיקום של איבר במערך•

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

איך נמיין מערך קיים ביעילות?

עד עכשיו הנחנו שהמערך ממויין...

29

Bubble Sortמיון בועות -

30

נסרוק את המערך ונשווה כל זוג ערכים שכנים•נחליף ביניהם אם הם בסדר הפוך•נחזור על התהליך עד שלא צריך לבצע יותר החלפות •

)המערך ממויין(

למה בועות? •האלגוריתם "מבעבע" בכל סריקה את האיבר •

הגדול ביותר למקומו הנכון בסוף המערך.

31

Bubble Sort Example

7 2 8 5 4

2 7 8 5 4

2 7 8 5 4

2 7 5 8 4

2 7 5 4 8

2 7 5 4 8

2 5 7 4 8

2 5 4 7 8

2 7 5 4 8

2 5 4 7 8

2 4 5 7 8

2 5 4 7 8

2 4 5 7 8

2 4 5 7 8

(done)

32

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]) {

// swaptmp = arr[j];arr[j] = arr[j+1];arr[j+1] = tmp;

}}

33

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;}

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]) {

// swaptmp = arr[j];arr[j] = arr[j+1];arr[j+1] = tmp;

}}

34

מיון בועות – ניתוח סיבוכיות זמן ריצה

nעבור מערך בגודל

n iterations

i iterations

constant

(n-1 + n-2 + n-3 + …. + 1 * )const ~ ½ * n2

35

דוגמאות לחישוב סיבוכיות זמן ריצה

מצא ערך מקסימלי במערך לא ממויין•מצא ערך מקסימלי במערך ממויין•מצא את הערך החמישי הכי גדול במערך •

ממוייןמצא ערך מסויים במערך לא ממויין•מצא ערך מסויים במערך ממויין• "שאלות פיבונאצ'י"nענה על •

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

,)O)n2ראינו שאפשר למיין מערך ב-

!כןהאם אפשר למיין מהר יותר?

36

MERGE SORT

Merge Sortהעקרונות -

ניתן למיין מערך קצר הרבה יותר מהר מאשר מערך ארוך•

מערכים ממויינים, ניתן לאחד אותם למערך 2בהנתן •.)O)nממויין אחד די מהר –

37

מערכים ממויינים2איחוד

38

12579 346810

p q

u

1

u

p p p p q q q q

u u u u u u u u

2 3 4 5 6 7 8 9 10

p

Merge Sortאלגוריתם -

אז הוא כבר ממויין.0 או 1אם המערך בגודל 1.

אחרת...

חצאים2חלק את המערך ל-2.

(MergeSortמיין כל תת-מערך רקורסיבית )ע"י קריאה ל-3.

אחד את שני תתי-המערכים הממויינים למערך ממויין 4.

אחד.

39

40

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);

}

41

Merge Sortדוגמא -

Merge Sortניתוח סיבוכיות זמן ריצה –

42

אז הוא כבר ממויין.0 או 1אם המערך בגודל 1.אחרת...

חצאים2חלק את המערך ל-2.

(MergeSortמיין כל תת-מערך רקורסיבית )ע"י קריאה ל-3.

אחד את שני תתי-המערכים הממויינים למערך ממויין 4.אחד.

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

השוואה גרפית

43

,))O)n log)nראינו שאפשר למיין מערך ב-

...לפעמיםהאם אפשר למיין מהר יותר?

44

BUCKET SORT

45

Bucket Sort

O(n)אלגוריתם בזמן לינארי : •

אבל... מוגבל למספרים שלמים, חסומים •בטווח.

46

Bucket Sort

מיון מחרוזות

עד כה מיינו מספרים•

איך נמיין מחרוזות?•

בסדר לקסיקוגרפי )מילוני(•

פרטים בתרגול...•

47

מיון גנרי

/ int / long / double / floatנרצה למיין מערך של •

char

עולה / יורדבסדר •

מה ההבדל בין המקרים?•

האלגוריתם זהה!•

האם נהיה חייבים לשכפל קוד עבור כל מקרה?•

48

49

הרעיון של מיון גנרי

נכתוב פונקציה אחת שתוכל למיין מערכים של•

int / long / double / float / char

.עולה או יורדבסדר

מה יהיו הפרמטרים?•

מצביע למערך•

מצביע לפונקציית השוואה•

void אפשר להעביר לפונקציה מצביע למערך כללי )Cב-•*)

וניתן להעביר לפונקציה מצביע לפונקציית ההשוואה.•

לא נכנס לפרטים במסגרת קורס זה...•

הרעיון של מיון גנרי

50Memory

Comperatorcode

array

top related