Week 6-2
Week 6-2
(part 2)
Chapter 4 textbook
Prepared by LC Kwek
Edited by NHAA
Objectives
2/30
Introduction
3/30
Array with Index Referencing
Method
• An array of records is used, with each record contains the
information for one node i Data Left right
• data
• index of left child 0 - 1 2
• index of right child 1 + 3 4
• Example: Given the tree below 2 8 -1 -1
- 3 * 5 6
4 / 7 8
+ 8
5 5 -1 -1
6 3 -1 -1
* /
7 7 -1 -1
5 3 7 2 8 2 -1 -1
*denotes absence of a
4/30
child
Define a Node for a Binary Tree
5/30
Declare & Initialize the Tree
• Whole tree is one array, with each element tree
occupies 3 memory blocks '-'
• Can be declared and initialized all at once in 1
one line 2
'+'
3
4
'8'
-1
-1
'*'
5
6
'/'
7
8
6/30
How is the Traversal Done?
• Example: Function preorder called with
node = 0 (i.e., the root) i Data Left right
• visit tree[0].data: ‘-’ 0 - 1 2
• Recurs 0’s left child, node = 1, visit ‘+’ 1 + 3 4
• Recurs 1’s left child, node = 3, visit ‘*’
• Recurs 3’s left child, node = 5, visit ‘5’
2 8 -1 -1
• Recurs 5’s left child, node = -1, return 3 * 5 6
• Recurs 5’s right child, node = -1, return
4 / 7 8
• Continue with 3’s right child, etc.
5 5 -1 -1
6 3 -1 -1
7 7 -1 -1
8 2 -1 -1
7/30
Implementing a Binary Tree using
Array Index Referencing Method (1/4)
8/30
Implementing a Binary Tree using
Array Index Referencing Method (2/4)
1 /* Implementing a binary tree with array */
2 #include <stdio.h>
3 #define MAXNODES 9 Maximum number of nodes in tree specified
4 (major limitation of array based approach)
5 struct Node {
6 char data; Definition of a node of the tree;
7 int left; integer variables replace the
8 int right; pointers of LL implementation
9 };
10 struct Node tree[MAXNODES] = {
11 {'-', 1, 2},
12 {'+', 3, 4},
13 {'8',-1,-1},
14 {'*', 5, 6},
15 {'/', 7, 8}, Array of nodes declared as
16 {'5',-1,-1}, a global variable
17 {'3',-1,-1},
18 {'7',-1,-1},
19 {'2',-1,-1}
20 };
9/30
Implementing a Binary Tree using
Array Index Referencing Method (3/4)
21 void visit(char data);
22 void preorder(int node); int of an array index rather
23 void postorder(int node); than pointer is passed
24 void inorder(int node);
25 Same as in LL, except that
26 int main(void){ index of root is passed
27 printf("\nPreorder traversal:\t"); preorder(0);
28 printf("\nInorder traversal:\t"); inorder(0);
29 printf("\nPostorder traversal:\t"); postorder(0);
30 return(0);
31 }
32
33 void visit(char data){ printf("%c ", data); }
34
35 void preorder(int node){ Checks if node exists
36 if (node!=-1){
37 visit(tree[node].data); Access data stored in node
38 preorder(tree[node].left);
39 preorder(tree[node].right);
40 } Index of right child
41 } Access current node 10/30
Implementing a Binary Tree using
Array Index Referencing Method (4/4)
42 void postorder(int node){
43 if (node!=-1){
44 postorder(tree[node].left);
45 postorder(tree[node].right);
46 visit(tree[node].data);
47 }
48 }
49 void inorder(int node){
50 if (node!=-1){
51 inorder(tree[node].left);
52 visit(tree[node].data);
53 inorder(tree[node].right);
54 }
55 }
Preorder traversal: - + * 5 3 / 7 2 8
Inorder traversal: 5 * 3 + 7 / 2 - 8
Postorder traversal: 5 3 * 7 2 / + 8 - Same as in LL
11/30
Strengths and Weaknesses
• Strengths
• Easier to initialize tree
• Shorter code
• Weakness
• Limited size – if the size of the data set changes, might need to use a
dynamic array, and use standard function realloc when run out of space
12/30
Why Use this Implementation?
13/30
Summarizing
Binary Trees with Array Index
Referencing
• A binary tree can be implemented using an array of records as a data
structure
• Each record (or node) contains
• the data
• the array index of the left child
• the array index of the right child
• It is useful for immutable data (not changing)
14/30
Binary Tree with Array Index
Calculation (1/4)
• Differences with the previous methods
• Pointers/indices not stored - instead, calculated
• Initialization laid out in nice tree fashion
• A better option if the tree is full
• If tree not full, space wasted (6 nodes, aside from root, wasted in the following
example)
15/30
Binary Tree with Array Index
Calculation (2/4)
• The key of this method
• Index of left child = index of parent * 2
• Index of right child = index of parent * 2 + 1
• A blank node in position 0 of the array (as 0 * 2 = 0)
• Specify an empty node by storing some special value which will never occur
(e.g. null character (‘\0’) since this won’t occur in the data)
16/30
Binary Tree with Array Index
Calculation (3/4) i Value
0 ‘\0’
• Example: Given the tree below 1 -
- 2 +
3 8
+ 8 4 *
5 /
6 ‘\0’
* /
7 ‘\0’
8 5
5 3 7 2
9 3
• Suppose we are at node 5 (‘/’) 10 7
• Left child = 5 * 2 = 10 (‘7’)
• Right child = 5 * 2 + 1 = 11 (‘2’)
11 2
• Parent = 5 / 2 = 2 (‘+’) 12 ‘\0’
13 ‘\0’
14 ‘\0’
17/30
15 ‘\0’
Binary Tree with Array Index
Calculation (4/4)
• How do we check if a tested node is valid?
• Returns “false” if the index is out of bound of the array or if the data is 0
18/30
Implementing a Binary Tree using
Array Index Calculation Method (1/5)
19/30
Implementing a Binary Tree using
Array Index Calculation Method (2/5)
1 /* Implementing a binary tree with array index cal. */
2 #include <stdio.h>
3 #define MDEPTH 4 Depth of tree rather than number of nodes specified
4
5 char tree[MDEPTH*MDEPTH] = {
6 0,
7 '-',
8 '+', '8',
9 '*', '/', 0, 0,
10 '5','3', '7','2', 0, 0, 0, 0
11 };
12
13 void visit(char data);
14 int valid(int node);
15 int leftChild(int node);
16 int rightChild(int node); Array index passed
17 void preorder(int node);
18 void postorder(int node);
19 void inorder(int node);
20
20/30
Implementing a Binary Tree using
Array Index Calculation Method (3/5)
21 int main(void){
22 printf("\nPreorder traversal:\t"); preorder(1);
23 printf("\nInorder traversal:\t"); inorder(1);
24 printf("\nPostorder traversal:\t"); postorder(1);
25 return(0);
26 } Index of root passed; In this implementation, the root is at 1
27
28 void visit(char data){ printf("%c ", data); }
29
30 int valid(int node){ /* if there's something there */
31
32 return((node < MDEPTH*MDEPTH) && tree[node]);
33 }
34
35 int leftChild(int node) { find left child at node * 2
36 return(node * 2);
37 }
38
39 int rightChild(int node) { find right child at node * 2 + 1
40 return((node * 2) + 1);
} 21/30
Implementing a Binary Tree using
Array Index Calculation Method (4/5)
41 void preorder(int node){
42 if (valid(node)){ Checks for valid node
43 visit(tree[node]);
44 preorder(node*2);
45 preorder(node*2+1);
46 }
47 }
48 void postorder(int node){
49 if (valid(node)){
50 postorder(leftChild(node));
51 postorder(rightChild(node));
52 visit(tree[node]);
53 }
54 }
55 void inorder(int node){
56 if (valid(node)){
57 inorder(leftChild(node));
58 visit(tree[node]);
59 inorder(rightChild(node));
60 }
61 } 22/30
Implementing a Binary Tree using
Array Index Calculation Method (5/5)
Preorder traversal: - + * 5 3 / 7 2 8
Inorder traversal: 5 * 3 + 7 / 2 - 8
Postorder traversal: 5 3 * 7 2 / + 8 -
23/30
Why Would We Use this Method?
24/30
Aside: How SHIFTLEFT Works (1/3)
25/30
Aside: How SHIFTRIGHT Works
(2/3)
26/30
Aside: How SHIFTRIGHT Works
(3/3)
27/30
Summarizing Binary Trees with Index
Calculation
28/30
Choosing a Tree Implementation
If you want ... And you do not mind ... You should use ...
full flexibility in the tree using more memory and Linked list implementation
structure and in insertion & things taking a bit longer
deletion
to use a language without having the tree size limited Array by index referencing
pointers, or if the tree is static by the array size
and sparse, and ease in
initialization
speed in accessing the nodes, having the tree size limited Array by index calculation
and ease in initialization by the array size, and having
a static structure, and
wasting space if the tree is
sparse
29/30
Summary
30/30