0% found this document useful (0 votes)
16 views

L12 Binary Trees

Uploaded by

Jessica Milner
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views

L12 Binary Trees

Uploaded by

Jessica Milner
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 39

Binary Trees

The Long Awaited Sequel


Tree
A data structure which consists of

• a finite set of elements called nodes or vertices.

• a finite set of directed arcs which connect the nodes.

If the tree is nonempty --

• One of the nodes (the root) has no incoming arc.

• Every other node can be reached by following a unique


sequence of consecutive arcs starting at the root.

2
Tree Terminology

3
Binary Tree
A binary tree is a tree with the following
properties:

1. Each branch has at most two children (exactly


two for proper binary trees)

2. The children of a node are an ordered pair

1. We call the children of an internal node


left child and right child

Examples
● Results of multiple coin tosses
● Encoding/decoding messages in dots and dashes
such as Morse code
Binary Tree
Alternative recursive definition: a binary
tree is either

● a tree of a single node


● a tree whose root has an ordered
pair of children, each of which is a
binary tree

Applications:

● Arithmetic expressions
● Decision processes
● Searching
Binary Tree Example
Binary tree associated with an
arithmetic expression

Branches: Operators

Leafs: Operands

Arithmetic expression tree for


the expression:

(2 × (a − 1) + (3 × b))
Binary Tree Example
Binary tree associated with a
decision process

Interior nodes: Questions with


yes/no answer

Branches: Decisions

Leafs: output values

Example: Dining Decision


Binary Tree Terms

a a

b c b c

d e f g d f g

j k l m i l n o

A full or proper binary tree is a tree in which This is an improper binary tree.
every node has either 0 or 2 children.
Binary Tree Terms

a a

b c b c

d e f g d e f g

h i j k l m n o h i l m n o

A perfect binary tree is a tree in which all This is a imperfect tree.


branches have two children and all leaves have
the same depth or same level.
Binary Tree Terms

a a

b c b c

d e f g d e f

h i j k l h i j k l

A complete binary tree is when every level, This is an incomplete binary tree.
except possibly the last, is completely filled, and
all nodes in the last level are as far left as
possible.
Binary Tree Terms

a a

b c b c

d e f g d

h m n o h

A binary tree is balanced if the left and right This binary tree is unbalanced.
subtrees' heights differ by at most one. So the
left subtree must be balanced and the right
subtree must be balanced.
Properties of Binary Trees
● Let T be a nonempty binary tree, then T has the following properties:

1. ℎ + 1 ≤ 𝑛 ≤ 2ℎ+1 − 1

2. 1 ≤ 𝑒 ≤ 2ℎ

3. ℎ ≤ 𝑖 ≤ 2ℎ − 1

4. log(𝑛 + 1) − 1 ≤ ℎ ≤ 𝑛 − 1,
where h - the height of T, n - the number of nodes in T, 𝑒 - the number of
external nodes in T, and 𝑖 - the number of internal node in T
Properties of Full/Proper Binary Trees
Notation:
h ≥ log2(e)
n - number of nodes e=i+1
e - number of leaf / h ≥ log2(n + 1)
n = 2e -
external nodes -1
1
i - number of branch h≤i
/ internal nodes e ≤ 2h
h - height
h ≤ (n - 1) / 2

In a nonempty proper binary tree T, the number of external nodes is one more than the number of internal
nodes.
Implementation
● A binary tree ADT can be implemented either as a
linked structure or as an array.

14
BinaryTree ADT
The BinaryTree ADT extends the Tree ADT, i.e., it inherits all the methods of the
Tree ADT

Additional methods:

● position p.left()
● position p.right()

Update methods may be defined by data structures implementing the BinaryTree


ADT

Proper binary tree: Each node has either 0 or 2 children


//
//
//
//
//
//
//

Node
//

// a node of the tree


struct Node {
Elem elt; // element value
Binary Tree Node* par; // parent
Node* left; // left child
Node* right; // right child

// constructor
Node() : elt(), par(NULL), left(NULL), right(NULL) { }
};
// position in the tree
class Position {
private:
Node* v; // pointer to the node
public:
Position(Node* _v = NULL) : v(_v) { } // constructor
Elem& operator*() { return v->elt; } // get element

// get left, right, parent child

Position
Position left() const { return Position(v->left); }
Position right() const { return Position(v->right); }
Position parent() const { return Position(v->par); }

// is root or external/leaf?
Binary Tree bool isRoot() const { return v->par == NULL; }
bool isExternal() const {
return v->left == NULL && v->right == NULL;
}

friend class LinkedBinaryTree; // give tree access


};

typedef std::list<Position> PositionList; // list of positions


Linked Data Structure for a Binary Tree
Linked Implementation of Binary Trees
● Uses space more efficiently

○ for incomplete trees

● Provides additional flexibility

● Each node has two links

○ One to the left child of the node

○ One to the right child of the node

○ If no child node exists for a node, the link is set to NULL


19
typedef int Elem; // base element type
class LinkedBinaryTree {
protected: // insert Node declaration here...
public: // insert Position declaration here...
public:
LinkedBinaryTree(); // constructor
int size() const; // number of nodes
bool empty() const; // is tree empty?

Interface
Position root() const; // get the root
void addRoot(); // add root to empty tree
PositionList positions() const; // list of nodes
// expand external node
void expandExternal(const Position& p);
Binary Tree // remove p and parent
Position removeAboveExternal(const Position& p);
// housekeeping functions omitted...
protected: // local utilities
void preorder(Node* v, PositionList& pl) const;
private:
Node* _root; // pointer to the root
int n; // number of nodes
};
// constructor
LinkedBinaryTree::LinkedBinaryTree() : _root(NULL), n(0) { }

// number of nodes
int LinkedBinaryTree::size() const {

Simple
return n;
}

Functions
// is tree empty?
bool LinkedBinaryTree::empty() const {
return size() == 0;
}

Binary Tree // get the root


LinkedBinaryTree::Position LinkedBinaryTree::root() const {
return Position(_root);
}

// add root to empty tree


void LinkedBinaryTree::addRoot() {
_root = new Node; n = 1;
}
// list of all nodes
LinkedBinaryTree::PositionList LinkedBinaryTree::positions()
const {
PositionList pl;
preorder(_root, pl); // preorder traversal
return PositionList(pl); // return resulting list
}

Traversal // preorder traversal


void LinkedBinaryTree::preorder(Node* v, PositionList& pl) const
{

Binary Tree pl.push_back(Position(v)); // add this node


if (v->left != NULL) { // traverse left subtree
preorder(v->left, pl);
}
if (v->right != NULL) { // traverse right subtree
preorder(v->right, pl);
}
}
// expand external node
void LinkedBinaryTree::expandExternal(const Position& p) {
Node* v = p.v; // p's node

Expand
v->left = new Node; // add a new left child
v->left->par = v; // v is its parent

v->right = new Node; // and a new right child

Binary Tree v->right->par = v; // v is its parent

n += 2; // two more nodes


}
Binary Tree Remove Node and Parent
// remove p and parent
LinkedBinaryTree::Position
LinkedBinaryTree::removeAboveExternal(const Position& p) {
// get p's node and parent
Node* w = p.v; Node* v = w->par;
Node* sib = (w == v->left ? v->right : v->left);

// child of root?
if (v == _root) {

Removal
_root = sib; // ...make sibling root
sib->par = NULL;
} else {
Node* gpar = v->par; // w's grandparent
if (v == gpar->left) {
Binary Tree gpar->left = sib; // replace parent by sib
} else {
gpar->right = sib;
}
sib->par = gpar;
}
delete w; delete v; // delete removed nodes
n -= 2; // two fewer nodes
return Position(sib);
}
Inorder Traversal
In an inorder traversal a node is
visited after its left subtree and before
its right subtree

Application: draw a binary tree

Algorithm inOrder(v) {
if v.isInternal() {
inOrder(v.left())
}
visit(v)
if v.isInternal() {
inOrder(v.right())
}
}
Methods of Traversal
Preorder Inorder Postorder
1 5 7

2 6 2 7 4 6

3 4 7 1 4 6 1 3 5

5 3 2

Algorithm preOrder(v) { Algorithm inOrder(v) { Algorithm postOrder(v) {


visit(v) if v.isInternal() { if v.isInternal() {
if v.isInternal() { inOrder(v.left()) postOrder(v.left())
preOrder(v.left()) } }
} visit(v) if v.isInternal() {
if v.isInternal() { if v.isInternal() { postOrder(v.right())
preOrder(v.right()) inOrder(v.right()) }
} } visit(v)
} } }
Methods of Traversal
Preorder Inorder Postorder
1 5 7

2 6 2 7 4 6

3 4 7 1 4 6 1 3 5

5 3 2

Algorithm preOrder(v) { Algorithm inOrder(v) { Algorithm postOrder(v) {


visit(v) if v.isInternal() { if v.isInternal() {
if v.isInternal() { inOrder(v.left()) postOrder(v.left())
preOrder(v.left()) } }
} visit(v) if v.isInternal() {
if v.isInternal() { if v.isInternal() { postOrder(v.right())
preOrder(v.right()) inOrder(v.right()) }
} } visit(v)
} } }
Binary trees
● Running time of an n-node binary tree implemented with a linked structure

Operation Time
left, right, parent, isExternal, is root O(1)
size, empty O(1)
root O(1)
expendExternal, removeAboveExternal O(1)
positions O(n)
Array-Based Representation of Binary Trees
Binary trees can also be stored in breadth-first (as opposed to depth-first) order in
arrays

If the tree is a complete binary tree, this method wastes no space

The root of the tree is held at A[0]

The left child of a node is held at 2i + 1, the right child is held at 2i + 2, where i
is the parents index

A parent is held at ⌊(i - 1) / 2⌋ when the root node is at A[0]


Array Binary Trees
0

Arrays benefits from more


compact storage and better 1 2

locality of reference
3 4 5 6
It is expensive to grow and
wastes space proportional to
2h for a tree of depth h with
n nodes. In the worst case,
this can be high as 2𝑛 − 1
Array Implementation of Binary Trees
0

1 2

M T

3 4 5 6

E P U
C

● Store node n in location n of the array.


32
Array Implementation of Binary Trees
● Works OK for complete trees, not for sparse trees

33
Binary search tree
● Everything in left subtree is less than root.
● Everything in right subtree is greater than root. 49

○Recursively!
28 66
● What is the time of searching in a BST?

35 62 80
13
Question:
Draw a (single) binary tree T , such that:
● Each node of T stores a single character
● A preorder traversal of T yields EXAMFUN
● An inorder traversal of T yields MAFXUEN
Question:
What is post order output
of the tree given on the
right?
Question:
Draw the binary tree representation of the following arithmetic expression: (((5+ 4) /(2+1))*(((3+6)-7)/(9-
7))*8)
Question:
Draw an arithmetic expression tree that has four external nodes, storing the number 1,3,5, and 8(with
each number stored in a distinct external node, but not necessary in this order) and has three internal
nodes, each storing an operator from the set {+, -, x, or /}, so that the value of the root is 20. The
operators may return and act on fractions, and operator may be used more than once.
Small Group Activity
Determine how a tree could be utilized to represent an equation. Could
different traversals provide prefix, infix, or postfix notation? Draw a real
example (and cite any sources). Discuss in your small group and post
1-2 paragraphs (with any screenshots necessary for illustration) with
all team members' names included.

You might also like