Professional Documents
Culture Documents
So far we used
Algorithm Complexity
Algorithm Complexity
log2 n
n log2n
n2
2n
Algorithm Complexity
log2 n
n2
n log2n
2n
16
16
24
64
256
16
64
256
65536
32
180
1024 4294967296
Binary Tree
Binary tree
1.
2.
3.
3.
4.
Inserting Items
Anscestor of 3
siblings
5
2
7
3
Descendant of 1
Is at depth 3
leaf
Inserting items
Inserting items
root
1
insert in order 1, 2, 3, 4, 5, 6, 7
VERY unbalanced tree
balanced tree is where the depth of
the leaves differ by at most 1
worst case
behaves as a list
Average path to a node
(1+2+3+4+5+6+7)/7= 3
2
3
4
5
6
7
Inserting items
root
4
2
1
6
3
root
4
2
1
6
3
Need to consider
inserting a node
removing a node
finding a node
traversing a tree (visiting ALL nodes in a tree)
Need to define
class Node
class Tree
int data;
Node *left;
Node *right;
class Tree {
public:
Node *root;
Tree();
};
// initially NULL
// default constructor
void insert(Node*);
Node *find(int);
int remove(Node*);
};
10
Insert Node
void Tree::insert(Node *n)
{
if (root == NULL) {
root = n;
return;
}
..
// empty tree
11
Insert Node
{
Finding nodes
12
// NOT found
// public method
// call helper with root of tree
13
Can add cout <<calling funciton find <<endl; to keep track how many times its
called recursively
root
4
2
1
6
3
14
Finding nodes
// public method
// call helper with root node
// NB. -1
15
root
4
-- left
// public method
// check for root == NULL
// NB. -1
// private helper method
// return NULL
// check n->left
// check n->right
// return greater of lh and lr + 1
// return 0
16
root
4
Tree Traversal
visit ALL nodes in tree and perform some
action on each node (eg. print)
in-order - traverse left subtree then
node then right subtree
1, 2, 4, 6
reverse order traverse the right
subtree then node then left subtree
6, 4, 2, 1
pre-order visit the node then traverse
left subtree then right subtree
4, 2, 1, 6
post-order - traverse left subtree then
right subtree then node
1, 2, 6, 4
root
4
17
Tree Traversal
// public method
// call helper with root node
18
19
Node deletion
root
3 cases to consider
10
2
1
12
7
E.g. delete 8
Simply remove the node
root
10
6
2
1
12
7
20
e.g. delete 7
Delete node
Make parent point to subtree
root
10
6
2
1
12
7
root
64
2
1
12
7
21
Delete implementation
Delete implementation
Node* Tree::remove(int v)
{ Node *pp = NULL, *p = root;
while (p) {
if (v == p->v) {
if (pp == NULL)
removeN(root); // special case if root
else
// pass reference to pointer to be modified
removeN (v < pp->v? pp->left: pp->right);
p->left = p->right = NULL; // set left and right pointers to NULL
return p; // return pointer to removed node
}
pp = p; // remember parent
p = (v < p->v) ? p->left : p->right; // go left or right
}
return NULL; // NOT found
}
22
Delete implementation
void Tree::removeN(Node*&np)
// removeN helper
{
if ((np->left == NULL) && (np->right == NULL)) { // case 1
np = NULL; // update pointer to removed Node
return;
}
if ((np->left == NULL) || (np->right == NULL)) { // case 2
np = (np->left == NULL) ? np->right : np->left;
// update pointer to removed Node
return;
}
Node*p = np->left, *pp = NULL;
// case 3
while (p->right) {
// find largest Node in left sub tree
pp= p;
// pointer to parent
p = p->right; // go right
}
if (pp == NULL)
// by pass largest node
np->left = p->left;
// need to think about this!
else
pp->right = p->left;
// need to think about this!
p->left = np->left;
// node p replaces node np
p->right = np->right; // copy left and right
np = p;
// make switch
}
Delete example
delete node 4
node 3 is the largest node in left sub
tree of node 4
node 4 must be made point to node 2
[np->left = p->left]
need to swap nodes 3 and 4 so that
a pointer to a detached node 4 can be
returned
root
8
np
4
p
3
2
12
6
7
23
Delete example
root
8
[3]
p
3
12
[2]
[1]
6
7
Delete example
24
Destructor
Node::~Node(){
cout << node destructor"<<endl;
if (left != NULL) delete left;
if (right != NULL) delete right;
}
Tree::~Tree()
{
cout << tree destructor" <<endl;
if (root != NULL) delete root;
}
25
root
stack
8
4
->8
->4
12
sp
->3
6
7
26