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

ds 3

Uploaded by

y2h7gdh7n6
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views

ds 3

Uploaded by

y2h7gdh7n6
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 68

Data Structures - Unit 3

Prepared by

Prof. Nandini K
Dr. Senthil Kumar A
UNIT III - DYNAMIC DATA STRUCTURES:

Linked List: Types, Representation of Linked Lists in Memory.


Traversing, Searching, Insertion & Deletion from Linked List. Circular
List, Doubly Linked List, Operations on Doubly Linked List (Insertion,
Deletion, Traversal).

Applications: Stack & Queue Implementation using Linked Lists.


Case Study: Josephus problem. TB2: 4.2,4.3,4.5
List
■ A list refers to a sequence of data items
□ Example: An array
■ The array index is used for accessing and
manipulation of array elements
□ Problems with arrays
■ The array size has to be specified at the beginning
(at least during dynamic allocation)
□ realloc can be used to readjust size in middle, but
contiguous chunk of memory may not be available
■ Deleting an element or inserting an element may require
shifting of elements
■ Wasteful of space
Linked List
• A linked list is a linear data structure where each element,
known as a node, is connected to the next one using pointers.
• A node contains two fields i.e. data stored at that particular
address and the pointer which contains the address of the
next node in the memory.
• The last node of the list contains pointer to the null.

node
data next

4
Linked List …

A linked list can change during execution ( Dynamic Data


Structure)
• Successive elements are connected by pointers.
• Last element points to NULL.
• It can grow or shrink in size during execution of a program.
• It can be made just as long as required.
• It does not waste memory space.
5
Linked List - Representation
Linked List can be implemented using Array / Structures ADT

Structures ADT supports to implement Linked List in the


following way.

• Make each data in the list part of a structure

• The structure also contains a pointer or link to the structure


(of the same type) containing the next data

• This type of list is called a linked list


cont..

■ Let each structure of the list (lets call it node) have two fields:
□ One containing the data
□ The other containing the address of the structure
holding the next data in the list
■ The structures in the linked list need not be contiguous
in memory
□ They are ordered by logical links that are stored as part of
the data in the structure itself
□ The link is a pointer to another structure of the same type
struct node
{
int data;
struct node *next;
}
■ The pointer variable next contains either the address of the
location in memory of the successor list element or the
special value NULL defined as 0

□ NULL is used to denote the end of the list (no successor element)

■ Such structures which contain a member field pointing to the


same structure type are called self- referential structures
Example: nodes of the list
struct node a, b, c;
a.data = 1;
b.data = 2;
c.data = 3;
a.next = b.next = c.next = NULL

a.next = &b;
b.next = &c;
Types of Linked
List
• Singly Linked List
• Doubly Linked List
• Circular Linked List
• Circular Doubly Linked List
• Header Linked List
1. Singly Linked List
■ A singly linked list is a data structure consisting of a sequence
of nodes
■ Each node stores
□ data
□ link to the next node

■ A head pointer addresses the first element of the list


■ Each element points at a successor element
■ The last element has a link value NULL
■ In general, a node of the linked list may be
represented as
Example: Creating a Singly Linked List

■ Structure for each nod


■ Create the links between the nodes
e struct stud n1.next = &n2
n2.next = &n3
{ n3.next =
int roll; NULL

char name[30];
int age;
struct stud *next;
};
■ Suppose the list has three students’ records
■ Declare three nodes n1, n2, and n3
struct stud n1, n2,
Basic operations of Linked List

• Creation - Creates a linked list


• Insertion – Adds an element to the list.
• Deletion – Deletes an element to the list.
• Display – Displays the complete list.
• Search – Searches an element using the given
• Delete key.
– Deletes an element using the given key.

14
Code for Creating a Singly Linked List
Alternative Way for Creating a Singly Linked List
■ Instead of statically declaring the structures n1, n2, n3,
□ Dynamically allocate space for the nodes
□ Use malloc individually for every node allocated
Algorithm for Creating a Singly Linked List
Algorithm: CREATE (HEAD, ITEM)
1. Create NEW node
a) Allocate memory for NEW node.
b) IF NEW = NULL then Print: “Memory not Available” and Return
c) Set NEW→DATA = ITEM
d) Set NEW→LINK = NULL
2. [Whether List is empty, head is the content of HEADER]
If HEAD = NULL then
Set HEAD = NEW
Else
a) Set Temp = HEAD
b) While Temp→LINK ≠ NULL do
Set Temp = Temp→LINK [End of while]

3. Set Temp→LINK = NEW [End of IF]


4. Return
Example: Creating Singly Linked List by Reading value from
Keyboard
C Implementation of Linked List // Function to add a new node to the end of the list
void create(Node** head, int item) {
#include <stdio.h> Node* newNode = createNode(item);
#include <stdlib.h> if (*head == NULL) {
*head = newNode;
// Define the structure for a linked list node } else {
typedef struct Node { Node* temp = *head;
int data; while (temp->link != NULL) {
struct Node* link; temp = temp->link;
} Node; }
temp->link = newNode;
// Function to create a new node }
Node* createNode(int item) { }
Node* newNode = (Node*) malloc(sizeof(Node));
if (newNode == NULL) { int main() {
printf("Memory not available\n"); Node* head = NULL;
return NULL; create(&head, 1); create(&head, 2); create(&head, 3);
} // Print the linked list
newNode->data = item; Node* temp = head;
newNode->link = NULL; while (temp != NULL) {
return newNode; printf("%d ", temp->data);
} temp = temp->link;
}
return 0; }
Printing All the elements of a Linked List
Algorithm (Inserting a node at the beginning of a linked list)

1. Declare head pointer and make it as NULL.

2. Create a new node with the given data.


And make the new node => next as NULL.
(Because the new node is going to be the last node.)

3. If the head node is NULL (Empty Linked


List), make the new node as the head.

4. If the head node is not NULL , (Linked list already has some
elements), find the last node.
make the last node => next as the new node.

23
Insertion at Front
Steps to insert node at the beginning of singly linked list

Step 1: Create a new node.


Insertion at Front
Step 2: Link the newly created node with the head node, i.e. the newNode will now
point to head node.

Step 3: Make the new node as the head node, i.e. now head node will point to newNode.
Insertion at front
/*Create a new node and insert at the beginning of the linked list.*/

void insertNodeAtBeginning(int data)


{
struct node *newNode;
newNode = (struct node*)malloc(sizeof(struct node));

if(newNode == NULL)
{
printf("Unable to allocate memory.");
}
else
{
newNode->data = data; //Links the data part
newNode->next = head; //Links the address part

head = newNode; //Makes newNode as first node

printf("DATA INSERTED SUCCESSFULLY\n");


}
}
Single Linked List: Insertion at End https://youtu.be/o3QSIpwbnWA

Steps to insert node at the end of Singly linked list


Step 1: Create a new node and make sure that the address part of the new node points to
NULL. i.e. newNode->next=NULL

Step 2: Traverse to the last node of the linked list and connect the last node of the list with the
new node, i.e. last node will now point to new node. (lastNode->next = newNode).
Insertion at End
/* Create a new node and insert at the end of the linked list. */
void insertNodeAtEnd(int data)
{
struct node *newNode, *temp;
newNode = (struct node*)malloc(sizeof(struct node));
if(newNode == NULL)
{
printf("Unable to allocate memory.");
}
else
{
newNode->data = data; //Links the data part
newNode->next = NULL;
temp = head;

while(temp->next != NULL) //Traverse to the last node


temp = temp->next;

temp->next = newNode; //Links the address part


printf("DATA INSERTED SUCCESSFULLY\n");
}
Single Linked List: Insertion at any Position
Steps to insert node at any position of Singly Linked List
Step 1: Create a new node.

Step 2: Traverse to the n-1th position of the linked list and connect the new node with the
n+1th node. (newNode->next = temp->next) where temp is the n-1th node.
Single Linked List: Insertion at any position
Step 3: Now at last connect the n-1th node with the new node i.e. the n-1th node will now
point to new node. (temp->next = newNode) where temp is the n-1th node.
Insertion at any Position
/* Create a new node and insert at middle of the linked list.*/

void insertNodeAtMiddle(int data, int position)


{
int i;
struct node *newNode, *temp;

newNode = (struct node*)malloc(sizeof(struct node));

if(newNode == NULL)
{
printf("Unable to allocate memory.");
}
else
{
newNode->data = data; //Links the data part
newNode->next = NULL;

temp = head;
Insertion at any Position
for(i=2; i<=position-1; i++) /* Traverse to the n-1 position */
{
temp = temp->next;

if(temp == NULL)
break;
}
if(temp != NULL)
{
/* Links the address part of new node */
newNode->next = temp->next;

/* Links the address part of n-1 node */


temp->next = newNode;

printf("DATA INSERTED SUCCESSFULLY\n");


}
else
{
printf("UNABLE TO INSERT DATA AT THE GIVEN POSITION\n");
}
}
}
Inserting node at the end of the list
Algorithm
1. Declare head pointer and make it as NULL.
2. Create a new node with the given data. And make the
new node => next as NULL.
(Because the new node is going to be the last node.)
3. If the head node is NULL (Empty Linked
List), make the new node as the head.
4. If the head node is not null, (Linked list already has
some elements),
find the last node.
Make the last node => next as the new node. 33
Linked List
Implementation
//declaring nodes
#include<stdio.h> struct node
#include<stdlib.h> *head,*middle,*last;
//allocating memory for each node
int main() head =
{ malloc(sizeof(struct node));
//node structure middle = malloc(sizeof(struct
struct node node)); last =
{ malloc(sizeof(struct
//assigning values to each node));
node
int regno; head->regno = 10;
char name[20]; head->name=” DSU”;
struct node *next; middle->regno = 20;
}; head->name =”DSE”;
; last->regno = 30;
head->name=”DSI”
ssor, Department of CSE, Dayananda Sagar
rsity, Harohalli, Karnataka. 23
//connecting each nodes.
head->middle->last headnext= middle;
middle->next = last;
last->next = NULL;
//temp is a reference for head pointer.
struct node *temp = head;
//till the node becomes null, printing each nodes data
while(temp != NULL)
{
printf("\n Regno: %d Name: %s => ",temp->regno,temp->na me );
temp = temp->next;
}
printf("NULL");
return 0;
}

35
Deleting a Node from a Singly Linked List
• There are four cases, which can occur while removing the node. These cases
are similar to the cases in add operation.

• Case 1: List has only one Node


- Disposes the node, pointed by head and sets head to NULL.

• Case 2: Remove first Node


- Update head link to point to
the node, next to the head
- Dispose removed node.
Deleting a Node from a Singly Linked List.....
• Case 3: Remove last Node

- Find the last node by traversing from the head.

- Set previous to last node address as NULL


Deleting a Node from a Singly Linked List.....
• Case 4: Remove at a Specific Position

- Update next link of the previous node, to point to the next node, relative to
the removed node.
#include<stdio.h> Code for Deleting Front and Last Node
struct Node
{
int data;
struct Node *next; void deleteEnd (struct Node **head)
}; {
struct Node *temp = *head;
void deleteStart (struct Node **head) struct Node *temp2;
{
struct Node *temp = *head; // if there are no nodes in Linked List can't delete
if (*head == NULL)
// if there are no nodes in Linked List can't delete {
if (*head == NULL) printf ("Linked List Empty, nothing to delete");
{ return;
printf ("Linked List Empty, nothing to delete"); }
return;
} // if Linked List has only 1 node
if (temp->next == NULL)
// move head to next node {
*head = (*head)->next; *head = NULL;
free (temp); return;
} }
// else traverse to the last node
while (temp->next != NULL)
{
// store previous link node as we need to change its next val
temp2 = temp;
temp = temp->next;
}
temp2->next = NULL;

free (temp);

}
Circular linked list
Circular list is a list in which the link field of the last node is
made to point to the start/first node of the list.

41
Circular Linked List
In a circular linked list, each node has a data element and a
pointer/reference to the next node in the sequence.

The last node in the list points back to the first node, and the
traversal of the list can continue indefinitely in a loop.

42
Insertion at the Beginning
• store the address of the current first node in the newNode (i.e. pointing
the newNode to the current first node)

• point the last node to newNode (i.e making


newNode as head) Insert at the beginning

43
Insertion at beginning in linked list the steps are followed

1. Make the linked list.

1. Take an extra pointer which points to the end node of


the circular linked list.

1. Then we have a pointer that is pointing to the end


node, then end node-> next will point to the first node.

1. At last follow the algorithm for insertion at beginning in


circular linked list given below
44
void insertStart (struct Node *head, int data)
{
struct Node *newNode = (struct Node *) malloc (sizeof (struct Node));
newNode->data = data;
// if its the first node being entered
if (*head == NULL)
{
*head = newNode;
(*head)->next = *head;
return;
}
45
// if LL already as >=1
node struct Node *curr = *head;
// traverse till last node in LL
while (curr->next != *head)
{
curr = curr->next;
}
// assign LL's last node's next as this new node
curr->next = newNode;
// assign newNode's next as current head
newNode->next = *head;
// change head to this new node
*head = newNode;
}
46
Insertion at the end

• store the address of the head node to next of newNode (making newNode
the last node)

• point the current last node to newNode make newNode as the last node

47
Insertion at end in the Circular Linked List
1.Make a new node.
2.Assign the new node next to circular list.
3.If the list is empty then return new node.
4.Assign the new node next to the front of the list.
5.Assign tail next to the new node.
6.Return the end node of the circular linked list.
48
void insertLast (struct Node **head, int data)
{
struct Node *newNode = (struct Node *) malloc (sizeof (struct
Node));
newNode->data = data;
// if LL already as >=1 node
// if its the first node being struct Node *curr = *head;
entered
// traverse till last node in LL
if (*head == NULL)
while (curr->next != *head)
{
*head = newNode;
{
(*head)->next = curr = curr->next;
*head; return; }
} // assign LL's current last node's next as
this new node
curr->next = newNode;
// assign this new node's next as current
head of LL
newNode->next = *head;
}
49
Insertion in between two nodes

• Let's insert newNode after the first node. travel to the node given
(let this node be p)

• point the next of newNode to the node next to p store the


address of newNode at next of p

50
Insertion in between the nodes in linked list the steps are followed
:-
1.Make a new node and set the data.
2.Move to pos-1 position in the circular linked list.
3. Now link the next pointer of new node with the node
pointed by the next pointer of current(pos-1) node.
4. After that join the next pointer of current node with the
newly created node which means that the next pointer of
current node will point to new node.
5.Now print the linked list.
6.Learn algorithm given below to understand better.
51
void insertPosition (int data, int pos, struct Node
**head)
//function to insert element at specific position
{
struct Node *newnode, *curNode;
int i;
if (*head == NULL) else
{ {
printf ("List is empty"); newnode = (struct Node *) malloc (sizeof (struct
} Node)); newnode->data = data;
if (pos == 1) curNode = *head;
{ while (--pos > 1)
insertStart (head, {
data); return; curNode = curNode->next;
} }
newnode->next = curNode->next;
curNode->next = newnode;
}
}

52
Doubly Linked List
• Doubly linked list is a collection of nodes linked together in a sequential way.
• Doubly linked list is almost similar to singly linked list except it contains two
address or reference fields, where one of the address field contains reference
of the next node and other contains reference of the previous node.
• First and last node of a linked list contains a terminator generally a NULL
value, that determines the start and end of the list.
• Doubly linked list is sometimes also referred as bi-directional linked list since
it allows traversal of nodes in both direction.
• Since doubly linked list allows the traversal of nodes in both direction, we can
keep track of both first and last nodes.
Operations on Doubly Linked List

• Inserting or Deleting a Node in DLL


• Traversal in Doubly Linked List
• Searching in Doubly Linked List
• Finding Length of Doubly Linked List
Traversal in Doubly Linked List
To Traverse the doubly list, we can use the following steps:
a. Forward Traversal:
- Initialize a pointer to the head of the linked list.
- While the pointer is not null:
- Visit the data at the current node.
- Move the pointer to the next node.
b. Backward Traversal:
- Initialize a pointer to the tail of the linked list.
- While the pointer is not null:
- Visit the data at the current node.
- Move the pointer to the previous node.
Insertion at the Beginning in DLL

• Create a new node, say new_node with the given data and set its previous
pointer to null, new_node->prev = NULL.
• Set the next pointer of new_node to current head, new_node->next = head.
• If the linked list is not empty, update the previous pointer of the current head to
new_node, head->prev = new_node.
• Return new_node as the head of the updated linked list.
Insertion at the End of DLL

• Allocate memory for a new node and assign the provided value to its data field.
• Initialize the next pointer of the new node to nullptr.
• If the list is empty:
- Set the previous pointer of the new node to nullptr.
- Update the head pointer to point to the new node.
• If the list is not empty:
- Traverse the list starting from the head to reach the last node.
- Set the next pointer of the last node to point to the new node.
- Set the previous pointer of the new node to point to the last node.
Double Linked List: Insertion at any Position
Steps to insert a new node at nth position in a Doubly linked list.
Step 1: Traverse to N-1 node in the list, where N is the position to insert. Say temp now
points to N-1th node.

Step 2: Create a newNode that is to be inserted and assign some data to its data field.
Doubly Linked List: Insertion at any Position
Step 3: Connect the next address field of newNode with the node pointed by next
address field of temp node.

Step 4: Connect the previous address field of newNode with the temp node.
Doubly Linked List: Insertion at any Position
Step 5: Check if temp.next is not NULL then, connect the previous address field of node
pointed by temp.next to newNode.

Step 6: Connect the next address field of temp node to newNode.


Doubly Linked List: Insertion at any Position

Step 7: Final doubly linked list looks like


Doubly Linked List: Insertion at any Position
#include <stdio.h>
#include <stdlib.h>

struct node { /* Basic structure of Node */


int data;
struct node * prev;
struct node * next;
}*head, *last;

int main()
{
int n, data;
head = NULL;
last = NULL;

printf("Enter the total number of nodes in list: ");


scanf("%d", &n);
createList(n); // function to create double linked list
displayList(); // function to display the list

printf("Enter the position and data to insert new node: ");


scanf("%d %d", &n, &data);
insert_position(data, n); // function to insert node at any position
displayList();
return 0;
}
Doubly Linked List: Insertion at any Position
void createList(int n)
{
int i, data;
struct node *newNode;
if(n >= 1){ /* Creates and links the head node */
head = (struct node *)malloc(sizeof(struct node));
printf("Enter data of 1 node: ");
scanf("%d", &data);
head->data = data;
head->prev = NULL;
head->next = NULL;

last = head;

for(i=2; i<=n; i++){ /* Creates and links rest of the n-1 nodes */
newNode = (struct node *)malloc(sizeof(struct node));
printf("Enter data of %d node: ", i);
scanf("%d", &data);

newNode->data = data;
newNode->prev = last; //Links new node with the previous node
newNode->next = NULL;

last->next = newNode; //Links previous node with the new node


last = newNode; //Makes new node as last/previous node
}
printf("\nDOUBLY LINKED LIST CREATED SUCCESSFULLY\n");
}
}
Doubly Linked List: Insertion at any Position
void insert_position(int data, int position)
{
struct node * newNode, *temp;
if(head == NULL){
printf("Error, List is empty!\n");
}
else{
temp = head;
if(temp!=NULL){
newNode = (struct node *)malloc(sizeof(struct node));

newNode->data = data;
newNode->next = temp->next; //Connects new node with n+1th node
newNode->prev = temp; //Connects new node with n-1th node

if(temp->next != NULL)
{
temp->next->prev = newNode; /* Connects n+1th node with new node */
}
temp->next = newNode; /* Connects n-1th node with new node */
printf("NODE INSERTED SUCCESSFULLY AT %d POSITION\n", position);
}
else{
printf("Error, Invalid position\n");
}
}
}
Doubly Linked List: Insertion at any Position
void displayList()
{
struct node * temp;
int n = 1;

if(head == NULL)
{
printf("List is empty.\n");
}
else
{
temp = head;
printf("DATA IN THE LIST:\n");

while(temp != NULL)
{
printf("DATA of %d node = %d\n", n, temp->data);
n++;

/* Moves the current pointer to next node */


temp = temp->next;
}
}
}
Applications of linked list in computer science

• Implementation of stacks and queues


• Implementation of graphs: Adjacency list representation of graphs
is the most popular which uses a linked list to store adjacent
vertices.
• Dynamic memory allocation: We use a linked list of free blocks.
• Maintaining a directory of names
• Performing arithmetic operations on long integers
• Manipulation of polynomials by storing constants in the node of the
linked list
• Representing sparse matrices
Implementation of Stack using Linked List

Linked List Stack Visualization (usfca.edu)

Linked List (Single, Doubly), Stack, Queue, Deque – VisuAlgo


Case Study: Josephus problem

• There are N people standing in a circle waiting to be executed.


• The counting out begins at some point in the circle and
proceeds around the circle in a fixed direction. In each step, a
certain number of people are skipped and the next person is
executed.
• The elimination proceeds around the circle (which is becoming
smaller and smaller as the executed people are removed),
until only the last person remains, who is given freedom.
• Given the total number of persons N and a number k which
indicates that k-1 persons are skipped and the kth person is
killed in a circle. The task is to choose the person in the initial
circle that survives.

You might also like