1
What is a Tree
• A tree is a finite nonempty
set of elements.
• It is an abstract model of a
hierarchical structure.
• consists of nodes with a
parent-child relation.
Computers”R”Us
Sales other
Manufacturing
Laptops Desktops
US International
Europe Asia Canada
2
Why a tree?
• Applications:
• Applications:
– storing files
– compiler design
– text processing
– searching algorithms
 Organization charts
 File systems
 Programming environments
 Faster than linear data structures
 More natural fit for some kinds of data
Binary Trees
3
A binary tree is made of nodes, where each node contains a "left“ pointer, a
"right" pointer, and a data element.
The "root" pointer points to the topmost node in the tree. The left and right
pointers recursively point to smaller "subtrees" on either side.
the binary tree is built with a node type like this..
struct node {
int data;
node* left;
node* right;
}
Traversal of Binary Trees
4
With preorder traversal we first visit a node, then traverse its left subtree, and
then traverse its right subtree.
With inorder traversal we first traverse the left subtree, then visit the node,
and then traverse its right subtree.
With postorder traversal we first traverse the left subtree, then traverse the
right subtree, and finally visit the node.
Traversal of Binary Trees : Example
5
6
Binary search Trees
7
A "binary search tree" (BST)
or "ordered binary tree" is a
type of binary tree where the
nodes are arranged in order:
for each node, all elements in
its left subtree are less-orequal
to the node (<=), and all
the elements in its right
subtree are greater than the
node (>). The tree shown on
the right is a binary search
tree --because the "root" node
is a 5, and its left subtree
nodes (1, 3, 4) are <= 5, and
its right subtree nodes (6, 9)
are > 5. also for the other left
and right subtrees.
8
full
9
Full Binary Tree
• A full binary tree (sometimes proper binary tree or 2-tree
or strictly binary tree) is a tree in which every node other
than the leaves has two children .
• All nodes have either 0 or 2 children.
Called : Full, Strict , Proper binary tree or 2-tree binary tree.
full binary tree.
1
2 3
7
5
11
4
10
6
9
8 15
14
13
12
Full binary tree of depth 4
10
Complete Binary Trees
• A Binary Tree is complete Binary Tree if all levels are
completely filled except possibly the last level and the
last level has all keys as left as possible.
• A binary tree with n nodes and level k is complete if its
nodes correspond to the nodes numbered from 1 to n
in the full binary tree of level k.
1
2 3
7
5
9
4
8
6
Complete binary tree
11
Skewed Binary Tree
• If a tree which is dominated by left child node or right child node, is
said to be a Skewed Binary Tree.
• In a skewed binary tree, all nodes except one have only one child
node. The remaining node has no child.
• In a left skewed tree, most of the nodes have the left child without
corresponding right child.
• In a right skewed tree, most of the nodes have the right child
without corresponding left child.
12
Height balanced binary tree (AVL Tree)
An AVL tree is a binary search tree in which
A binary search tree is said to be AVL balanced if:The difference in the
heights between the left and right sub-trees is at most 1, and Both
sub-trees are themselves AVL trees
AVL tree checks the height of the left and the right
sub-trees and assures that the difference is not more than 1.
This difference is called the Balance Factor.
AVL property
violated here
13
Searching in the binary search tree
14
Given a binary search tree and a "target" value,
search the tree to see if it contains the target.
The basic pattern of the code occurs in many recursive tree algorithms:
-deal with the base case where the tree is empty
-deal with the current node,
-and then use recursion to deal with the subtrees.
If the tree is a binary search tree, there is often some sort of less-than test on
the node to decide if the recursion should go left or right.
15
Recursive search tree function:
Node * search_for_node( Node* sub_root, int target)
{
if (sub_root == NULL || sub_root->data == target)
return sub_root;
else if (sub_root->data < target)
return search_for_node(sub_root->right, target);
else return search_for_node(sub_root->left, target);
}
Node * Search_for_node( Node *sub_root, int target)
{
while (sub_root != NULL && sub_root->data != target)
if (sub_root->data < target) sub_root = sub_root->right;
else sub_root = sub_root->left;
return sub_root;
}
Nonrecursive version:
Adding New Node To Binary search Tree
Adding a new node to the binary search tree requires identifying
its position in the tree according to its data value. So most of
the time we need to search the tree to decide where the new
node Will fit.
In the following code if the tree is empty , then the new node will
be the root ,but if it’s not empty , we have to go down the tree
and check each node’s data and compare it with the new data,
upon the result we should go right or left
The following figure shows the steps required to insert the nodes
e b d f a g c in sequence
16
17
18
/* Given a binary search tree and a number, inserts a new node with the given
number in the correct place in the tree.Returns the new root pointer which the
caller should then use (the standard trick to avoid using reference
parameters).*/
Node* insert (struct Node* node, int data)
{
// 1. If the tree is empty, return a new, single node
if (node == NULL)
return( newNode (data) ); // newNode is an auxiliary function : see next slide
else {
// 2. Otherwise, recur down the tree
if ( data <= node->data )
node->left = insert (node->left, data);
else
node->right = insert (node->right, data);
return(node); // return the (unchanged) node pointer
}
}
19
*/
Helper function that allocates a new node with the given data and NULL
left and right pointers.
/*
Node* NewNode (int data)
{
Node* node = new(struct Node); // "new" is like "malloc"
node->data = data;
node->left = NULL;
node->right = NULL;
return(node);
}
If a Record with a key matching that of new data already belongs to the Search
tree a code of duplicate error is returned. Otherwise, the Record new data is
inserted into the tree in such a way that the properties of a binary
search tree are preserved, and a code of success is returned.
20
Search_and_insert( node* &sub_root,char newdata)
{
if (sub_root == NULL) {
Sub_root = newnode (newdata);
return success;
}
else if (newdata < sub_root->data)
return search_and_insert(sub_root ->left, newdata);
else if (newdata > sub_root->data)
return search_and_insert(sub_root->right, newdata);
else return duplicate_error;
}
21
Treesort
When a binary search tree is traversed in inorder(LVR), the keys will come out in
sorted order.This is the basis for a sorting method, called
treesort: Take the entries to be sorted, use the method insert to build
them into a binary search tree, and then use inorder traversal to put them out in
order.
First advantage of treesort : The nodes need not all be available at the
start of the process, but are built into the tree one by one as they become
available.
Second advantage: The search tree remains available for later
insertions and removals.
Drawback: If the keys are already sorted, then treesort will be a
disaster.the search tree it builds will reduce to a chain.Treesort should never be
used if the keys are already sorted, or are nearly so.
Removing a node from the Binary Search Tree
22
23
node* Remove( node* root, int key)
{
if (root == NULL)
return root;
if (key < root->data)
root->left = deleteNode(root->left, key);
else if (key > root->data)
root->right = deleteNode(root->right, key);
else {
if (root->left == NULL and root->right == NULL)
return NULL;
else if (root->left == NULL) {
struct node* temp = root->right;
free(root);
return temp;
}
else if (root->right == NULL) {
struct node* temp = root->left;
free(root);
return temp;
}
struct node* temp = min (root->right);
root->data = temp->data;
root->right = Remove(root->right, temp->data);
}
return root;
}
24
Given a binary tree, print out all of its root-to-leaf
paths, one per line. Uses a recursive helper to do the work.
void printPaths(struct node* node)
{int path[1000];
printPathsRecur(node, path, 0); }
/*Recursive helper function -- given a node, and an array
containing
the path from the root node up to but not including this node,
print out all the root-leaf paths. */
void printPathsRecur(struct node* node, int path[], int pathLen)
{
if (node==NULL) return;
// append this node to the path array
path[pathLen] = node->data;
pathLen++;
// it's a leaf, so print the path that led to here
if (node->left==NULL && node->right==NULL)
{
printArray(path, pathLen);
}
else
{ // otherwise try both subtrees
printPathsRecur(node->left, path, pathLen);
printPathsRecur(node->right, path, pathLen);
} }

Treeeeeeeeeeeeeeeeereeeeeeeeeeeeeeee.pdf

  • 1.
    1 What is aTree • A tree is a finite nonempty set of elements. • It is an abstract model of a hierarchical structure. • consists of nodes with a parent-child relation. Computers”R”Us Sales other Manufacturing Laptops Desktops US International Europe Asia Canada
  • 2.
    2 Why a tree? •Applications: • Applications: – storing files – compiler design – text processing – searching algorithms  Organization charts  File systems  Programming environments  Faster than linear data structures  More natural fit for some kinds of data
  • 3.
    Binary Trees 3 A binarytree is made of nodes, where each node contains a "left“ pointer, a "right" pointer, and a data element. The "root" pointer points to the topmost node in the tree. The left and right pointers recursively point to smaller "subtrees" on either side. the binary tree is built with a node type like this.. struct node { int data; node* left; node* right; }
  • 4.
    Traversal of BinaryTrees 4 With preorder traversal we first visit a node, then traverse its left subtree, and then traverse its right subtree. With inorder traversal we first traverse the left subtree, then visit the node, and then traverse its right subtree. With postorder traversal we first traverse the left subtree, then traverse the right subtree, and finally visit the node.
  • 5.
    Traversal of BinaryTrees : Example 5
  • 6.
  • 7.
    Binary search Trees 7 A"binary search tree" (BST) or "ordered binary tree" is a type of binary tree where the nodes are arranged in order: for each node, all elements in its left subtree are less-orequal to the node (<=), and all the elements in its right subtree are greater than the node (>). The tree shown on the right is a binary search tree --because the "root" node is a 5, and its left subtree nodes (1, 3, 4) are <= 5, and its right subtree nodes (6, 9) are > 5. also for the other left and right subtrees.
  • 8.
  • 9.
    9 Full Binary Tree •A full binary tree (sometimes proper binary tree or 2-tree or strictly binary tree) is a tree in which every node other than the leaves has two children . • All nodes have either 0 or 2 children. Called : Full, Strict , Proper binary tree or 2-tree binary tree. full binary tree. 1 2 3 7 5 11 4 10 6 9 8 15 14 13 12 Full binary tree of depth 4
  • 10.
    10 Complete Binary Trees •A Binary Tree is complete Binary Tree if all levels are completely filled except possibly the last level and the last level has all keys as left as possible. • A binary tree with n nodes and level k is complete if its nodes correspond to the nodes numbered from 1 to n in the full binary tree of level k. 1 2 3 7 5 9 4 8 6 Complete binary tree
  • 11.
    11 Skewed Binary Tree •If a tree which is dominated by left child node or right child node, is said to be a Skewed Binary Tree. • In a skewed binary tree, all nodes except one have only one child node. The remaining node has no child. • In a left skewed tree, most of the nodes have the left child without corresponding right child. • In a right skewed tree, most of the nodes have the right child without corresponding left child.
  • 12.
    12 Height balanced binarytree (AVL Tree) An AVL tree is a binary search tree in which A binary search tree is said to be AVL balanced if:The difference in the heights between the left and right sub-trees is at most 1, and Both sub-trees are themselves AVL trees AVL tree checks the height of the left and the right sub-trees and assures that the difference is not more than 1. This difference is called the Balance Factor. AVL property violated here
  • 13.
  • 14.
    Searching in thebinary search tree 14 Given a binary search tree and a "target" value, search the tree to see if it contains the target. The basic pattern of the code occurs in many recursive tree algorithms: -deal with the base case where the tree is empty -deal with the current node, -and then use recursion to deal with the subtrees. If the tree is a binary search tree, there is often some sort of less-than test on the node to decide if the recursion should go left or right.
  • 15.
    15 Recursive search treefunction: Node * search_for_node( Node* sub_root, int target) { if (sub_root == NULL || sub_root->data == target) return sub_root; else if (sub_root->data < target) return search_for_node(sub_root->right, target); else return search_for_node(sub_root->left, target); } Node * Search_for_node( Node *sub_root, int target) { while (sub_root != NULL && sub_root->data != target) if (sub_root->data < target) sub_root = sub_root->right; else sub_root = sub_root->left; return sub_root; } Nonrecursive version:
  • 16.
    Adding New NodeTo Binary search Tree Adding a new node to the binary search tree requires identifying its position in the tree according to its data value. So most of the time we need to search the tree to decide where the new node Will fit. In the following code if the tree is empty , then the new node will be the root ,but if it’s not empty , we have to go down the tree and check each node’s data and compare it with the new data, upon the result we should go right or left The following figure shows the steps required to insert the nodes e b d f a g c in sequence 16
  • 17.
  • 18.
    18 /* Given abinary search tree and a number, inserts a new node with the given number in the correct place in the tree.Returns the new root pointer which the caller should then use (the standard trick to avoid using reference parameters).*/ Node* insert (struct Node* node, int data) { // 1. If the tree is empty, return a new, single node if (node == NULL) return( newNode (data) ); // newNode is an auxiliary function : see next slide else { // 2. Otherwise, recur down the tree if ( data <= node->data ) node->left = insert (node->left, data); else node->right = insert (node->right, data); return(node); // return the (unchanged) node pointer } }
  • 19.
    19 */ Helper function thatallocates a new node with the given data and NULL left and right pointers. /* Node* NewNode (int data) { Node* node = new(struct Node); // "new" is like "malloc" node->data = data; node->left = NULL; node->right = NULL; return(node); }
  • 20.
    If a Recordwith a key matching that of new data already belongs to the Search tree a code of duplicate error is returned. Otherwise, the Record new data is inserted into the tree in such a way that the properties of a binary search tree are preserved, and a code of success is returned. 20 Search_and_insert( node* &sub_root,char newdata) { if (sub_root == NULL) { Sub_root = newnode (newdata); return success; } else if (newdata < sub_root->data) return search_and_insert(sub_root ->left, newdata); else if (newdata > sub_root->data) return search_and_insert(sub_root->right, newdata); else return duplicate_error; }
  • 21.
    21 Treesort When a binarysearch tree is traversed in inorder(LVR), the keys will come out in sorted order.This is the basis for a sorting method, called treesort: Take the entries to be sorted, use the method insert to build them into a binary search tree, and then use inorder traversal to put them out in order. First advantage of treesort : The nodes need not all be available at the start of the process, but are built into the tree one by one as they become available. Second advantage: The search tree remains available for later insertions and removals. Drawback: If the keys are already sorted, then treesort will be a disaster.the search tree it builds will reduce to a chain.Treesort should never be used if the keys are already sorted, or are nearly so.
  • 22.
    Removing a nodefrom the Binary Search Tree 22
  • 23.
    23 node* Remove( node*root, int key) { if (root == NULL) return root; if (key < root->data) root->left = deleteNode(root->left, key); else if (key > root->data) root->right = deleteNode(root->right, key); else { if (root->left == NULL and root->right == NULL) return NULL; else if (root->left == NULL) { struct node* temp = root->right; free(root); return temp; } else if (root->right == NULL) { struct node* temp = root->left; free(root); return temp; } struct node* temp = min (root->right); root->data = temp->data; root->right = Remove(root->right, temp->data); } return root; }
  • 24.
    24 Given a binarytree, print out all of its root-to-leaf paths, one per line. Uses a recursive helper to do the work. void printPaths(struct node* node) {int path[1000]; printPathsRecur(node, path, 0); } /*Recursive helper function -- given a node, and an array containing the path from the root node up to but not including this node, print out all the root-leaf paths. */ void printPathsRecur(struct node* node, int path[], int pathLen) { if (node==NULL) return; // append this node to the path array path[pathLen] = node->data; pathLen++; // it's a leaf, so print the path that led to here if (node->left==NULL && node->right==NULL) { printArray(path, pathLen); } else { // otherwise try both subtrees printPathsRecur(node->left, path, pathLen); printPathsRecur(node->right, path, pathLen); } }