Binary trees - The Department of Computer Science

Binary trees
1
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
Tree Structure
2
 Tree structure is a way of representing the
hierarchical nature of a structure in a graphical form.
 Mathematically, a tree is an acyclic connected graph
where each node has zero or more children nodes
and at most one parent node. Furthermore, the
children of each node have a specific order.
 In computer science, a tree is a widely-used data
structure that emulates a hierarchical tree structure
with a set of linked nodes.
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
Binary trees : definitions
3
 Binary tree is a tree data structure in which each
node has at most two child nodes, usually
distinguished as "left" and "right".
 nodes with children are parent nodes, and child
nodes may contain references to their parents.
 A node that has a child is called the child's parent
node (or ancestor node, or superior). A node has at
most one parent.
 nodes that do not have any children are called leaf
nodes.
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
Binary trees : definitions (cont.)
4
 The height of a node is the length of the longest




downward path to a leaf from that node.
The height of the root is the height of the tree.
The depth of a node is the length of the path to its
root (i.e., its root path).
An internal node or inner node is any node of a
tree that has child nodes and is thus not a leaf node.
A subtree of a tree T is a tree consisting of a node in
T and all of its descendants in T.
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
Common operations
5
 Enumerating all the items
 Enumerating a section of a tree
 Searching for an item
 Adding a new item at a certain position on the tree
 Deleting an item
 Removing a whole section of a tree (called pruning)
 Adding a whole section to a tree (called grafting)
 Finding the root for any node
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
node – Definition and making
6
 typedef struct node_t {
int data;
struct node_t *right, *left;
}node;
 node *make_node(int y) {
node *newnode;
newnode=(node *)malloc(sizeof(node));
newnode->data=y;
newnode->right=newnode->left=NULL;
return(newnode);
}
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
Sorting tree
7
 In computer science, a binary search tree (BST)
or ordered binary tree is a node-based binary tree
data structure which has the following properties:
 The left subtree of a node contains only nodes with
keys less than the node's key.
 The right subtree of a node contains only nodes with
keys greater than the node's key.
 Both the left and right subtrees must also be binary
search trees.
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
Examples
8
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
Making Sorting Tree
9
void main(){
node *root = NULL;
int data;
do {
printf("\n Enter number:");
scanf("%d",& data);
if(data==-1)
break;
root = build_tree(root, data);
} while(1);
}
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
Adding node to sorting tree
10
node * build_tree( node * root, int data){
if (root == NULL)
root = newnode(data);
else if (data <= root->data)
root->left = build_tree(root->left, data);
else
root->right = build_tree(root->right, data);
return root;
}
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
Binary Tree Traversal - Inorder
11
void inorder(node *r){
if(r!=NULL){
inorder(r->left);
printf("\t %d",r->data);
inorder(r->right);
}
}
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
Binary Tree Traversal - Preorder
12
 void preorder( node *r) {
if(r!=NULL) {
printf("\t %d",r->data);
preorder(r->left);
preorder(r->right);
}
}
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
Binary Tree Traversal - Postorder
13
void postorder( node *r) {
if(r!=NULL) {
postorder(r->left);
postorder(r->right);
printf("\t %d",r->data);
}
}
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
Functions on Trees
14
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
Print leaves
15
void printLeaves (node * root) {
if (root == NULL)
return;
if (root->left == NULL && root->right == NULL)
printf("(%2d)", root->data);
else {
printLeaves(root->left);
printLeaves(root->right);
}
{
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
Size of tree
16
int size(node * root) {
if (root == NULL)
return 0;
return 1 + size(root->left) + size(root->right);
{
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
Height of tree
17
int height(node * root) {
int l_h, r_h;
if (root == NULL)
return -1;
l_h = height(root->left);
r_h = height(root->right);
return 1 + (l_h > r_h) ? l_h : r_h;
}
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
Searching data in tree
18
int search(node * root, int data) {
if (root == NULL)
return 0;
if (root->data == data)
return 1;
return search(root->left, data)
|| search(root->right, data);
}
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
Searching in tree
19
int search(node * root, int data) {
if (root == NULL)
return 0;
if (root->data == data)
return 1;
if (data < root->data)
return search(root->left, data);
else
return search(root->right, data);
}
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
Freeing tree
20
// frees all the allocated memory and sets the root to
NULL
void empty_tree(node **root) {
if (!(*root))
return;
empty_tree(&((*root)->left));
empty_tree(&((*root)->right));
free(*root);
*root = NULL;
}
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
‫נתונה ההגדרה הבאה של צומת בעץ בינארי‪:‬‬
‫|‬
‫‪5‬‬
‫‪| 2‬‬
‫‪5‬‬
‫|‬
‫‪5‬‬
‫‪| 2‬‬
‫‪5‬‬
‫|‬
‫‪5‬‬
‫‪2‬‬
‫;‪typedef struct tree tree‬‬
‫{ ‪struct tree‬‬
‫;‪int value‬‬
‫;‪int count‬‬
‫;‪tree * left, * right‬‬
‫;}‬
‫•כתוב פונקציה רקורסיבית )‪ int fillNode(tree * node , int number‬שמקבלת‬
‫‪ tree‬שורש של עץ בינארי כלשהו ו‪ number -‬מספר שלם‪ .‬הפונקציה סופרת ומחזירה כמה‬
‫פעמים ‪ number‬מופיע בשדות ‪ value‬של צמתי העץ‪ .‬תוך כדי ספירה הפונקציה מכניסה‬
‫בשדות ‪ count‬של כל הצמתים שהשדה ‪value‬שלהם שווה ל‪number -‬מספר המופעים‬
‫של ‪ number‬מאותו צומת ותחתיו‪.‬‬
‫הערך ההתחלתי של השדות ‪ count‬בכל העץ הוא אפס‪.‬‬
‫•כתוב פונקציה רקורסיבית )‪ void fillTree(tree * root‬שמקבלת עץ בינארי כלשהו‬
‫ובעזרת הפונקציה ‪fillNode‬מעדכנת את השדה ‪count‬בכל הצמתים בעץ לפי מספר‬
‫המופעים של הערך שבשדה ‪value‬מאותו צומת ותחתיו (ראה דוגמה של עץ מעודכן)‪.‬‬
‫שבת ‪ 29‬יולי ‪2017‬‬
‫‪| 2‬‬
‫‪5‬‬
‫‪21‬‬
‫‪Department of Computer Science-BGU‬‬
‫‪2‬‬
‫‪2‬‬
Example
22
tree
3count= |5
value=
3 | 2
1 | 2
3 | 3
1 | 3
2 | 3
1 | 5
Department of Computer Science-BGU
1 | 2
1 | 3
1 | 5
2017 ‫ יולי‬29 ‫שבת‬
Solution
23
int fillNode(tree *node,int value){
int temp;
if(!node) return 0;
temp=fillNode(node->lc, value) + fillNode(node->rc,
value);
if(node->value==value)
node->count = ++temp;
return temp;
}
void fillTree(node *root){
if(!root) return;
if(!root->count)
fillNode(root, root->value);
fillTree(root->lc);
fillTree(root->rc);
}
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
‫;‪typedef struct node Node‬‬
‫{ ‪struct node‬‬
‫;‪int data‬‬
‫;‪int min‬‬
‫;‪int max‬‬
‫;‪struct node *left‬‬
‫;‪struct node *right‬‬
‫;}‬
‫‪‬‬
‫כתוב פונקציה )‪ updateMinMax(Node root‬שמקבל שורש של‬
‫עץ חיפוש בינארי ממוין לפי השדה ‪ data‬ומעדכנת בכל האיברים של העץ את‬
‫השדות ‪ min‬ו‪ min .max -‬הוא הערך המינימלי מאותו איבר ומטה‪ max ,‬הוא‬
‫הערך המקסימלי מאותו איבר ומטה‪.‬‬
‫‪ ‬כתוב פונקציה )‪search(int key, Node root‬שמחפשת בעץ חיפוש‬
‫בינארי ששורשו ‪ root‬את המבנה שמכיל בשדה ‪ data‬את ערך ‪ key‬אם מבנה‬
‫כזה קיים הפונקציה מחזירה את הכתובת שלו אחרת ‪.NULL‬‬
‫יש לנצל את השדות המעודכנים ‪ min‬ו‪ max -‬על מנת לקצר את החיפוש‪.‬‬
‫שבת ‪ 29‬יולי ‪2017‬‬
‫‪24‬‬
‫‪Department of Computer Science-BGU‬‬
Solution
25
void updateMinMax(Node root){
if(!root)return;
if(!root->left)
root->min = root->data;
else{
updateMinMax(root->left);
root->min = root->left->min;
}
if(!root->right)
root->max = root->data;
else{
updateMinMax(root->right);
root->max = root->right->max;
}
}
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
Solution
26
Node search(int key, Node root){
while(root){
if(key > root->max || key < root->min) return NULL;
if(key > root->data)
root = root->right;
else
if(key < root->data)
root = root->left;
else
return root;
}
return NULL;
}
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
27
typedef struct node TreeNode ;
struct node{
int value;
tNode *left, *right;
};
int inOrderNum(TreeNode* tree, int num) ‫כתוב פונקציה רקורסיבית‬
‫ הפונקציה תדפיס את‬,num ‫ מצביע לעץ חיפוש בינארי ומספר שלם וחיובי‬tree ‫שמקבלת‬
,‫ דוגמא‬.‫ האיברים הקטנים בעץ‬num
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
‫‪28‬‬
‫עבור העץ ‪ tree‬הבא‪:‬‬
‫לאחר הקריאה )‪ inOrderNum(tree, 4‬יודפס‪:‬‬
‫‪1‬‬
‫‪2‬‬
‫‪5‬‬
‫‪8‬‬
‫שימו לב‪:‬‬
‫במידה שמספר הצמתים בעץ קטן מ‪ num-‬יודפסו כל הערכים שבעץ והפונקציה מחזירה‬
‫את מספר הצמתים שבעץ אחרת הפונקציה מחזירה ‪.num‬‬
‫אין להשתמש בפונקצית עזר‪.‬‬
‫שבת ‪ 29‬יולי ‪2017‬‬
‫‪Department of Computer Science-BGU‬‬
Solution
29
int inOrderNum(TreeNode* tree, int num) {
int numPrinted;
if (tree==NULL)
return 0;
numPrinted = inOrderNum(tree->left, num);
if (numPrinted < num){
printf("%d\n",tree->value);
numPrinted++;
if (numPrinted < num){
numPrinted+=inOrderNum(tree->right, num - numPrinted);
{
{
return numPrinted;
{
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
‫‪30‬‬
‫‪ ‬עץ בינארי יקרא עץ זיגזג אם לכל בן שמאלי יש לכל היותר בן אחד‬
‫והוא בן‪-‬ימני ולכל בן ימני יש לכל‬
‫‪ ‬היותר בן אחד והוא בן שמאלי‪ ,‬לשורש העץ יש לכל היותר בן אחד‪.‬‬
‫‪ ‬דוגמא של עץ זיגזג בגובה ‪:3‬‬
‫‪ ‬עץ ריק‪ ,‬עץ של צומת אחד ועץ של ‪ 2‬צמתים מוגדרים כעצי זיגזג‪.‬‬
‫שבת ‪ 29‬יולי ‪2017‬‬
‫‪Department of Computer Science-BGU‬‬
‫‪31‬‬
‫; ‪typedef struct node TreeNode‬‬
‫{‪struct node‬‬
‫;‪int value‬‬
‫;‪tNode *left, *right‬‬
‫;}‬
‫כתבו פונקציה רקורסיבית *‪int isZigzagTree(TreeNode‬‬
‫)‪tree‬שמקבלת ‪ tree‬מצביע לעץ בינארי ומחזירה ‪ 1‬אם העץ הוא‬
‫עץ זיגזג אחרת מחזירה ‪ .0‬הפונקציה סורקת את העץ פעם אחת בלבד‬
‫ואינה משתמשת באף פונקצית עזר‪ .‬ניתן להניח שהפונקציה מקבלת‬
‫כתובת חוקית של עץ‪.‬‬
‫שבת ‪ 29‬יולי ‪2017‬‬
‫‪Department of Computer Science-BGU‬‬
32
int isZigzagTree(TreeNode* tree){
if (!tree)
return 1;
if (!tree->left && !tree->right)
return 1;
if (tree->left && !tree->left->left)
return isZigzagTree(tree->left);
if (tree->right && !tree->right->right)
return isZigzagTree(tree->right);
return 0;
}
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬
‫‪33‬‬
‫כתבו פונקציה רקורסיבית *‪TreeNode‬‬
‫)‪ createZigzagTree(int height, int type‬המקבלת‬
‫כפרמטר ‪height‬גובה העץ ו‪type -‬ערך שלם שמותר להשתמש‬
‫כרצונכם‪ ,‬הפונקציה מחזירה עץ זיגזג‪.‬‬
‫הפונקציה מופעלת עם ‪height‬חיובי ו‪ type-‬שווה אפס‪.‬‬
‫שבת ‪ 29‬יולי ‪2017‬‬
‫‪Department of Computer Science-BGU‬‬
34
TreeNode* createZigzagTree(int height, int type) {
TreeNode *root;
if (!height)
return NULL;
root = (TreeNode*)malloc(sizeof(TreeNode));
root->left = root->right = NULL;
if (type)
root->left = createZigzagTree(height - 1, !type);
else
root->right = createZigzagTree(height - 1, !type);
return root;
}
Department of Computer Science-BGU
2017 ‫ יולי‬29 ‫שבת‬