department of computer engineering faculty of engineering, prince of songkla university 1 8 –...
TRANSCRIPT
1
Department of Computer Engineering Faculty of Engineering, Prince of Songkla University
8 – Trees8 – Trees
22
Overview:
1. Tree Example
2. Binary Trees
3. Binary Trees in C
4. Tree Traversal
5. Binary Search Trees
6. Searching a BST
7. Insertion into a BST
8. Deletion from a BST
33
1. Tree Example
Board of Directors
ResearchDivision
ManufacturingDivision Admin Marketing
ComputerSystems
AccountsPayable Payroll
55
Binary Tree Jargon
a is the root of the tree
b, c are the children of a
left subtree of a: the tree whose root is b
right subtree of a: the tree whose root is c
d, e, h, i, j are descendents of b
every node is a descendent of a (the root)
h, i, j, k, g are the leaves of the tree
77
Some Binary Tree ADT Operations
create an empty tree
build a new tree from a data value and two subtrees
deletion
insertion
check to see if a tree is empty
print out all the elements in a tree
88
3. Binary Trees in C
3.1 Binary Tree Type
3.2 Examples
3.3 Some Functions
3.4 Size of a Binary Tree
3.5 Height of a Binary Tree
99
3.1 Binary Tree Type
struct treenode { struct treenode *leftptr; int data;
struct treenode *rightptr;
};
typedef struct treenode TREENODE; typedef TREENODE *TREE;
treenodedata
rightptrleftptr
1212
3.3 Some Functions
int isEmptyTree ( TREE t ){ if (t == NULL) return 1; /* true */ else return 0; /* false */ }
1313
int value(TREE t){ if (isEmptyTree(t)) { printf(“Tree is empty \n”); return -1; } else return t->data;}
TREE mkEmpty(void)/* return an empty tree */{ return NULL;}
1414
TREE mkTree(int x, TREE leftT,TREE rightT)/* make a new tree from a data value x and two existing trees */{ TREE temp;
temp = malloc(sizeof(TREENODE)); temp->data = x; temp->leftptr = leftT; temp->rightptr = rightT;
return temp;}
1515
TREE lsTree(TREE t){ return t->leftptr; /* don’t bother dealing with the empty tree case */}
TREE rsTree(TREE t){ return t->rightptr; }
1616
3.4 Size of a Binary Tree
an empty tree has 0 size
a non-empty tree has one node plus the number of elements in the subtrees
n
tree2tree1
size(tree) = 1 + size(tree1) +
size(tree2)
1717
C Version
int size(TREE t){ if (isEmptyTree(t)) return 0; else return (1 + size(lsTree(t))
+ size(rsTree(t)) );}
1818
Rephrased
int size(TREE t){ if (t == NULL) return 0; else return (1 + size(t->leftptr)
+ size(t->rightptr)); }
1919
3.5 Height of a Binary Tree
the height of an empty tree is 0
the height of a non-empty tree is 1 plus the height of the highest subtree
n
tree2tree1
heightof tree1 height
of tree2
height(tree) = 1 + max(height(tree1), height(tree2))
2020
C Version
int height(TREE t){ if(isEmptyTree(t)) return 0; else return (1 + max(height(lsTree(t)),
height(rsTree(t))));}
2121
2 general approaches to traversal sequence
depth-first traversal proceeds along a path from the root through
one child to the most distant descendent of that first child before processing a second child
breadth-first traversal proceeds horizontally from the root to all of its
children, then to its children’s children, and so forth until all nodes have been processed
4. Tree Traversal
2323
3 different depth-first traversal sequences
1. Preorder Traversal (N-L-R) look at the root node first, then the left subtre
e, then the right subtree
2. Inorder Traversal (L-N-R) (or mid-order) look at the left subtree first, then the root
node, then the right subtree
3. Postorder Traversal (L-R-N) look at the left subtree first, then the right su
btree, then the root node
4.1 Depth-First Traversals
N
RL
2424
Traversal Nodes Visited preorder. . . . . . 1 2 4 8 5 9 10 3 6 11 7 inorder. . . . . . . 8 4 2 9 5 10 1 6 11 3 7 postorder. . . . . 8 4 9 10 5 2 11 6 7 3 1
1
3
7654
2
111098
Example
2525
Print a Tree using Preorder
void preorder_print(TREE t){ if (!isEmptyTree(t)) { printf(“%3d”, value(t));
preorder_print(lsTree(t)); preorder_print(rsTree(t)); }}
2626
Inorder and Postorder Printing
void inorder_print(TREE t){ if (!isEmptyTree(t)) { inorder_print(lsTree(t)); printf(“%3d”, value(t));
inorder_print(rsTree(t)); }}
2727
void postorder_print(TREE t){ if (!isEmptyTree(t)) { postorder_print(lsTree(t)); postorder_print(rsTree(t)); printf(“%3d”, value(t)); }}
2828
all of the children of a node before proceeding with the next levelthat is, given a root at level n, we process all nodes at level n before processing with the nodes at level n + 1to traverse a tree in depth-first order, we use a stack (Remember: recursion uses stack )to traverse a tree in breadth-first order, we use a queue
4.2 Breadth-first Traversal
3232
5.1 Informal Definition
A Binary Search Tree (BST) is a binary tree, with an ordering on its nodes.
In every subtree (including the whole tree): all values in the left subtree are 'less than' the
value in the root node all values in the right subtree are 'greater than'
the value in the root node
3434
5.3 C BST Type
Change the typedef names to reflect the fact that we are treating the tree as a BST:
typedef struct treenode BSTNODE;typedef BSTNODE *BST;
C’s typing is not powerful en ough to
include the BST ordering information
3636
6.1 Informal Definition
To recursively search for an item (called the key) in a BST:
A key cannot be in an empty tree
For a non-empty tree: if key == root value, stop if key < root value, search left subtree if key > root value, search right subtree
3838
6.3 C Version
int bstsearch(int key, BST t){ int v; if (isEmptyTree(t)) return 0; v = value(t); if (key == v) return 1; if (key < v)
return bstsearch(key, lsTree(t)); if (key > v) return bstsearch(key, rsTree(t));}
3939
7. Insertion into a BST
7.1 Examples
7.2 Informal Insertion Definition
7.3 Tree Creation Functions
7.4 bstinsert()
7.5 More Efficient Insertion
7.6 Comparing bstinsert() and insert_node()
7.7 insert_node2()
4040
7.1 Examples
Insert the following into an empty BST:
4 2 3 6 1 5 7
The resulting tree:
4
6
5 731
2
4242
7.2 Informal Insertion Definition
1. If the tree is empty, the value becomes the root of a new tree.
If the tree is not empty, then:
2. If value < root, it must be inserted into the left subtree.
3. If value > root, it must be inserted into the right subtree.
4. If value == root, then stop.
4343
7.3 Tree Creation Functions
BST mkEmpty(void){ return NULL;}
BST mkTree(int x,BST leftT, BST rightT){ BST t; t = malloc(sizeof(BSTNODE)); t->data = x; t->leftptr = leftT; t->rightptr = rightT; return t;}
4444
7.4 bstinsert()
BST bstinsert(int x, BST t){
int v; BST t1, t2;
if (isEmptyTree(t)) return mkTree(x,mkEmpty(),mkEmpty()); v = value(t); //value of root node t1 = lsTree(t); t2 = rsTree(t);
continued
4545
if (x < v) return mkTree(v,bstinsert(x,t1),t2); else if (x > v) return mkTree(v,t1,bstinsert(x,t2)); else return mkTree(v, t1, t2); /* or return t; */}
• easy to understand
• inefficient due to copying
4646
Use:
BST t, newt;
t = bstinsert(5, bstinsert(7, bstinsert(1, bstinsert(2, bstinsert(4, mkEmpty())))));
newt = bstinsert(9, t);
4747
4
5
7
91
2
t
4
7
newt
bstinsert() has copied all of the n odes in the path from the root dow
n to the parent node of where the number has been inserted.
4848
7.5 More Efficient Insertion
Modify the input tree to include the new value.
no copying
destructive assignment
4949
insert_node()
void insert_node(BST *tp, int value){ /* tp is a pointer to a BST */ if( *tp == NULL) {
*tp = malloc(sizeof(BSTNODE));
(*tp)->data = value;
(*tp)->leftptr = NULL;
(*tp)->rightptr = NULL; } else if (value < (*tp)->data) insert_node(&((*tp)->leftptr),value); else if (value > (*tp)->data) insert_node(&((*tp)->rightptr),value); else printf(“duplicate node\n”);
}
5050
Use:
BST t = NULL;
insert_node(&t, 4); /* address of pointer */
insert_node(&t, 2);
insert_node(&t, 5);
insert_node(&t, 7);
5151
What is &((*tp)->leftptr)?
tp is a pointer to a BST
*tp is a BST
(*tp)->leftptr is the left subtree, another BST
&((*tp)->leftptr) is the address of that BST, which is the type of the first arg of insert_node()
The same reasoning applies to the use of: &((*tp)->rightptr)
5252
7.6 Comparing bstinsert() and insert_node()
bstinsert() easy to understand but inefficient copying
insert_node() efficient but hard to understand call by reference
5353
7.7 insert_node2()
/* call by reference replaced by returns */
BST insert_node2(BST t, int value){ if (t == NULL) { t = malloc(sizeof(BSTNODE)); t->data = value; t->leftptr = NULL; t->rightptr = NULL; }
continued
5454
else if (value < t->data) t->leftptr = insert_node2(t->leftptr, value);
else if (value > t->data) t->rightptr = insert_node2(t->rightptr, value);
else printf("duplicate node\n");
return t;}
5555
Use:
BST t = NULL;
t = insert_node2(t, 4);
t = insert_node2(t, 2);
t = insert_node2(t, 5);
t = insert_node2(t, 7);
5757
8.1 Deletion Cases
There are three cases. The deleted node has:
1) no children
2) one child
3) two children
6060
Case 2 : deleted node has 1 Child
Delete 8 from t:
4
6
5
1
74 6
5
81
2 7
3 • adjust the link to the child of the deleted node
2
3
6161
Case 3: deleted node has 2 Children
n
tree2tree1
rest oftree
delete n
x
x
tree2tree1
rest oftree
3.1) Select the least value in the right subtree to replace x is the next biggest value after n
6363
Case 3: deleted node has 2 Children
n
tree1 tree2
rest oftree
delete n
y
y
tree2tree1
rest oftree
3.2) Select the greatest value in the left subtree to replace y is the biggest value less than n