Chapter 3-5 Linked Lists
Chapter 3-5 Linked Lists
LINKED LISTS
1 01/20/2025
Introduction
Linked lists and arrays are similar since they both
4 01/20/2025
Linked List Concepts:
A linked list is a linear collection of data structure
structure. Head node is the first element in the list and key
is a value in the information field which contains the storage
address of the succossor node
The data items in the linked list are not in consecutive
6 01/20/2025
Cont…
Head(start) :pointer to the first node
7 01/20/2025
Composition of a Linked List
A linked list is called “linked” because each node
in the series
9 01/20/2025
Definition of link list (node of list)
Struct Node
{
data type data;
Node * next; // pointer to next node in the list
};
Example:
struct node
{ char name[20]; // Name of up to 20 letters
int age ;
float height;
node *nxt;// Pointer to next node
};
struct node *start_ptr = NULL;
10 01/20/2025
Advantages of linked lists:
Linked lists have many advantages:
Linked lists are dynamic data structures.
12 01/20/2025
Types of Linked Lists:
17 01/20/2025
Single Linked List
The beginning of the linked list is stored in a "start or
and so on.
The last node in the list has its next field set to NULL to
• Creation.
• Insertion.
• Deletion.
• Traversing.
19 01/20/2025
Creating a node for Single Linked List:
Creating a singly linked list starts with creating a node.
20 01/20/2025
Single linked list with 4 node
21 01/20/2025
The function createlist(), is used
to create ‘n’ number of nodes
22 01/20/2025
Insertion of a Node:
One of the most primitive operations that can be
24 01/20/2025
Inserting a node at the beginning:
The following steps are to be followed to insert a new
node at the beginning of the list:
newnode = getnode();
start = newnode;
25 01/20/2025
shows inserting a node into the single linked
list at the beginning
26 01/20/2025
The function for inserting a node at the
beginning
27 01/20/2025
Inserting a node at the end:
Get the new node using getnode()
newnode = getnode();
temp = start;
29 01/20/2025
The function for inserting a node at the end.
30 01/20/2025
Inserting a node at middle
position:
31 01/20/2025
Deletion of a node:
Another primitive operation that can be done in a
deleted.
A node can be deleted from the list from three
temp = start;
free(temp);
33 01/20/2025
shows deleting a node at the
beginning of a single linked list
34 01/20/2025
The function used for deleting the first
node in the list.
35 01/20/2025
Deleting a node at the end:
If list is empty then display ‘Empty List’ message.
prev=temp;
free(temp);
36 01/20/2025
shows deleting a node at the end
of a single linked list
37 01/20/2025
The function is used for deleting the
last node in the list.
38 01/20/2025
Lab Assignment
Write A Complete Source Code for the
Implementation of single Linked List
operation
39 01/20/2025
Double linked List
A double linked list is a two-way list in which all
nodes will have two links.
This helps in accessing both successor node and
predecessor node from the given node position.
It provides bi-directional traversing. Each node
contains three fields:
• Left link.(Pointer to previous node)
• Data.
• Right link.(pointer to next node)
The left link points to the predecessor node and
the right link points to the successor node.
The data field stores the required data.
40 01/20/2025
Double linked list
Many applications require searching forward
and backward through nodes of a list.
For example searching for a name in a
telephone directory would need forward and
backward scanning through a region of the
whole list.
41 01/20/2025
Operation on double linked List
The basic operations in a double linked list are:
Creation.
Insertion.
Deletion.
Traversing
42 01/20/2025
Creating Doubly Linked Lists
The nodes for a doubly linked list would be defined as
follows:
struct node
{
node *nxt; // Pointer to next node
44 01/20/2025
Node * temp= new Node;
// fill the information in temp
If (!tail)
{
Head= temp;
Tail = temp;
Temp->next=NULL;
Temp-> prev= NULL;
}
45 01/20/2025
Example
Else
{
Temp->next= head;
Head->prev = temp;
Head = temp;
Temp->prev= NULL;
}
46 01/20/2025
Inserting a node at the end:
Node * temp = new Node;
// store the information in new node
If (! tail)
{
Head = temp;
Tail = temp;
Temp-> next = NULL;
Temp->prev= NULL;
}
Else{
tail->next = temp;
Temp->prev= tail;
Temp->next= NULL;
Tail = temp;
}
47 01/20/2025
Inserting at end
48 01/20/2025
Deleting a node at the beginning:
The following steps are followed, to delete a
node at the beginning of the list:
• If list is empty then display ‘Empty List’
message.
• If the list is not empty, follow the steps given
below:
temp = start;
start = start -> right;
start -> left = NULL;
free(temp);
49 01/20/2025
Deleting at beginning
50 01/20/2025
Deleting a node at the end:
The following steps are followed to delete a node
at the end of the list:
• If list is empty then display ‘Empty List’ message
• If the list is not empty, follow the steps given
below:
temp = start;
while(temp -> right != NULL)
{
temp = temp -> right;
}
temp -> left -> right = NULL;
free(temp);
51 01/20/2025
Deleting at end
52 01/20/2025
Traversal and displaying a list (Left to Right):
To display the information, you have to traverse the
list, node by node from the first node, until the end of
the list is reached.
The following steps are followed, to traverse a list from
left to right:
• If list is empty then display ‘Empty List’ message.
• If the list is not empty, follow the steps given below:
temp = start;
while(temp != NULL)
{
print temp-> data;
temp = temp -> right;
}
53 01/20/2025
Traversal and displaying a list (Right to Left):
To display the information from right to left, you have to traverse
the list, node by node from the first node, until the end of the list is
reached
If list is empty then display ‘Empty List’ message.
If the list is not empty, follow the steps given below:
temp = start;
while(temp -> right != NULL)
temp = temp -> right;
while(temp != NULL)
{
print temp -> data;
temp = temp -> left;
}
54 01/20/2025
Counting the Number of Nodes:
The following code will count the number of
nodes exist in the list (using recursion).
int countno de(no de *start)
{
if(start == NULL)
return 0;
else
return(1 + countno de(start ->right ));
}
55 01/20/2025
Lab exercise
Write A Complete Source Code for the
Implementation of Double Linked List
operation:
56 01/20/2025
Circular Linked List
In linear linked lists if a list is traversed (all the elements
57 01/20/2025
Linear linked List
58 01/20/2025
Circular linked list
59 01/20/2025
Cont…
list.
The header node can be separated from the others by either
struct node{
int info;
};
61 01/20/2025
Chapter Four: Stack and
Queue
Stacks can be implemented using arrays
and linked lists.
Stack is an ordered collection of
homogenous data items.
Entry and exit points are referred to as top.
Operation of adding an item is called PUSH
and removing an item is called POP..
Stack works on the principle that an item
added last is removed first is known as
Last-in-First-out(LIFO) data structure.
62 01/20/2025
Examples of LIFO stacks
Ex
63 01/20/2025
Three states of stack
It stores alphabets letters A B, C D
D is popped
Finally E si in inserted .
64 01/20/2025
Stacks features:
It contains homogenous data elements
Elements in a stack are ordered (Linear)
Only topmost items can de retrieved.
To stack.
Popping operation is an item on to the
stack
Pushing operation an item off the stack
Checking if stack is empty or full
65 01/20/2025
Reverse Polish Notation (RPN)
66 01/20/2025
67 01/20/2025
The Push operation
It inserts or pushes a new data element
into the stack.
68 01/20/2025
The Pop operation
It removes an existing item from the top of
stack.
Before this operation, it must be ensured that
stack is not empty.
69 01/20/2025
The isEmpty operation
Returns true if the stack contains no element
It is normally applied before the pop operation.
70 01/20/2025
The isFull operation
Returns true if the stack is full and false
otherwise.
It is generally performed before the push
operation.
71 01/20/2025
Queue
Queue is a collection of homogenous data
items
Items can be added at one end and
removed from another end.
The end at which item is removed is called
FRONT.
The entry point is called REAR.
Queue is First-in-first-out(FIFO) data
structure
72 01/20/2025
…..
a data structure that has access to its data at the front and rear.
operates on FIFO (Fast In First Out) basis.
uses two pointers/indices to keep tack of information/data.
Has two basic operations:
enqueue - inserting data at the rear of the queue
dequeue – removing data at the front of the queue Basic
Operations:
73 01/20/2025
initialize: - creates an empty queue.
isEmpty: - returns true if the queue is empty, otherwise false.
isFull: - returns true if the queue is full, otherwise false.
enQueue: - adds an item at the end (rear) of the queue.
deQueue: - removes an item at the front of the queue.
front: - returns the item at the front of the queue, but don’t remove it.
Linked list implementation of enqueue and
dequeue operations
Enqueue- is inserting a node at the end of a
linked list
Dequeue- is deleting the first node in the list
Operations in queue:
77 01/20/2025
Queue: the add operation
It inserts a new item into the rear of a
queue
If enough space is not available, add
operation may result in overflow condition.
78 01/20/2025
Queue: the remove operation
It removes an item from the front of the
queue
If queue is empty underflow condition
occurs.
79 01/20/2025
Chapter Five: Tree
Structures
This chapter covers:
Basic concepts and definitions
Binary tree
Binary Search Tree (BST)
Operations on BST: Insertion, Searching,
Deletion, Traversal.
Balancing a Tree
80
Chapter Five: Tree Structures
This chapter covers:
Basic concepts and definitions
Binary tree
Binary Search Tree (BST)
Operations on BST: Insertion, Searching,
Deletion, Traversal.
Balancing a Tree
81
Introduction
A tree is a set of nodes and edges that connect pairs of
nodes.
It is an abstract model of a hierarchical relationship
structure.
A tree consists of a number of nodes connected by arcs.
Unlike a real tree, tree data structures are typically
depicted upside down, with the root at the top and the
leaves at the bottom.
A tree is a collection of data elements called nodes
A special node called root which provides an entry point
Nodes are connected together with edges also called
paths
Tree data structure grows from top to bottom.
Root is at the top, and leaves are located at lowest levels.
A node can be represented by a circle, oval, or rectangle.
82
…
Parent node is a node directly above a given node. Root node has no
parent.
Each node can have a number of child nodes, and the parent and
child nodes are connected by arcs.
Child node is directly below a node.
The root is the top node that has no parent nodes. The leaves of the
tree are those that have no child nodes.
Siblings are all children which have a common parent are collectively
known as siblings
If all siblings appear in definite order, the tree is called ordered tree.
83
Figure 1
Ancestors
Nodes which appear on the path from a
given node to the root node
84 01/20/2025
…
85 01/20/2025
Descendents
A descendent is a child of a node.
All of the descendents of a node N, are
called sub tree rooted at N.
86 01/20/2025
Parent, child, and sibling
87 01/20/2025
Tree Level
Needs of a tree are organized at different
levels.
Root node is at level 0, children of root are
at level 1, children of children of root are at
level 2 and so on.
88 01/20/2025
Tree Height
The maximum levels of a node is a tree
called tree height i.e determining the
performance of search algorithms.
A tree with shorter height can be searched
faster than the one with greater height.
89 01/20/2025
Basic cXC
It is non- linear data structure
Binary tree is an ordered structure in which
each node can have at most two child
nodes.
90 01/20/2025
…
A path through the tree to a node is a
sequence of arcs that connect the root to the
node.
The length of a path is the number of arcs in
the path.
The level of a node is equal to the length of
the path from the root to the node plus 1.
The root node is said to be at level 1 of the
tree, its children at level 2, and so on.
The height of a tree is equal to the maximum
level of a node in the tree.
For example, Figure 1a has a height 91 of 2,
…
Trees can be useful data structures as they
often express the structure of real world
information more accurately.
For example, Figure 2 (next page) shows a
tree that represents the structure of
Haramaya University (not the current). This
information would not be easy to represent
in a linear data structure such as a linked
list or an array.
92
…
Haramaya University
Animal
Science
Crop
Productio
n
93
binary tree
A binary tree is a tree whose nodes have at
most two children each: a left child and a right
child. Nodes can have a single child (either left
or right), or they can have no children, but they
can never have more than two children.
94
A Full Binary Tree - Example
95
…
Complete Binary Tree: is a binary tree in which the
level of the any leaf node is either H or H-1 where
H is the height of the tree. The deepest level
should also be filled from left to right.
96
…
97
Binary Search Tree/Ordered Binary
Tree
It is a binary tree which can be empty or
satisfies the following:
Every node has a key and no two nodes have the
same key
The keys in the right subtree are larger than the
keys in the root
The keys in the left subtree are smaller than the
keys in the root
The left and right subtrees are also binary search
trees.
98
Binary Search Tree - Example
Alex
Alex
Abner
Abner Angela
Angela
Abigail
Abigail Adela
Adela Alice
Alice Audrey
Audrey
Adam Agnes
Agnes Allen Arthur
Adam Allen Arthur
99
Cont.. 15
20
10
17 23
6 13
24
22
14
4 8 9
101
Operations on Binary search
tree
Consider the following structure
struct Node{
int num;
10
Node *left,*right;
}; 5 13
Node *rootnodeptr=NULL;
14
3 6 11
2 4 7
102
Insertion
To insert a node (pointed by new node pointer)
in to a binary search tree (whose root node is
pointed by rootnodeptr)
If the tree is empty, the node to be inserted is made
the root node.
Otherwise, search the appropriate position and insert
the node (to insert newnodeptr 8, compare
rootnodeptr not null then compare 8 with 10, since
8<10 go to left compare 8 with 5, since 8>5, go to
right, compare 8 with 6, since 8>6, go to right,
compare, final compare 8 with 7 and since 8>7 and
right of 7 is null, 8 will be inserted to the right of 7)
103
//insert into a binary search tree, RNP=rootnodeptr, NNP=newnodeptr
Node *RNP, Node *NNP
void insertBST(Node *RNP, Node *NNP){
int inserted=0;//a flag to check inserted or not
Node *temp;
temp=RNP;
if(temp==NULL)
{
temp=NNP;
RNP=NNP;}
else{
while(inserted==0){
if(temp->num>NNP->num){
if(temp->left==NULL){
temp->left=NNP
inserted=1;}
else
temp=temp->left;}
104
else
{ //if temp->num <NNP->num
if(temp->right==NULL)
{
temp->right=NNP;
inserted=1;
}
else
temp=temp->right
}//else
}//end of while
}//end of function
105
Node Searching
Searching a binary search tree is not
dissimilar to the process performed when
inserting an item:
Compare the item that you are looking for with
the root,
and then push the comparison down into the
left or right subtree depending on the result of
this comparison, until a match is found or a leaf
is reached.
This takes at most as many comparisons as the
height of the tree.
At worst, this will be the number of nodes in the
tree minus one.
106
Implementation
Function call:
elementExists=searchBST(RNP, number);
The function (recursive implementation)
bool searchBST(Node *CurrNodeptr, int x)
{
if(currNodeptr==NULL)
return (false);
else if (currNodeptr->num==x)
return (true);
else if (currNodeptr->num>x)
return (searchBST(currNodeptr->left, x);
else
return (searchBST(currNodeptr->right, x);
}
107
Alternatively
The functrion call
searchedNodeptr=searchBST(RNP,Number);
The function (recursive implementation)
Node* searchBST(Node *CurrNodeptr, int x)
{
if(currNodeptr==NULL)
return (NULL);
else if (currNodeptr->num==x)
return (currNodeptr);
else if (currNodeptr->num>x)
return (searchBST(currNodeptr->left, x);
else
return (searchBST(currNodeptr->right, x);
}
108
Deletion
Deletion of a node from a binary search tree
can be more problematic. The difficulty of the
operation depends on the position of the node
in the tree. There are three cases:
1. The node is a leaf. This is the easiest case to
deal with. The appropriate pointer of its parent
is set to null and the node deleted
2. The node has one child. This case is also not
complicated. The appropriate pointer of its
parent is modified to point to the child of the
node
3. The node has two children. There is no simple
way to delete nodes like this. The following
sections discuss two possible ways 109 of dealing
110
Deletion by Merging
One way of deleting nodes that have two children is
called deletion by merging.
This algorithm works by merging the two subtrees
of the node and attaching the merged tree to the
node’s parent.
In binary search trees, every value in the left
subtree is less than every value in the right subtree,
so if we can find the largest value in the left
subtree, then we can attach the right subtree as the
right child of this node, and still preserve the
ordered nature of the tree. This process is illustrated
in the following figure.
1 5
114
Exercises..
From the above binary search tree
considering independently,
Give the tree after node 1 is deleted.
Give the tree after node 2 is deleted.
Give the tree after node 6 is deleted
(Deletion by merging)
Give the tree after node 10 is deleted
(Deletion by Coping).
115
Implementation (deletion by copy)
//PDNP=Previous Node of the "to be deleted Node"
void deleteBST(Node *RNP, Node* PDNP,int x){
Node *DNP;//DNP=DeleteNodePointer
if(RNP==NULL)
cout<<"Data Not Found";
else if(RNP->num > x)
deleteBST(RNP->left, RNP, x);
else if(RNP->num < x)
deleteBST(RNP->right, RNP, x);
else //if RNP->num==x
{
DNP=RNP;
if((DNP->left==NULL)&&(DNP->right==NULL)){//leaf node
if (PDNP->left==DNP)
{
PDNP->left=NULL;
delete DNP;
}
else
{
PDNP->right==NULL;
delete DNP;
}
} 116
Implementation….
else if(DNP->left!=NULL){
PDNP=DNP;
DNP=DNP->left;
while(DNP->right!=NULL){
PDNP=DNP;
DNP=DNP->right;
}
RNP->num=DNP->num;
deleteBST(DNP,PDNP,DNP->num);
}//else
else//has only a right child
{
PDNP=DNP;
DNP=DNP->right;
while(DNP->left!=NULL){
PDNP=DNP;
DNP=DNP->left;
}
RNP->num=DNP->num;
deleteBST(DNP,PDNP,DNP->num);
}//else
} 117
Tree Traversal
Compared to linear data structures like
linked lists and one dimensional arrays, which
have only one logical means of traversal, tree
structures can be traversed in many different
ways. Starting at the root of a binary tree,
there are three main steps that can be
performed and the order in which they are
performed define the traversal type. These
steps are: Performing an action on the current
node (referred to as "visiting" the node); or
repeating the process with the subtrees rooted
at our left and right children. Thus the process
is most easily described through recursion.
118
Traversal methods
To traverse a non-empty binary tree in preorder, we
perform the following three operations: 1. Visit the
root. 2. Traverse the left subtree in preorder. 3.
Traverse the right subtree in preorder.
To traverse a non-empty binary tree in inorder, perform
the following operations: 1. Traverse the left subtree in
inorder. 2. Visit the root. 3. Traverse the right subtree
in inorder.
To traverse a non-empty binary tree in postorder,
perform the following operations: 1. Traverse the left
subtree in postorder. 2. Traverse the right subtree in
postorder. 3. Visit the root. This is also called
Depth-first traversal
Finally, trees can also be traversed in level-order,
where we visit every node on a level before going to a
119
lower level. This is also called Breadth-first traversal
Binary Tree Traversals
Inorder Traversal (L-N-R)
1. Traverse the left subtree of R in inorder
2. Process the root R
3. Traverse the right subtree of R in inorder
Preorder Traversal (N-L-R)
4. Process the root R
5. Traverse the left subtree of R in preorder
6. Traverse the right subtree of R in preorder
Postorder Traversal (L-R-N)
7. Traverse the left subtree of R in preorder
8. Traverse the right subtree of R in preorder
12 9. Process the root R 01/20/2025
0
Excercise
Inorder:D-B-E-F-A-G-C-L-J-H-K-
Preorder:A-B-D –E-F--C-G-H-J-L K
Postorder:D-FEB—G—L--J—K-H-C-A-
12 01/20/2025
1
Preorder traversal yields:
F, B, A, D, C, E, G, I, H
In-order traversal yields:
A, B, C, D, E, F, G, H, I
Note that the in-order traversal
of a binary search tree yields an
ordered list
Postorder traversal yields:
A, C, E, D, B, H, I, G, F
Level-order traversal yields:
F, B, G, A, D, I, C, E, H
122
Implementation of preorder
void preorder(Node *currNodeptr){
if(currNodeptr!=NULL){
cout<<currNodeptr->num;
preorder(currNodeptr->left);
preorder(currNodeptr->right);
}
}
123
Implementation of Inorder
void inorder(Node *currNodeptr){
if(currNodeptr!=null){
inorder(currNodeptr->left);
cout<<currNodeptr->num;
inorder(currNodeptr->right);
}
}
124
Implementation of postorder
traversal
voidpostorder(Node *currNodepptr){
if (currNodeptr!=NULL){
postorder(currNodeptr->left);
postorder(currNodeptr->right);
cout<<currNodeptr->num;
}
}
125
Balancing a Tree
if a tree becomes unbalanced, the
efficiency of search operations using that
tree can be affected
A tree is perfectly balanced if it is balanced
and all leaves are to be found on one or
two levels.
126
How can we balance an unbalanced
tree?
Often trees become unbalanced because of
the order in which data arrives.
One technique to ensure trees become
balanced is to change the order in which
values are added to the tree.
This can be achieved by storing all values in
a linear data structure such as an array as
they arrive.
When all values have arrived they can be
added to the tree in such an order that leads
to a well-balanced tree.
127
example
3 7 8 10 12 13 15 19 22 23
The first node to be added to the tree is
the middle element of the array, in our
case 12. This effectively divided the
array into two.
Next, we recursively build two subtrees
based on the two remaining halves of
the array.
Dealing only with the left half, the next
node to be selected is 7. Again, this
divides our array into two halves:
128
…
3 7 8 10
The left half now consists of a single
element, so this is added to the tree
and we process the right half.
This consists of the values 8 and 10,
so these are also added to the tree.
This process continues until all
nodes have been added. In our case,
the values will be added to the tree
in the following order
129
The balanced tree…
130
…
The disadvantage of this algorithm is that it
requires the arrival of all values before we
can start to use the tree.
This is not always possible. It is always
possible to use inorder traversal to transfer
the data from the tree to an array, and then
recreate the tree using the algorithm
above.
131
Reading Assignment:
Balancing a tree
Self-adjusting trees
Heaps
Polish notation and expression trees
132