Presentation is loading. Please wait.

Presentation is loading. Please wait.

תכנות בשפת C תרגול 12 עצים בינאריים 20.05.2011.

Similar presentations


Presentation on theme: "תכנות בשפת C תרגול 12 עצים בינאריים 20.05.2011."— Presentation transcript:

1 תכנות בשפת C תרגול 12 עצים בינאריים

2 עצים גרף קשיר ללא מעגלים ייקרא עץ.
כאשר נשתמש במבנה נתונים של עצים ב- C, נשתמש בעצים מכוונים: כל צומת בגרף יכיל מידע כלשהו (יהיה מופע של מבנה של תא בעץ). שורש – צומת שאף איבר אחר בעץ לא יצביע עליו. יהיה ה"עוגן" של העץ שלנו (בציור בתמונה – G). יש ממנו מסלול לכל צומת בעץ. הקשתות יהיו המצביעים שלנו (בציור – כל צומת יכיל מצביעים לצמתים שהוא מחובר עליהם ישירות בשורה שמתחתיו – התא שערכו C יצביע על התאים שערכם A ו- F)

3 אבות ובנים אם מצומת מסוים יש קשת לצומת אחר, לדוגמא G ל- C, נקרא ל- G האבא של C, ול-C הבן של G. אם המסלול מהשורש לצומת מסויים n1 עובר דרך צומת n2, אזי n2 היינו אב-קדמון של n1. בתרשים – C היננו אב קדמון של B. שימו לב – A הוא גם אב וגם אב-קדמון של B.

4 צמתים פנימיים ועלים עלה – צומת שאין ממנו קשתות (לא מצביע) לאף צומת אחר. בתרשים – הצמתים B,E,W הינם עלים. צומת פנימי – צומת שאיננו עלה; כלומר צומת שיש ממנו קשת ללפחות צומת אחד.

5 גבהים ועומקים גובה של צומת היננו מספר הצמתים (כולל הוא עצמו) במסלול ממנו לעלה הרחוק ממנו ביותר (כולל העלה). גובהו של Y הינו 3 גובה של עץ – גובה השורש. גובהו של העץ בתרשים הוא 4. עומק של צומת היננו מספר הצמתים במסלול מהשורש אליו (לא כולל אותו). עומקו של Y בתרשים הוא 1. שימו לב – בגובה מונים את הצומת, בעומק לא!

6 עצים בינאריים ניתן לראות כל צומת בעץ בתור תת-עץ שהוא מהווה את השורש שלו. C הוא שורש בתת-עץ שמכיל את הצמתים C,A,F,B,E. עץ בינארי – עץ שבו לכל צומת לכל היותר 2 בנים. עץ חיפוש בינארי – עץ בינארי שבו ערך כל צומת גדול מכל הערכים בצמתים בתת עץ של בנו השמאלי, וקטן מכל ערכי הצמתים בתת עץ של בנו הימני.

7 איך נגדיר עץ בינארי ב- C? הגדרה ב- C תתבצע באופן דומה לרשימות מקושרות.
כל איבר בעץ יהיה מבנה, כל מבנה כזה יחולק ל-2 חלקים: מצביעים לתאי המשך ו-Data שהוא מכיל. השוני המרכזי – בעץ בינארי ייתכנו 2 בנים לכל צומת, כך שכל תא צריך להכיל 2 מצביעים לתאי המשך. typedef struct tree_node{ int val; struct tree_node* left; struct tree_node* right; } TreeNode;

8 סריקות מה תהיה תוצאות הדפסה של הסריקות הבאות עבור העץ הנתון משמאל:
מה תהיה תוצאות הדפסה של הסריקות הבאות עבור העץ הנתון משמאל: סריקת pre-order. סריקת in-order. סריקת post-order. זכרו – התחלת שם הסריקה מעידה מתי מבקרים באב יחסית לבניו. 1 9 8 6 3 2 5

9 סריקות Preorder – בקר באב ורק אח"כ בבנים:
1, 6, 8, 5, 2, 9, 3 In order – בקר בתת-עץ של בן שמאלי, באב ואח"כ בתת-עץ של בן ימני: 8, 6, 2, 5, 9, 1, 3 Postorder – בקר בבנים ואח"כ באב: 8, 2, 9, 5, 6, 3, 1 1 9 8 6 3 2 5

10 תרגיל 1 צריך לממש את הפונקציה הבאה באופן רקורסיבי:
תרגיל 1 צריך לממש את הפונקציה הבאה באופן רקורסיבי: int treeHeight(TreeNode* tree); הפונקציה מקבלת מצביע לעץ, וצריכה להחזיר את גובה העץ. להזכירכם, גובה העץ היננו מס' הצמתים מהשורש לעלה הרחוק ביותר ממנו.

11 תרגיל 1 – פתרון /*Returns the hight of a given tree. */
תרגיל 1 – פתרון /* Aux. Function*/ int max(int a, int b){ return (a > b ? a: b); } /*Returns the hight of a given tree. */ int treeHight(TreeNode * tree) { if (!tree) return 0; return 1+max(treeHight (tree->left), treeHight (tree->right));

12 תרגיל 2 צריך לממש את הפונקציה הבאה באופן רקורסיבי:
תרגיל 2 צריך לממש את הפונקציה הבאה באופן רקורסיבי: int sumTree(TreeNode* tree); הפונקציה מקבלת מצביע לעץ, וצריכה להחזיר את סכום אברי העץ. האם יש דמיון לתרגיל הקודם (באופן המעבר על העץ)?

13 תרגיל 2 - פתרון /*returns the sum of values on all tree nodes.*/ int sumTree(TreeNode * tree) { if (!tree) return 0; return tree->val+ sumTree(tree->left)+ sumTree(tree->right) ; }

14 תרגיל 3 צריך לממש את הפונקציה הבאה:
תרגיל 3 צריך לממש את הפונקציה הבאה: ListNode* InOrderList(TreeNode* tree); הפונקציה מקבלת מצביע לעץ, וצריכה להחזיר רשימה מקושרת של ערכי העץ כפי שהיו מושגים מסריקת inorder. ניתן להניח שהפונקציות הבאות כבר ממומשות: ListNode* allocateListNode(int val); void appendLists(ListNode*, ListNode*); 3 1 6

15 תרגיל 3 - פתרון ListNode * InOrderList(TreeNode * root){ ListNode * curr, * left = NULL, * right = NULL; if (root) { left = InOrderList(root->left); right = InOrderList(root->right); curr = allocateListNode(root->val); curr->next = right; left = appendLists(left, curr); } return left;

16 שאלת מבחן 1 נתונה ההגדרה הבאה של צומת בעץ בינארי: typedef struct tree tree; struct tree { int value; int count; tree* left, *right; }; כתוב פונקציה רקורסיבית int fillNode(tree * node , int number) שמקבלת צומת בעץ ומספר שלם. הפונקציה תחשב כמה צמתים מתחת לצומת הנוכחי (כולל הצומת הנוכחי) מכילים את הערך number של node. את הערך שחושב תכניס למשתנה count ב- node.

17 שאלת מבחן 1 - המשך כתוב פונקציה רקורסיבית void fillTree(tree * root) שמקבלת עץ בינארי ומחשבת עבור כל צומת בו כמה צמתים מתחתיו כולל הוא עצמו מכילים את הערך number. את תוצאת החישוב נכניס למשתנה count בצומת הנוכחי. value=5 | count=3 2 | 3 2 | 1 3 | 3 3 | 1 5 | 1 tree 3 | 2

18 שאלת מבחן 1 - פתרון int fillNode(tree *node,int value){ int temp; if(!node) return 0; temp=fillNode(node->left, value) + fillNode(node->right, value); if(node->value==value) node->count = ++temp; return temp; }

19 שאלת מבחן 1 – פתרון (המשך)
void fillTree(node *root){ if(!root) return; fillNode(root, root->value); fillTree(root->left); fillTree(root->right); }

20 שאלת מבחן 2 נתון עץ בינארי שקדקודיו מהטיפוס הבא:
struct node{ int value; node *left; node *right; }node; כתוב פונקציה countNodes אשר מקבלת שורש של עץ בינארי ורמה בעץ וסופרת כמה קדקודים יש מרמה זו ומטה. (השורש נמצא ברמה 0)

21 פתרון int countNodesFrom(node *root, int level) { int count;
if (!root) return 0; count = level <= 0 ? 1 : 0; count += countNodeFrom( root->left, level – 1) count += countNodeFrom( root->right, level – 1); return count; }


Download ppt "תכנות בשפת C תרגול 12 עצים בינאריים 20.05.2011."

Similar presentations


Ads by Google