Title: Trees
1Trees
2Chained Hash table
- Hash table, where collided records are stored in
linked list - good hash function, appropriate hash size
- Few collisions. Add, delete, search very fast
O(1) - otherwise
- some hash value has a long list of collided
records.. - add - just insert at the head fast O(1)
- delete a target - delete from unsorted linked
list slow - search - sequential search slow O(n)
3Binary tree
A binary tree is either empty, or it consists of
a node called the root together with two binary
trees called the left subtree and the right
subtree of the root.
4Root and subtrees
root
right subtree
left subtree
5Some binary trees
6Some terms
parent
root
left child
right child
leaves
Leaves are nodes that have no children.
7Small binary trees
Empty tree
Tree of size 2
Tree of size 1
8Small binary trees
Tree of size 3
9Traversal
- Three standard traversal order
- preorder - V L R
- inorder - L V R
- postorder - L R V
Inorder traverse all nodes in the LEFT subtree
first, then the node itself, then all nodes in
the RIGHT subtree.
10Traversal
1
preorder 1 2 4 5 3 6 inorder 4 2 5 1 3
6 postorder 4 5 2 6 3 1
2
3
4
5
6
preorder 1 ... inorder 1 ... postorder
1
11Linked implementation
type TreeEntry / type of data to be store
/ TreePointer TreeNode TreeNode
record entry TreeEntry left, right
TreePointer end var root TreePointer
12Linked implementation
13Example
var root, Lchild, Rchild TreePointer begin
new(root) root.entry 1 new(Lchild)
Lchild.entry 2 Lchild.left nil
Lchild.right nil new(Rchild)
Rchild.entry 3 Rchild.left nil
Rchild.right nil root.left Lchild
root.right Rchild end.
14Example
var root TreePointer begin new(root)
root.entry 1 new(root.left)
root.left.entry 2 root.left.left
nil root.left.right nil
new(root.right) with root.right do begin
entry 3 left nil right nil
end end.
root
1
15Create Tree
procedure CreateTree (var root
TreePointer) begin root nil end
root
16Recursive manipulation of tree
Any non-empty tree consists of the root node, its
left subtree and its right subtree. (The subtree
may be empty). Because the subtrees are also
tree, if an operation works for tree, we can also
apply it on the subtrees.
R
L
17Inorder traversal
procedure PrintInorder (root TreePointer) begin
if rootltgtnil then begin PrintInorder(root.l
eft) writeln(root.entry)
PrintInorder(root.right) end end
Preorder and postorder traversal are similar.
(change the order of the three statements in the
IF.
18Tree size
function TreeSize (root TreePointer)
integer begin if rootnil then TreeSize
0 else TreeSize 1
TreeSize(root.left) TreeSize(root.right)
end
19Counting leaves
function NumOfLeaves (var root TreePointer)
integer begin if rootnil then
TreeNumOfLeaves 0 else if (root.leftnil)
and (root.rightnil) then TreeNumOfLeaves
1 else TreeNumOfLeaves
TreeNumOfLeaves(root.left)
TreeNumOfLeaves(root.right) end
20Tree height
function TreeHeight (var root TreePointer)
integer var hl,hr integer begin if rootnil
then TreeHeight 0 else begin hl
TreeHeight(root.left) hr
TreeHeight(root.right) if hlgthr then
TreeHeight hl1 else TreeHeight
hr1 end end
21Binary search tree (BST)
- the key of every node in the left subtree is
smaller than the key of this node - the key of every node in the right subtree is
larger than the key of this node
A binary search tree is a binary tree in which
every node satisfies the following
22Binary search tree
type TreeEntry record key KeyType
end TreePointer TreeNode TreeNode
record entry TreeEntry left, right
TreePointer end var root TreePointer
23Binary search tree
- The left subtree and the right subtree are also
BST - No two nodes in a BST have the same key
- If we traverse a BST inorder, we list the key in
ascending order
24Some examples
8
25Is this a BST?
This is NOT BST!
This is an incorrect check of BST.
Every node satisfies the following - the key of
the left node is smaller than the its own key -
the key of the right node is larger than its own
key
26Search BST
To find a key in a BST, we start at the root.
Compare the target key with the key of the
current node. - target found. Done. - target lt
p.entry.key, go left - target gt p.entry.key, go
right
Note that the principle behind is similar to
binary search...
5
target
27Tree search, recursive
procedure TreeSearch(root TreePointer
target KeyType var position TreePointer) var
hl,hr integer begin if root nil then
position nil else if root.entry.key
target then position root else if target
lt root.entry.key then TreeSearch(root.left,
target, position) else TreeSearch(root.righ
t, target, position) end
28Tree search
procedure TreeSearch(root TreePointer
target KeyType var position TreePointer) var
finished boolean begin position root
repeat if position nil then finished
true else if position.entry.key target
then finished true else begin
finished false if target lt
position.entry.key then position
position.left else position
position.right end until finished end
29Balance tree
1
The efficiency of tree search depends on the
shape of the tree. If the tree is balance,
(minimum height, very bushy), the search is fast
(log(n) steps). If the tree is a long narrow
chain, the search is slow (n steps)
15
2
14
Compare this with sequential and binary search ...
3
log(16)4
4
5
13
30Insert Delete Tree
- First well study simple-minded Insert and Delete
procedure. They may result in highly unbalanced
tree - Then well study a special kind of BST called AVL
tree which maintains near balance in inserting
and deleting.
31Insert Tree
procedure InsertTree (var root TreePointer
newnode TreePointer) begin if root nil then
begin root newnode root.left
nil root.right nil end else if
newnode.entry.key lt root.entry.key then
InsertTree(root.left, newnode) else
InsertTree(root.right, newnode) end
If the tree is empty, make a new single node tree
that contains the new node
Otherwise, add the new node to the left subtree
or right subtree.
32Insert Tree, example
New nodes are always added as leaves.
33Delete Tree
?
Case 1 delete a leaf
34Delete Tree
L
?
L
Case 2 delete a node that has only one subtree.
Attach that subtree to the parent of the node.
If the node is a left child, attach the subtree
to the left side of the parent. Similar for right
child case.
35Delete Tree
R
?
R
L
L
Case 3 delete a node that has nonempty left and
right subtrees.
36Delete Tree
Case 3 (continue) Attach the right subtree to
the parent of the node in place of the deleted
node. Then attach the left subtree to the left
side of the leftmost node in the right subtree.
R
L
37Delete Tree, example
?
?
Case 2 delete a node that has only one subtree.
38Delete Tree, example
10
10
?
5
12
12
4
8
16
16
6
9
2
14
14
3
7
1
15
15
Case 3 delete a node that has nonempty left and
right subtrees.
39Delete Tree
procedure DeleteNodeTree (var position
TreePointer) begin if position nil then
Error( ) else if position.right nil then
begin reattach the left subtree in place of
position temp position position
position.left dispose(temp) end else if
position.left nil then begin reattach
the right subtree in place of position
temp position position
position.right dispose(temp) end else ...
This is the pointer in the tree that points to
the node to be deleted.
Case 1 and 2
This mainly handles case 2 (either left subtree
or right subtree is nonempty), but it also
handles case 1 (leaf) nicely.
40Delete Tree
procedure DeleteNodeTree (var position
TreePointer) var temp TreePointer begin
else begin neither subtree is empty.
move right, then as far left as possible.
temp position.right while temp.left ltgt
nil do temp temp.left temp.left
position.left temp position
position position.right dispose(temp)
end end
Case 3 nonempty left and right subtree
After this while loop, temp points to the
leftmost node in the right subtree. That is the
smallest node in the right subtree.
Then we attach the left subtree to the left of
this node.
Finally, we replace the deleted node with the
right subtree.
41Delete a node with target key
procedure DeleteKeyTree (target KeyType var
keyPos, root TreePointer) begin if root nil
then Error('Attempt to delete a key not
present in the binary search tree')
else if root.entry.key target then begin
keyPos root DeleteNodeTree(root) end
else if targetltroot.entry.key then
DeleteKeyTree(target, keyPos, root.left) else
DeleteKeyTree(target, keyPos,
root.right) end
42Binary search tree
- Binary search tree, using simple insert and
delete procedures - the tree is nearly balance
- add - fast O(log n)
- delete a target - fast O(log n)
- search - fast O(log n)
- the tree is highly unbalance, it becomes a singly
linked list - add, delete and search - slow O(n) effectively
using sequential search to find a location