AB-JAVA2-Chapter25and26.pdf

Chapter 25: Binary Search Trees

Chapter 26: AVL Trees

Dr. Adriana Badulescu

Chapter 25 Objectives▪ To design and implement a binary search tree (§25.2).

▪ To represent binary trees using linked data structures (§25.2.1).

▪ To search an element in binary search tree (§25.2.2).

▪ To insert an element into a binary search tree (§25.2.3).

▪ To traverse elements in a binary tree (§25.2.4).

▪ To delete elements from a binary search tree (§25.3).

▪ To display binary tree graphically (§25.4).

▪ To create iterators for traversing a binary tree (§25.5).

▪ To implement Huffman coding for compressing data using a binary tree (§25.6).

Binary Trees

A list, stack, or queue is a linear structure that consists of a sequence of elements. A binary tree is a hierarchical structure. It is either empty or consists of an element, called the root, and two distinct binary trees, called the left subtree and right subtree.

60

55 100

57 67 107 45

G

F R

M T A

(A) (B)

See How a Binary Search Tree Works

Binary Tree TermsThe root of left (right) subtree of a node is called a left (right) child of the node. A node without children is called a leaf. A special type of binary tree called a binary search tree is often useful. A binary search tree (with no duplicate elements) has the property that for every node in the tree the value of any node in its left subtree is less than the value of the node and the value of any node in its right subtree is greater than the value of the node. The binary trees in Figure 25.1 are all binary search trees. This section is concerned with binary search trees.

Representing Binary TreesA binary tree can be represented using a set of linked nodes. Each node contains a value and two links named left and right that reference the left child and right child, respectively, as shown in Figure 25.2.

Searching an Element in a Binary Search Tree

Inserting an Element to a Binary Search Tree

If a binary tree is empty, create a root node with the new element. Otherwise, locate the parent node for the new element node. If the new element is less than the parent element, the node for the new element becomes the left child of the parent. If the new element is greater than the parent element, the node for the new element becomes the right child of the parent. Here is the algorithm:

Inserting an Element to a Binary Tree

Trace Inserting 101 into the following tree

Trace Inserting 101 into the following tree, cont.

Trace Inserting 101 into the following tree, cont.

Trace Inserting 101 into the following tree, cont.

Trace Inserting 101 into the following tree, cont.

Trace Inserting 101 into the following tree, cont.

Trace Inserting 101 into the following tree, cont.

Trace Inserting 101 into the following tree, cont.

Trace Inserting 101 into the following tree, cont.

Trace Inserting 101 into the following tree, cont.

Trace Inserting 101 into the following tree, cont.

Trace Inserting 101 into the following tree, cont.

Trace Inserting 101 into the following tree, cont.

Trace Inserting 101 into the following tree, cont.

Trace Inserting 101 into the following tree, cont.

Trace Inserting 101 into the following tree, cont.

Trace Inserting 101 into the following tree, cont.

Trace Inserting 101 into the following tree, cont.

Trace Inserting 101 into the following tree, cont.

Trace Inserting 101 into the following tree, cont.

Inserting 59 into the Tree

Tree TraversalTree traversal is the process of visiting each node in the tree exactly once. There are several ways to traverse a tree. This section presents inorder, preorder, postorder, depth-first, and breadth-first traversals.

The inorder traversal is to visit the left subtree of the current node first recursively, then the current node itself, and finally the right subtree of the current node recursively.

The postorder traversal is to visit the left subtree of the current node first, then the right subtree of the current node, and finally the current node itself.

Tree Traversal, cont.

The preorder traversal is to visit the current node first, then

the left subtree of the current node recursively, and finally the right subtree of the current node recursively.

Tree Traversal, cont.

The breadth-first traversal is to visit the nodes level by level. First visit the root, then all children of the root from left to right, then grandchildren of the root from left to right, and so on.

For example, in the tree in Figure 25.2, the inorder is 45 55 57 59 60 67 100 101 107. The postorder is 45 59 57 55 67 101 107 100 60. The preorder is 60 55 45 57 59 100 67 107 101. The breadth-first traversal is 60 55 100 45 57 67 107 59 101.

The Tree Interface

The Tree interface defines common operations for trees.

«interface» Tree<E>

+search(e: E): boolean

+insert(e: E): boolean

+delete(e: E): boolean

+inorder(): void

+preorder(): void

+postorder(): void

+getSize(): int

+isEmpty(): boolean

+clear(): void

Override the add, isEmpty, remove,

containsAll, addAll, removeAll,

retainAll, toArray(), and toArray(T[])

methods defined in Collection using

default methods.

Returns true if the specified element is in the tree.

Returns true if the element is added successfully.

Returns true if the element is removed from the tree

successfully.

Prints the nodes in inorder traversal.

Prints the nodes in preorder traversal.

Prints the nodes in postorder traversal.

Returns the number of elements in the tree.

Returns true if the tree is empty.

Removes all elements from the tree.

«interface»

java.lang.Collection<E>

Tree

The BST Class

Let’s define the binary tree class, named BST with A concrete BST class can be defined to extend AbstractTree.

BST<E extends Comparable<E>>

#root: TreeNode<E>

#size: int

+BST()

+BST(objects: E[])

+path(e: E): java.util.List<TreeNode<E>>

1

m TreeNode<E>

Link

0

The root of the tree.

The number of nodes in the tree.

Creates a default BST.

Creates a BST from an array of elements.

Returns the path of nodes from the root leading to the

node for the specified element. The element may not be

in the tree.

«interface» Tree<E>

BST

Example: Using Binary Trees

Write a program that creates a binary tree using BST. Add strings into the binary tree and traverse the tree in inorder, postorder, and preorder.

TestBST

Tree After Insertions

Deleting Elements in a Binary Search TreeTo delete an element from a binary tree, you need to first locate the node that contains the element and also its parent node. Let current point to the node that contains the element in the binary tree and parent point to the parent of the currentnode. The current node may be a left child or a right child of the parent node. There are two cases to consider:

Deleting Elements in a Binary Search Tree

Case 1: The current node does not have a left child, as shown in this figure (a). Simply connect the parent with the right child of the current node, as shown in this figure (b).

parent

current

No left child

Subtree

parent

Subtree

current may be a left or

right child of parent Subtree may be a left or

right subtree of parent

current points the node

to be deleted

Deleting Elements in a Binary Search TreeFor example, to delete node 10 in Figure 25.9a. Connect the parent of node 10 with the right child of node 10, as shown in Figure 25.9b.

20

10 40

30 80

root

50

16

27

20

40

30 80

root

50

16

27

Deleting Elements in a Binary Search Tree

Case 2: The current node has a left child. Let rightMostpoint to the node that contains the largest element in the left subtree of the current node and parentOfRightMostpoint to the parent node of the rightMost node, as shown in Figure 25.10a. Note that the rightMost node cannot have a right child, but may have a left child. Replace the element value in the current node with the one in the rightMost node, connect the parentOfRightMost node with the left child of the rightMost node, and delete the rightMost node, as shown in Figure 25.10b.

Deleting Elements in a Binary Search TreeCase 2 diagram

parent

current

.

.

.

rightMost

parentOfRightMost

parent

.

.

.

parentOfRightMost

Content copied to

current and the node

deleted

Right subtree Right subtree

current

current may be a left or

right child of parent

current points the node

to be deleted

The content of the current node is

replaced by content by the content of

the right-most node. The right-most

node is deleted.

leftChildOfRightMost leftChildOfRightMost

Deleting Elements in a Binary Search TreeCase 2 example, delete 20

rightMost

20

10 40

30 80

root

50

16

27

16

10 40

30 80

root

50 27 14 14

Examples

Delete this

node George

Adam Michael

Daniel Jones Tom

Peter

Daniel

Adam Michael

Jones Tom

Peter

Examples

Daniel

Adam Michael

Jones Tom

Peter

Delete this

node

Daniel

Michael

Jones Tom

Peter

Examples

Daniel

Michael

Jones Tom

Peter

Delete this

node

Daniel

Jones

Tom

Peter

TestBSTDelete

Binary Tree Time Complexity

It is obvious that the time complexity for the inorder, preorder, and postorder is O(n), since each node is traversed only once. The time complexity for search, insertion and deletion is the height of the tree. In the worst case, the height of the tree is O(n).

Tree Visualization

BTView

Iterators

An iterator is an object that provides a uniform way for traversing the elements in a container such as a set, list, binary tree, etc.

TestBSTWithIterator

Data Compression: Huffman Coding In ASCII, every character is encoded in 8 bits. Huffman coding compresses data by using fewer bits to encode more frequently occurring characters. The codes for characters are constructed based on the occurrence of characters in the text using a binary tree, called the Huffman coding tree.

Mississippi

Constructing Huffman Tree▪ To construct a Huffman coding tree, use a greedy

algorithm as follows:

▪ Begin with a forest of trees. Each tree contains a node for a character. The weight of the node is the frequency of the character in the text.

▪ Repeat this step until there is only one tree:

Choose two trees with the smallest weight and create a new node as their parent. The weight of the new tree is the sum of the weight of the subtrees.

Constructing Huffman Tree

HuffmanCode

Chapter 26 Objectives

▪ To know what an AVL tree is (§26.1).▪ To understand how to rebalance a tree using the LL

rotation, LR rotation, RR rotation, and RL rotation (§26.2).▪ To know how to design the AVLTree class (§26.3).▪ To insert elements into an AVL tree (§26.4).▪ To implement node rebalancing (§26.5).▪ To delete elements from an AVL tree (§26.6).▪ To implement the AVLTree class (§26.7).▪ To test the AVLTree class (§26.8).▪ To analyze the complexity of search, insert, and delete

operations in AVL trees (§26.9).

Why AVL Tree? The search, insertion, and deletion time for a binary

tree is dependent on the height of the tree. In the

worst case, the height is O(n). If a tree is perfectly

balanced, i.e., a complete binary tree, its height is .

Can we maintain a perfectly balanced tree? Yes.

But it will be costly to do so. The compromise is to

maintain a well-balanced tree, i.e., the heights of

two subtrees for every node are about the same.

What is an AVL Tree?

AVL trees are well-balanced. AVL trees were

invented by two Russian computer scientists G. M.

Adelson-Velsky and E. M. Landis in 1962. In an

AVL tree, the difference between the heights of two

subtrees for every node is 0 or 1. It can be shown

that the maximum height of an AVL tree is O(logn).

AVL Tree Animation

Balance Factor/Left-Heavy/Right-HeavyThe process for inserting or deleting an element in an AVL

tree is the same as in a regular binary search tree. The

difference is that you may have to rebalance the tree after

an insertion or deletion operation. The balance factor of a

node is the height of its right subtree minus the height of

its left subtree. A node is said to be balanced if its balance

factor is -1, 0, or 1. A node is said to be left-heavy if its

balance factor is -1. A node is said to be right-heavy if its

balance factor is +1.

Balancing TreesIf a node is not balanced after an insertion or deletion

operation, you need to rebalance it. The process of

rebalancing a node is called a rotation. There are four

possible rotations.

LL imbalance and LL rotation LL Rotation: An LL imbalance occurs at a node A such that A has a

balance factor -2 and a left child B with a balance factor -1 or 0. This

type of imbalance can be fixed by performing a single right rotation

at A.

A -2

B -1 or 0

T2

T3

T1 h+1

h

h

T2’s height is h or

h+1

A 0 or -1

B 0 or 1

T2 T3

T1 h+1

h h

RR imbalance and RR rotation RR Rotation: An RR imbalance occurs at a node A such that A has a

balance factor +2 and a right child B with a balance factor +1 or 0.

This type of imbalance can be fixed by performing a single left

rotation at A.

A +2

B +1 or 0

T2

T3

T1 h+1

h

h

T2’s height is

h or h+1

A 0 or +1

B 0 or -1

T2 T3

T1

h+1

h h

LR imbalance and LR rotation LR Rotation: An LR imbalance occurs at a node A such that A has a

balance factor -2 and a left child B with a balance factor +1. Assume

B’s right child is C. This type of imbalance can be fixed by

performing a double rotation (first a single left rotation at B and then

a single right rotation at A).

A -2

C -1, 0, or 1

T3

T4

T2 h h

h

B +1

T1 h

T2 and T3 may have

different height, but

at least one' must

have height of h.

C 0

A 0 or 1

T3 T4 T2 h h h

B 0 or -1

T1 h

RL imbalance and RL rotation RL Rotation: An RL imbalance occurs at a node A such that A has a

balance factor +2 and a right child B with a balance factor -1.

Assume B’s left child is C. This type of imbalance can be fixed by

performing a double rotation (first a single right rotation at B and

then a single left rotation at A).

A +2

C 0, -1,

or 1

T3

T4

T2 h h

h

B -1

T1 h

T2 and T3 may have

different height, but

at least one' must

have height of h.

C 0

B 0 or 1

T3 T4 T2 h h h

A 0 or -1

T1 h

Designing Classes for AVL Trees▪ An AVL tree is a binary tree. So you can define the

AVLTree class to extend the BST class.

TestAVLTree

AVLTree