MODULE-3
ADDITIONAL LIST OPERATIONS
typedef struct listnode *listpointer ;
typedef struct listnode
{
char data;
listpointer link;
};
Inverting a singly linked list
ListPointer invert(ListPointer lead)
{
ListPointer middle, trail;
middle = NULL;
while (lead)
{
trail = middle;
middle = lead;
lead = lead->link;
middle->link = trail;
}
return middle;
}
Concatenating singly linked lists
listpointer concatenate(listpointer ptr1, listpointer ptr2)
{
listpointer temp;
if(ptr1==NULL)
return ptr2;
if(ptr2==NULL)
return ptr1;
temp=ptr1;
while(templink!=NULL)
temp=templink;
templink=ptr2;
return ptr1;
}
Operations For Circularly Linked Lists
Inserting at the front of a list
void insertfront(listpointer *last, listpointer node)
{
if (*last == NULL) {
/* The list is empty, change ptr to point to the new entry */
*last = node;
node->link = node;
} else
{
/* List is not empty, add the new entry at the front */
node->link = (*last)->link;
(*last)->link = node;
}
}
Finding the length of a circular list
int length(listpointer last) {
listpointer temp;
int count = 0;
if (last ) {
temp = last;
do {
count++;
temp = temp“>link;
} while {temp != last);
}
return count;
}
What is Doubly Linked List?
• A doubly linked list (DLL) is a special type of linked
list in which each node contains a pointer to the
previous node as well as the next node of the linked list.
circular Doubly Linked List
A node in a doubly linked list has at least three fields, a left link field (llink), a
data field (item), and a right link field (rlink).
The necessary declarations are:
typedef struct node *nodepointer;
typedef struct
{
nodepointer llink;
element item;
nodepointer rlink;
} node;
• suppose that ptr points to any node in a doubly linked list.
• Then:
ptr = ptr->llink->rlink = ptr->rlink->llink
Insertion into a doubly linked
circular list
void dinsert(nodepointer node, nodepointer newnode)
{ /* insert newnode to the right of node */
newnode->llink = node;
newnode-> rink = node->rlink;
node->rlink->llink = newnode;
node—>rlink = newnode;
}
Deletion from a doubly linked circular list
void ddelete(NodePointer node, NodePointer deleted)
{
if (node == deleted)
{
printf("Deletion of head node not permitted.\n");
}
else
{
deleted->llink->rlink = deleted->rlink;
deleted->rlink->llink = deleted->llink;
free(deleted);
}
}
TREES
• Non linear data structure
• Used to represent data containing a hierarchical relationship
between data elements
DEFINITION
A tree is a finite set of one or more nodes such that
• There is a specially designated node called root.
• The remaining nodes are partitioned into n >= 0 disjoint set T1,…,Tn,
where each of these sets is a tree. T1,…,Tn are called the subtrees of
the root
Terminologies
Node :
is the item of information and branches to other nodes
Degree of node : number of subtrees of a node is called its degree
ex: degree(A)=3
degree(C)=1
degree(M)=0
Leaf nodes /terminal nodes: nodes that have degree 0
example: {K,L,F,G,M,I,J}
Degree of a tree: is the max of degree of the nodes in the tree
Level of a node:
is defined by letting the root be at level 1 .
if a node is at level l ,then its children are at level l+1
Height /depth of a tree: is defined to be the max level of any node in
the tree
Ancestors of a node: are all the nodes along the path from root to
that node
List Representation
• The tree can be represented as a List
(A (B (E (K, L), F), C (G), D (H (M), I, J) ) )
• The information in the root node comes first.
• The root node is followed by a list of the subtrees of that node.
• Each link represent child of a node
Left Child-Right Sibling
Representation
• we first note that every node has only one leftmost child and one
closest right sibling.
Representation As A Degree
Two Tree
• the degree two tree representation of a tree is obtained by rotating
the left child-right sibling tree clockwise by 45 degrees.
BINARY TREES
• Definition: A binary tree is a finite set of nodes that is either empty or
consists of a root and two disjoint binary trees called the left subtree
and the right subtree.
The Abstract Data Type
Properties Of Binary Trees
1.Lemma :[Maximum number of nodes]
The maximum number of nodes on level i of a binary tree is ,i>=1
The maximum number of nodes in a binary tree of depth k is 2^k - 1, k
>= 1.
Proof:
The proof is by induction on i.
(1) Induction base: The root is the only node on level i = 1. Hence, the
maximum number of nodes on level i = 1 is 2^i-1 = 2^0=1.
(2) Induction hypothesis: let i be an arbitrary positive integer greater
than 1 .Assume that max number of nodes on level i-1 is
• Induction step: The maximum number of nodes on level i - 1 is 2^i-1
by the induction hypothesis. Since each node in a binary tree has a
maximum degree of 2, the maximum number of nodes on level i is
two times the maximum number of nodes on level i-1 or
The maximum number of nodes in a binary tree
of depth k is -1, k >= 1.
• The maximum number of nodes in a binary tree of depth k is
K k
Σ (max number of nodes on level i)= Σ =-1
i=1 i=1
Lemma 2 :[Relation between number of leaf nodes and nodes
of degree 2]
• For any nonempty binary tree, T, if is the number of leaf nodes and
the number of nodes of degree 2, then = + 1
Proof:
Let be the number of nodes of degree one and n the total number of
nodes.
Since all nodes in T are of degree at most two
n = + + ---------------------------1
• If we count the number of branches in a binary tree, every node except
the root has a branch leading into it.
• If B is the number of branches, then n = B+1
• All branches stem from a node of degree one or two. Thus,
B=+2.
Hence , n=B+1n= + 2 +1------------------2
Subtract eq 2 from 1 & rearranging terms
= +1
Full binary tree
• A full binary tree of depth k is a binary tree of depth k having -1
nodes, k>=0.
Complete binary tree
• Definition: A binary tree with n nodes and depth k is complete iff its
nodes correspond to the nodes numbered from 1 to n in the full
binary tree of depth k
• Neither full nor complete
full not complete
Complete not full
Complete & full
Binary Tree Representations
• There are two different methods to represent a binary tree in
computers memory.
1. Array Representation
2. Linked Representation
Array Representation
• If a complete binary tree with n nodes is represented sequentially,
then for any node with index i, 1 <=i <= n
we have:
1. Parent(i) is at i/ 2 if i!=1. If i = 1, i is at the root and has no parent.
2. left-child(i) is at 2i if 2i <= n. If 2i > n, then i has no left child.
3.right-child(i) is at 2i + 1 if 2i+ 1 <=n. If 2i + 1 >= n, then i has no right
child
index TREE
0 -
INDEX NODE
1 A 0 -
2 B 1 A
3
4 C
2 B
5 3 C
6 4 D
7
8 D
5 E
9 6 F
10 7 G
11
12
8 H
13 9 I
14
15
16 E
Linked Representation
• sequential representation is acceptable for complete binary trees, it
wastes space for many other binary trees
• insertion or deletion of nodes from the middle of a tree requires the
movement of potentially many nodes to reflect the change in the
level of these nodes. We can easily overcome these problems by using
a linked representation.
• Each node has three fields, left-child, data, and right-child, and is
defined in C as
typedef struct node * treepointer;
typedef struct node
{
int data;
treepointer leftchild, rightchiId;
};
BINARY TREE TRAVERSALS
• TREE Traversing refers to a process of visiting each node in the tree
exactly once.
• A full traversal produces a linear order for the information in a tree.
• There are 3 traversal methods
1. Pre-Order Traversal ( Root-Left-Right)
2. In-Order Traversal ( Left-Root-Right)
3. post-Order Traversal ( Left-Right-Root)
Inorder Traversal
• an inorder traversal moves down the tree toward the left until a null
node is reached.
• The null node’s parent is then "visited," and the traversal continues
with the node that is one to the right.
• If there is no move to the right, the traversal continues with the last
unvisited node at the next higher level of the tree.
void inorder(treepointer ptr) /* inorder tree traversal */
{
if (ptr)
{
inorder(ptr->leftchild);
printf("%d", ptr->data) ;
inorder(ptr->rightchild);
}
Preorder Traversal
• With this traversal we "visit" the node first and then follow left
branches visiting all nodes encountered. This continues until we reach
a null node. At this point, we back up to the closest ancestor that has
a right child and continue with this child
Post order traversal
void preorder(treepointer ptr) /* inorder tree traversal */
{
if (ptr)
{
printf("%d", ptr->data) ;
preorder(ptr->leftchild);
preorder(ptr->rightchild);
}
}
void postorder(treepointer ptr) /* inorder tree traversal */
{
if (ptr)
{
postorder(ptr->leftchild);
postorder(ptr->rightchild);
printf("%d", ptr->data) ;
}
}
Iterative inorder traversal
1.Create an empty stack (say S).
2.Initialize the node as root.
3.Push the node to S and set node = node->left until
node is NULL
4.If node is NULL and the stack is not empty then:
4.Pop the top item from the stack.
5.Print the popped item and set node= popped_item->right
6.Go to step 3.
5.If node is NULL and the stack is empty then we are
done.
void iter_inorder(treepointer node)
{
int top = -1; /* initialize stack */
treepointer stack[MAX—STACK—SIZE];
for (;;)
{
for(; node!=NULL; node=nodeleftchild)
push(node);
node=pop();
if (!node) break;
printf( “%d”,node->data)
node=node—>rightchild;
}
Level Order Traversal
void levelorder(treepointer ptr)
{
int front = rear = 0;
treepointer queue[MAX—QUEUE—SIZE] ;
if (!ptr) return; /★ empty tree */
addq(ptr);
for (;;)
{
ptr = deleteq(ptr);
if (ptr)
{
printf (" %d’, ptr->data)
if (ptr->leftchild)
addq(ptr->leftchild);
if (ptr->rightchild)
addq(ptr->rightchild);
}
else
break;
}
THREADED BINARY TREES
• In linked representation of any binary tree, there are more null links
than actual pointers. Specifically, there are n + 1 null links out of 2n
total links.
• TBT replaces the null links by pointers to other nodes in the tree
called threads.
Rules to construct the threads
1.If ptr -> leftchild is null, replace ptr -> leftchild with a pointer to the
node that would be visited before ptr in an inorder traversal.(inorder
predecessor of ptr)
2. If ptr -> rightchild is null, replace ptr -> rightchild with a pointer to
the node that would be visited after ptr in an inorder traversal.
(inorder successor of ptr)
• When we represent the tree in memory, we must be able to
distinguish between threads and normal pointers.
• This is done by adding two additional fields to the node structure,
leftthread and rightthread.
• Assume that ptr is an arbitrary node in a threaded tree.
• If ptr -> leftthread = TRUE, then ptr -> leftchild contains a thread;
otherwise it contains a pointer to the left child.
• if ptr -> rightthread = TRUE, then ptr -> rightchild contains a thread;
otherwise it contains a pointer to the right child.
Node structure for Threaded
Binary Tree
typedef struct threadedtree * threadedpointer;
typedef struct threadedtree
{
short int leftthread;
threadedpointer leftchild;
char data;
threadedpointer rightchiId;
short int rightthread;
};
• In threded binary tree, the leftlink of leftmost node and right link of
rightmost child have been left dangling
• we do not want to have loose threads in our tree. Therefore, we
assume that all threaded binary trees have a head node.
• This means that an empty threaded tree always contains one node
In order succesor of TBT
threadedpointer insucc(threadpointer node)
{
threadpointer temp;
temp=noderlink;
if(noderthread== 1) return temp;
while (templthread !=1)
temp=templlink;
return temp;
}
Inorder traversal of TBT
void tinorder (threadedpointer tree)
{
threadedpointer temp=tree;
for(;;)
{
temp=insucc(temp);
If (temp==tree) break;
printf(“%c”,tempdata);
}
void tinorder (threadedpointer tree)
{
if (headllink==head)
{
printf(“tree is empty”);
return;
}
printf(“inorder traversal :\n”);
temp=headllink;
while(templthread != 1)
temp=templlink;
while(temp !=head)
{
printf(“%3c”,tempdata);
temp=insucc(temp);
}
}