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

Data Structure and Algorithms

The document provides an overview of linked lists, which are collections of nodes that can store different data types and have no predefined size. It explains the types of linked lists (singly, doubly, and circular), basic operations (insertion, deletion, searching), and includes algorithms and examples for various operations. Additionally, it covers the process of reversing a linked list.

Uploaded by

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

Data Structure and Algorithms

The document provides an overview of linked lists, which are collections of nodes that can store different data types and have no predefined size. It explains the types of linked lists (singly, doubly, and circular), basic operations (insertion, deletion, searching), and includes algorithms and examples for various operations. Additionally, it covers the process of reversing a linked list.

Uploaded by

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

Data Structure and Algorithms - Linked List

If arrays accommodate similar types of data types, linked lists consist of elements with different data
types that are also arranged sequentially.

But how are these linked lists created?

A linked list is a collection of “nodes” connected together via links. These nodes consist of the data to be
stored and a pointer to the address of the next node within the linked list. In the case of arrays, the size is
limited to the definition, but in linked lists, there is no defined size. Any amount of data can be stored in it
and can be deleted from it.

There are three types of linked lists −

• Singly Linked List − The nodes only point to the address of the next node in the list.
• Doubly Linked List − The nodes point to the addresses of both previous and next nodes.
• Circular Linked List − The last node in the list will point to the first node in the list. It can
either be singly linked or doubly linked.

Linked List Representation


Linked list can be visualized as a chain of nodes, where every node points to the next node.

As per the above illustration, following are the important points to be considered.

• Linked List contains a link element called first (head).


• Each link carries a data field(s) and a link field called next.
• Each link is linked with its next link using its next link.
• Last link carries a link as null to mark the end of the list.
Types of Linked List
Following are the various types of linked list.

Singly Linked Lists


Singly linked lists contain two “buckets” in one node; one bucket holds the data and the other bucket holds
the address of the next node of the list. Traversals can be done in one direction only as there is only a
single link between two nodes of the same list.

Doubly Linked Lists


Doubly Linked Lists contain three “buckets” in one node; one bucket holds the data and the other buckets
hold the addresses of the previous and next nodes in the list. The list is traversed twice as the nodes in
the list are connected to each other from both sides.

Circular Linked Lists


Circular linked lists can exist in both singly linked list and doubly linked list.

Since the last node and the first node of the circular linked list are connected, the traversal in this linked
list will go on forever until it is broken.

Basic Operations in the Linked Lists


The basic operations in the linked lists are insertion, deletion, searching, display, and deleting an element
at a given key. These operations are performed on Singly Linked Lists as given below −

• Insertion − Adds an element at the beginning of the list.


• Deletion − Deletes an element at the beginning of the list.
• Display − Displays the complete list.
• Search − Searches an element using the given key.
• Delete − Deletes an element using the given key.

Insertion Operation
Adding a new node in linked list is a more than one step activity. We shall learn this with diagrams here.
First, create a node using the same structure and find the location where it has to be inserted.

Imagine that we are inserting a node B (NewNode), between A (LeftNode) and C (RightNode). Then point
B.next to C −
NewNode.next −> RightNode;
It should look like this −

Now, the next node at the left should point to the new node.
LeftNode.next −> NewNode;

This will put the new node in the middle of the two. The new list should look like this −

Insertion in linked list can be done in three different ways. They are explained as follows −

Insertion at Beginning
In this operation, we are adding an element at the beginning of the list.
n this operation, we are adding an element at the beginning of the list.

Algorithm
1. START
2. Create a node to store the data
3. Check if the list is empty
4. If the list is empty, add the data to the node and assign the head pointer to it.
5 If the list is not empty, add the data to a node and link to the current head. Assign the head to the newly added
node.
6. END
Example
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *head = NULL;
struct node *current = NULL;

// display the list


void printList(){
struct node *p = head;
printf("\n[");

//start from the beginning


while(p != NULL) {
printf(" %d ",p->data);
p = p->next;
}
printf("]");
}

//insertion at the beginning


void insertatbegin(int data){

//create a link
struct node *lk = (struct node*) malloc(sizeof(struct node));
lk->data = data;

// point it to old first node


lk->next = head;

//point first to new first node


head = lk;
}
void main(){
int k=0;
insertatbegin(12);
insertatbegin(22);
insertatbegin(30);
insertatbegin(44);
insertatbegin(50);
printf("Linked List: ");

// print list
printList();
}
Output
Linked List:
[ 50 44 30 22 12 ]
Insertion at Ending
In this operation, we are adding an element at the ending of the list.

Algorithm
1. START
2. Create a new node and assign the data
3. Find the last node
4. Point the last node to new node
5. END
Example
Following are the implementations of this operation in various programming languages
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *head = NULL;
struct node *current = NULL;

// display the list


void printList(){
struct node *p = head;
printf("\n[");

//start from the beginning


while(p != NULL) {
printf(" %d ",p->data);
p = p->next;
}
printf("]");
}

//insertion at the beginning


void insertatbegin(int data){

//create a link
struct node *lk = (struct node*) malloc(sizeof(struct node));
lk->data = data;

// point it to old first node


lk->next = head;

//point first to new first node


head = lk;
}
void insertatend(int data){

//create a link
struct node *lk = (struct node*) malloc(sizeof(struct node));
lk->data = data;
struct node *linkedlist = head;
// point it to old first node
while(linkedlist->next != NULL)
linkedlist = linkedlist->next;

//point first to new first node


linkedlist->next = lk;
}
void main(){
int k=0;
insertatbegin(12);
insertatend(22);
insertatend(30);
insertatend(44);
insertatend(50);
printf("Linked List: ");

// print list
printList();
}

Output
Linked List:
[ 12 22 30 44 50 ]
Insertion at a Given Position
In this operation, we are adding an element at any position within the list.

Algorithm
1. START
2. Create a new node and assign data to it
3. Iterate until the node at position is found
4. Point first to new first node
5. END
Example
Following are the implementations of this operation in various programming languages
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *head = NULL;
struct node *current = NULL;

// display the list


void printList(){
struct node *p = head;
printf("\n[");

//start from the beginning


while(p != NULL) {
printf(" %d ",p->data);
p = p->next;
}
printf("]");
}

//insertion at the beginning


void insertatbegin(int data){

//create a link
struct node *lk = (struct node*) malloc(sizeof(struct node));
lk->data = data;

// point it to old first node


lk->next = head;

//point first to new first node


head = lk;
}
void insertafternode(struct node *list, int data){
struct node *lk = (struct node*) malloc(sizeof(struct node));
lk->data = data;
lk->next = list->next;
list->next = lk;
}
void main(){
int k=0;
insertatbegin(12);
insertatbegin(22);
insertafternode(head->next, 30);
printf("Linked List: ");

// print list
printList();
}

Output
Linked List:
[ 22 12 30 ]
Deletion Operation
Deletion is also a more than one step process. We shall learn with pictorial representation. First, locate
the target node to be removed, by using searching algorithms.

The left (previous) node of the target node now should point to the next node of the target node −
LeftNode.next −> TargetNode.next;
This will remove the link that was pointing to the target node. Now, using the following code, we will
remove what the target node is pointing at.
TargetNode.next −> NULL;

We need to use the deleted node. We can keep that in memory otherwise we can simply deallocate
memory and wipe off the target node completely.

Similar steps should be taken if the node is being inserted at the beginning of the list. While inserting it
at the end, the second last node of the list should point to the new node and the new node will point to
NULL.

Deletion in linked lists is also performed in three different ways. They are as follows −

Deletion at Beginning
In this deletion operation of the linked, we are deleting an element from the beginning of the list. For this,
we point the head to the second node.

Algorithm
1. START
2. Assign the head pointer to the next node in the list
3. END
Example
Following are the implementations of this operation in various programming languages
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *head = NULL;
struct node *current = NULL;

// display the list


void printList(){
struct node *p = head;
printf("\n[");

//start from the beginning


while(p != NULL) {
printf(" %d ",p->data);
p = p->next;
}
printf("]");
}

//insertion at the beginning


void insertatbegin(int data){

//create a link
struct node *lk = (struct node*) malloc(sizeof(struct node));
lk->data = data;

// point it to old first node


lk->next = head;

//point first to new first node


head = lk;
}
void deleteatbegin(){
head = head->next;
}
void main(){
int k=0;
insertatbegin(12);
insertatbegin(22);
insertatbegin(30);
insertatbegin(40);
insertatbegin(55);
printf("Linked List: ");

// print list
printList();
deleteatbegin();
printf("\nLinked List after deletion: ");

// print list
printList();
}

Output
Linked List:
[ 55 40 30 22 12 ]
Linked List after deletion:
[ 40 30 22 12 ]
Deletion at Ending
In this deletion operation of the linked, we are deleting an element from the ending of the list.

Algorithm
1. START
2. Iterate until you find the second last element in the list.
3. Assign NULL to the second last element in the list.
4. END
Example
Following are the implementations of this operation in various programming languages −
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *head = NULL;
struct node *current = NULL;

// display the list


void printList(){
struct node *p = head;
printf("\n[");

//start from the beginning


while(p != NULL) {
printf(" %d ",p->data);
p = p->next;
}
printf("]");
}

//insertion at the beginning


void insertatbegin(int data){

//create a link
struct node *lk = (struct node*) malloc(sizeof(struct node));
lk->data = data;

// point it to old first node


lk->next = head;

//point first to new first node


head = lk;
}
void deleteatend(){
struct node *linkedlist = head;
while (linkedlist->next->next != NULL)
linkedlist = linkedlist->next;
linkedlist->next = NULL;
}
void main(){
int k=0;
insertatbegin(12);
insertatbegin(22);
insertatbegin(30);
insertatbegin(40);
insertatbegin(55);
printf("Linked List: ");

// print list
printList();
deleteatend();
printf("\nLinked List after deletion: ");

// print list
printList();
}

Output
Linked List:
[ 55 40 30 22 12 ]
Linked List after deletion:
[ 55 40 30 22 ]
Deletion at a Given Position
In this deletion operation of the linked, we are deleting an element at any position of the list.

Algorithm
1. START
2. Iterate until find the current node at position in the list
3. Assign the adjacent node of current node in the list to its previous node.
4. END
Example
Following are the implementations of this operation in various programming languages −
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *head = NULL;
struct node *current = NULL;

// display the list


void printList(){
struct node *p = head;
printf("\n[");

//start from the beginning


while(p != NULL) {
printf(" %d ",p->data);
p = p->next;
}
printf("]");
}

//insertion at the beginning


void insertatbegin(int data){

//create a link
struct node *lk = (struct node*) malloc(sizeof(struct node));
lk->data = data;

// point it to old first node


lk->next = head;

//point first to new first node


head = lk;
}
void deletenode(int key){
struct node *temp = head, *prev;
if (temp != NULL && temp->data == key) {
head = temp->next;
return;
}

// Find the key to be deleted


while (temp != NULL && temp->data != key) {
prev = temp;
temp = temp->next;
}

// If the key is not present


if (temp == NULL) return;

// Remove the node


prev->next = temp->next;
}
void main(){
int k=0;
insertatbegin(12);
insertatbegin(22);
insertatbegin(30);
insertatbegin(40);
insertatbegin(55);
printf("Linked List: ");

// print list
printList();
deletenode(30);
printf("\nLinked List after deletion: ");

// print list
printList();
}

Output
Linked List:
[ 55 40 30 22 12 ]
Linked List after deletion:
[ 55 40 22 12 ]

Reverse Operation
This operation is a thorough one. We need to make the last node to be pointed by the head node and
reverse the whole linked list.
First, we traverse to the end of the list. It should be pointing to NULL. Now, we shall make it point to its
previous node −

We have to make sure that the last node is not the last node. So we'll have some temp node, which looks
like the head node pointing to the last node. Now, we shall make all left side nodes point to their previous
nodes one by one.

Except the node (first node) pointed by the head node, all nodes should point to their predecessor, making
them their new successor. The first node will point to NULL.

We'll make the head node point to the new first node by using the temp node.

Algorithm
Step by step process to reverse a linked list is as follows −
1 START
2. We use three pointers to perform the reversing: prev, next, head.
3. Point the current node to head and assign its next value to the prev node.
4. Iteratively repeat the step 3 for all the nodes in the list.
5. Assign head to the prev node.
Example
Following are the implementations of this operation in various programming languages
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *head = NULL;
struct node *current = NULL;

// display the list


void printList(){
struct node *p = head;
printf("\n[");

//start from the beginning


while(p != NULL) {
printf(" %d ",p->data);
p = p->next;
}
printf("]");
}

//insertion at the beginning


void insertatbegin(int data){

//create a link
struct node *lk = (struct node*) malloc(sizeof(struct node));
lk->data = data;

// point it to old first node


lk->next = head;

//point first to new first node


head = lk;
}
void reverseList(struct node** head){
struct node *prev = NULL, *cur=*head, *tmp;
while(cur!= NULL) {
tmp = cur->next;
cur->next = prev;
prev = cur;
cur = tmp;
}
*head = prev;
}
void main(){
int k=0;
insertatbegin(12);
insertatbegin(22);
insertatbegin(30);
insertatbegin(40);
insertatbegin(55);
printf("Linked List: ");

// print list
printList();
reverseList(&head);
printf("\nReversed Linked List: ");
printList();
}

Output
Linked List:
[ 55 40 30 22 12 ]
Reversed Linked List:
[ 12 22 30 40 55 ]

Search Operation
Searching for an element in the list using a key element. This operation is done in the same way as array
search; comparing every element in the list with the key element given.

Algorithm
1 START
2 If the list is not empty, iteratively check if the list contains the key
3 If the key element is not present in the list, unsuccessful search
4 END
Example
Following are the implementations of this operation in various programming languages
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *head = NULL;
struct node *current = NULL;

// display the list


void printList(){
struct node *p = head;
printf("\n[");

//start from the beginning


while(p != NULL) {
printf(" %d ",p->data);
p = p->next;
}
printf("]");
}

//insertion at the beginning


void insertatbegin(int data){

//create a link
struct node *lk = (struct node*) malloc(sizeof(struct node));
lk->data = data;

// point it to old first node


lk->next = head;

//point first to new first node


head = lk;
}
int searchlist(int key){
struct node *temp = head;
while(temp != NULL) {
if (temp->data == key) {
return 1;
}
temp=temp->next;
}
return 0;
}
void main(){
int k=0;
insertatbegin(12);
insertatbegin(22);
insertatbegin(30);
insertatbegin(40);
insertatbegin(55);
printf("Linked List: ");

// print list
printList();
k = searchlist(30);
if (k == 1)
printf("\nElement is found");
else
printf("\nElement is not present in the list");
}

Output
Linked List:
[ 55 40 30 22 12 ]
Element is found

Traversal Operation
The traversal operation walks through all the elements of the list in an order and displays the elements
in that order.

Algorithm
1. START
2. While the list is not empty and did not reach the end of the list, print the data in each node
3. END
Example
Following are the implementations of this operation in various programming languages
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *head = NULL;
struct node *current = NULL;

// display the list


void printList(){
struct node *p = head;
printf("\n[");

//start from the beginning


while(p != NULL) {
printf(" %d ",p->data);
p = p->next;
}
printf("]");
}

//insertion at the beginning


void insertatbegin(int data){

//create a link
struct node *lk = (struct node*) malloc(sizeof(struct node));
lk->data = data;

// point it to old first node


lk->next = head;

//point first to new first node


head = lk;
}
void main(){
int k=0;
insertatbegin(12);
insertatbegin(22);
insertatbegin(30);
printf("Linked List: ");

// print list
printList();
}

Output
Linked List:
[ 30 22 12 ]
Data Structure Doubly Linked List
Doubly Linked List is a variation of Linked list in which navigation is possible in both ways, either forward
and backward easily as compared to Single Linked List. Following are the important terms to understand
the concept of doubly linked list.

• Link − Each link of a linked list can store a data called an element.
• Next − Each link of a linked list contains a link to the next link called Next.
• Prev − Each link of a linked list contains a link to the previous link called Prev.
• Linked List − A Linked List contains the connection link to the first link called First and to
the last link called Last.

Doubly Linked List Representation

As per the above illustration, following are the important points to be considered.

• Doubly Linked List contains a link element called first and last.
• Each link carries a data field(s) and a link field called next.
• Each link is linked with its next link using its next link.
• Each link is linked with its previous link using its previous link.
• The last link carries a link as null to mark the end of the list.

Basic Operations
Following are the basic operations supported by a list.

• Insertion − Adds an element at the beginning of the list.


• Deletion − Deletes an element at the beginning of the list.
• Insert Last − Adds an element at the end of the list.
• Delete Last − Deletes an element from the end of the list.
• Insert After − Adds an element after an item of the list.
• Delete − Deletes an element from the list using the key.
• Display forward − Displays the complete list in a forward manner.
• Display backward − Displays the complete list in a backward manner.
Insertion at the Beginning
In this operation, we create a new node with three compartments, one containing the data, the others
containing the address of its previous and next nodes in the list. This new node is inserted at the beginning
of the list.

Algorithm
1. START
2. Create a new node with three variables: prev, data, next.
3. Store the new data in the data variable
4. If the list is empty, make the new node as head.
5. Otherwise, link the address of the existing first node to the next variable of the new node, and assign null to the
prev variable.
6. Point the head to the new node.
7. END
Example
Following are the implementations of this operation in various programming languages −
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
struct node {
int data;
int key;
struct node *next;
struct node *prev;
};

//this link always point to first Link


struct node *head = NULL;

//this link always point to last Link


struct node *last = NULL;
struct node *current = NULL;

//is list empty


bool isEmpty(){
return head == NULL;
}

//display the doubly linked list


void printList(){
struct node *ptr = head;
while(ptr != NULL) {
printf("(%d,%d) ",ptr->key,ptr->data);
ptr = ptr->next;
}
}

//insert link at the first location


void insertFirst(int key, int data){

//create a link
struct node *link = (struct node*) malloc(sizeof(struct node));
link->key = key;
link->data = data;
if(isEmpty()) {

//make it the last link


last = link;
} else {

//update first prev link


head->prev = link;
}

//point it to old first link


link->next = head;
//point first to new first link
head = link;
}
void main(){
insertFirst(1,10);
insertFirst(2,20);
insertFirst(3,30);
insertFirst(4,1);
insertFirst(5,40);
insertFirst(6,56);
printf("\nDoubly Linked List: ");
printList();
}

Output
Doubly Linked List: (6,56) (5,40) (4,1) (3,30) (2,20) (1,10)
Deletion at the Beginning
This deletion operation deletes the existing first nodes in the doubly linked list. The head is shifted to the
next node and the link is removed.

Algorithm
1. START
2. Check the status of the doubly linked list
3. If the list is empty, deletion is not possible
4. If the list is not empty, the head pointer is shifted to the next node.
5. END
Example
Following are the implementations of this operation in various programming languages −
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
struct node {
int data;
int key;
struct node *next;
struct node *prev;
};

//this link always point to first Link


struct node *head = NULL;

//this link always point to last Link


struct node *last = NULL;
struct node *current = NULL;

//is list empty


bool isEmpty(){
return head == NULL;
}

//display the doubly linked list


void printList(){
struct node *ptr = head;
while(ptr != NULL) {
printf("(%d,%d) ",ptr->key,ptr->data);
ptr = ptr->next;
}
}

//insert link at the first location


void insertFirst(int key, int data){

//create a link
struct node *link = (struct node*) malloc(sizeof(struct node));
link->key = key;
link->data = data;
if(isEmpty()) {

//make it the last link


last = link;
} else {

//update first prev link


head->prev = link;
}

//point it to old first link


link->next = head;

//point first to new first link


head = link;
}

//delete first item


struct node* deleteFirst(){

//save reference to first link


struct node *tempLink = head;

//if only one link


if(head->next == NULL) {
last = NULL;
} else {
head->next->prev = NULL;
}
head = head->next;

//return the deleted link


return tempLink;
}
void main(){
insertFirst(1,10);
insertFirst(2,20);
insertFirst(3,30);
insertFirst(4,1);
insertFirst(5,40);
insertFirst(6,56);
printf("\nDoubly Linked List: ");
printList();
printf("\nList after deleting first record: ");
deleteFirst();
printList();
}
Output
Doubly Linked List: (6,56) (5,40) (4,1) (3,30) (2,20) (1,10)
List after deleting first record: (5,40) (4,1) (3,30) (2,20) (1,10)
Insertion at the End
In this insertion operation, the new input node is added at the end of the doubly linked list; if the list is not
empty. The head will be pointed to the new node, if the list is empty.

Algorithm
1. START
2. If the list is empty, add the node to the list and point the head to it.
3. If the list is not empty, find the last node of the list.
4. Create a link between the last node in the list and the new node.
5. The new node will point to NULL as it is the new last node.
6. END
Example
Following are the implementations of this operation in various programming languages −
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
struct node {
int data;
int key;
struct node *next;
struct node *prev;
};

//this link always point to first Link


struct node *head = NULL;

//this link always point to last Link


struct node *last = NULL;
struct node *current = NULL;

//is list empty


bool isEmpty(){
return head == NULL;
}

//display the doubly linked list


void printList(){
struct node *ptr = head;
while(ptr != NULL) {
printf("(%d,%d) ",ptr->key,ptr->data);
ptr = ptr->next;
}
}

//insert link at the first location


void insertFirst(int key, int data){

//create a link
struct node *link = (struct node*) malloc(sizeof(struct node));
link->key = key;
link->data = data;
if(isEmpty()) {

//make it the last link


last = link;
} else {

//update first prev link


head->prev = link;
}

//point it to old first link


link->next = head;

//point first to new first link


head = link;
}

//insert link at the last location


void insertLast(int key, int data){

//create a link
struct node *link = (struct node*) malloc(sizeof(struct node));
link->key = key;
link->data = data;
if(isEmpty()) {

//make it the last link


last = link;
} else {

//make link a new last link


last->next = link;

//mark old last node as prev of new link


link->prev = last;
}

//point last to new last node


last = link;
}
void main(){
insertFirst(1,10);
insertFirst(2,20);
insertFirst(3,30);
insertFirst(4,1);
insertLast(5,40);
insertLast(6,56);
printf("\nDoubly Linked List: ");
printList();
}

Output
Doubly Linked List: (4,1) (3,30) (2,20) (1,10) (5,40) (6,56)
Data Structure - Circular Linked List
Circular Linked List is a variation of Linked list in which the first element points to the last element and
the last element points to the first element. Both Singly Linked List and Doubly Linked List can be made
into a circular linked list.

Singly Linked List as Circular


In singly linked list, the next pointer of the last node points to the first node.

Doubly Linked List as Circular


In doubly linked list, the next pointer of the last node points to the first node and the previous pointer of
the first node points to the last node making the circular in both directions.

As per the above illustration, following are the important points to be considered.

• The last link's next points to the first link of the list in both cases of singly as well as doubly
linked list.
• The first link's previous points to the last of the list in case of doubly linked list.

Basic Operations
Following are the important operations supported by a circular list.

• insert − Inserts an element at the start of the list.


• delete − Deletes an element from the start of the list.
• display − Displays the list.
Insertion Operation
The insertion operation of a circular linked list only inserts the element at the start of the list. This differs
from the usual singly and doubly linked lists as there is no particular starting and ending points in this list.
The insertion is done either at the start or after a particular node (or a given position) in the list.

Algorithm
1. START
2. Check if the list is empty
3. If the list is empty, add the node and point the head to this node
4. If the list is not empty, link the existing head as the next node to the new node.
5. Make the new node as the new head.
6. END
Example
Following are the implementations of this operation in various programming languages −
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
struct node {
int data;
int key;
struct node *next;
};
struct node *head = NULL;
struct node *current = NULL;
bool isEmpty(){
return head == NULL;
}

//insert link at the first location


void insertFirst(int key, int data){

//create a link
struct node *link = (struct node*) malloc(sizeof(struct node));
link->key = key;
link->data = data;
if (isEmpty()) {
head = link;
head->next = head;
} else {

//point it to old first node


link->next = head;

//point first to new first node


head = link;
}
}

//display the list


void printList(){
struct node *ptr = head;
printf("\n[ ");

//start from the beginning


if(head != NULL) {
while(ptr->next != ptr) {
printf("(%d,%d) ",ptr->key,ptr->data);
ptr = ptr->next;
}
}
printf(" ]");
}
void main(){
insertFirst(1,10);
insertFirst(2,20);
insertFirst(3,30);
insertFirst(4,1);
insertFirst(5,40);
insertFirst(6,56);
printf("Circular Linked List: ");

//print list
printList();
}

Output
Circular Linked List:
[ (6,56) (5,40) (4,1) (3,30) (2,20) ]
Deletion Operation
The Deletion operation in a Circular linked list removes a certain node from the list. The deletion operation
in this type of lists can be done at the beginning, or a given position, or at the ending.

Algorithm
1. START
2. If the list is empty, then the program is returned.
3. If the list is not empty, we traverse the list using a current pointer that is set to the head pointer and create
another pointer previous that points to the last node.
4. Suppose the list has only one node, the node is deleted by setting the head pointer to NULL.
5. If the list has more than one node and the first node is to be deleted, the head is set to the next node and the
previous is linked to the new head.
6. If the node to be deleted is the last node, link the preceding node of the last node to head node.
7. If the node is neither first nor last, remove the node by linking its preceding node to its succeeding node.
8. END
Example
Following are the implementations of this operation in various programming languages −
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
struct node {
int data;
int key;
struct node *next;
};
struct node *head = NULL;
struct node *current = NULL;
bool isEmpty(){
return head == NULL;
}

//insert link at the first location


void insertFirst(int key, int data){

//create a link
struct node *link = (struct node*) malloc(sizeof(struct node));
link->key = key;
link->data = data;
if (isEmpty()) {
head = link;
head->next = head;
} else {

//point it to old first node


link->next = head;
//point first to new first node
head = link;
}
}

//delete first item


struct node * deleteFirst(){

//save reference to first link


struct node *tempLink = head;
if(head->next == head) {
head = NULL;
return tempLink;
}

//mark next to first link as first


head = head->next;

//return the deleted link


return tempLink;
}

//display the list


void printList(){
struct node *ptr = head;

//start from the beginning


if(head != NULL) {
while(ptr->next != ptr) {
printf("(%d,%d) ",ptr->key,ptr->data);
ptr = ptr->next;
}
}
}
void main(){
insertFirst(1,10);
insertFirst(2,20);
insertFirst(3,30);
insertFirst(4,1);
insertFirst(5,40);
insertFirst(6,56);
printf("Circular Linked List: ");

//print list
printList();
deleteFirst();
printf("\nList after deleting the first item: ");
printList();
}

Output
Circular Linked List: (6,56) (5,40) (4,1) (3,30) (2,20)
List after deleting the first item: (5,40) (4,1) (3,30) (2,20)
Display List Operation
The Display List operation visits every node in the list and prints them all in the output.

Algorithm
1. START
2. Walk through all the nodes of the list and print them
3. END
Example
Following are the implementations of this operation in various programming languages −
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
struct node {
int data;
int key;
struct node *next;
};
struct node *head = NULL;
struct node *current = NULL;
bool isEmpty(){
return head == NULL;
}

//insert link at the first location


void insertFirst(int key, int data){

//create a link
struct node *link = (struct node*) malloc(sizeof(struct node));
link->key = key;
link->data = data;
if (isEmpty()) {
head = link;
head->next = head;
} else {

//point it to old first node


link->next = head;

//point first to new first node


head = link;
}
}

//display the list


void printList(){
struct node *ptr = head;
printf("\n[ ");

//start from the beginning


if(head != NULL) {
while(ptr->next != ptr) {
printf("(%d,%d) ",ptr->key,ptr->data);
ptr = ptr->next;
}
}
printf(" ]");
}
void main(){
insertFirst(1,10);
insertFirst(2,20);
insertFirst(3,30);
insertFirst(4,1);
insertFirst(5,40);
insertFirst(6,56);
printf("Circular Linked List: ");

//print list
printList();
}

Output
Circular Linked List:
[ (6,56) (5,40) (4,1) (3,30) (2,20) ]
Data Structure and Algorithms - Stack
A stack is an Abstract Data Type (ADT), that is popularly used in most programming languages. It is
named stack because it has the similar operations as the real-world stacks, for example – a pack of cards
or a pile of plates, etc.

The stack follows the LIFO (Last in - First out) structure where the last element inserted would be the first
element deleted.

Stack Representation
A Stack ADT allows all data operations at one end only. At any given time, we can only access the top
element of a stack.

The following diagram depicts a stack and its operations −

A stack can be implemented by means of Array, Structure, Pointer, and Linked List. Stack can either be a
fixed size one or it may have a sense of dynamic resizing. Here, we are going to implement stack using
arrays, which makes it a fixed size stack implementation.

Basic Operations on Stacks


Stack operations usually are performed for initialization, usage and, de-initialization of the stack ADT.
The most fundamental operations in the stack ADT include: push(), pop(), peek(), isFull(), isEmpty(). These
are all built-in operations to carry out data manipulation and to check the status of the stack.

Stack uses pointers that always point to the topmost element within the stack, hence called as
the top pointer.

Insertion: push()
push() is an operation that inserts elements into the stack. The following is an algorithm that describes
the push() operation in a simpler way.

Algorithm
1 − Checks if the stack is full.
2 − If the stack is full, produces an error and exit.
3 − If the stack is not full, increments top to point next empty space.
4 − Adds data element to the stack location, where top is pointing.
5 − Returns success.
Example
Following are the implementations of this operation in various programming languages −
#include <stdio.h>
int MAXSIZE = 8;
int stack[8];
int top = -1;

/* Check if the stack is full*/


int isfull(){
if(top == MAXSIZE)
return 1;
else
return 0;
}

/* Function to insert into the stack */


int push(int data){
if(!isfull()) {
top = top + 1;
stack[top] = data;
} else {
printf("Could not insert data, Stack is full.\n");
}
}

/* Main function */
int main(){
int i;
push(44);
push(10);
push(62);
push(123);
push(15);
printf("Stack Elements: \n");

// print stack data


for(i = 0; i < 8; i++) {
printf("%d ", stack[i]);
}
return 0;
}

Output
Stack Elements:
44 10 62 123 15 0 0 0
Note − In Java we have used to built-in method push() to perform this operation.

Deletion: pop()
pop() is a data manipulation operation which removes elements from the stack. The following pseudo
code describes the pop() operation in a simpler way.

Algorithm
1 − Checks if the stack is empty.
2 − If the stack is empty, produces an error and exit.
3 − If the stack is not empty, accesses the data element at which top is pointing.
4 − Decreases the value of top by 1.
5 − Returns success.
Example
Following are the implementations of this operation in various programming languages −
#include <stdio.h>
int MAXSIZE = 8;
int stack[8];
int top = -1;

/* Check if the stack is empty */


int isempty(){
if(top == -1)
return 1;
else
return 0;
}

/* Check if the stack is full*/


int isfull(){
if(top == MAXSIZE)
return 1;
else
return 0;
}

/* Function to delete from the stack */


int pop(){
int data;
if(!isempty()) {
data = stack[top];
top = top - 1;
return data;
} else {
printf("Could not retrieve data, Stack is empty.\n");
}
}

/* Function to insert into the stack */


int push(int data){
if(!isfull()) {
top = top + 1;
stack[top] = data;
} else {
printf("Could not insert data, Stack is full.\n");
}
}

/* Main function */
int main(){
int i;
push(44);
push(10);
push(62);
push(123);
push(15);
printf("Stack Elements: \n");

// print stack data


for(i = 0; i < 8; i++) {
printf("%d ", stack[i]);
}
/*printf("Element at top of the stack: %d\n" ,peek());*/
printf("\nElements popped: \n");

// print stack data


while(!isempty()) {
int data = pop();
printf("%d ",data);
}
return 0;
}

Output
Stack Elements:
44 10 62 123 15 0 0 0
Elements popped:
15 123 62 10 44
Note − In Java we are using the built-in method pop().

peek()
The peek() is an operation retrieves the topmost element within the stack, without deleting it. This
operation is used to check the status of the stack with the help of the top pointer.

Algorithm
1. START
2. return the element at the top of the stack
3. END
Example
Following are the implementations of this operation in various programming languages −
#include <stdio.h>
int MAXSIZE = 8;
int stack[8];
int top = -1;

/* Check if the stack is full */


int isfull(){
if(top == MAXSIZE)
return 1;
else
return 0;
}

/* Function to return the topmost element in the stack */


int peek(){
return stack[top];
}

/* Function to insert into the stack */


int push(int data){
if(!isfull()) {
top = top + 1;
stack[top] = data;
} else {
printf("Could not insert data, Stack is full.\n");
}
}

/* Main function */
int main(){
int i;
push(44);
push(10);
push(62);
push(123);
push(15);
printf("Stack Elements: \n");

// print stack data


for(i = 0; i < 8; i++) {
printf("%d ", stack[i]);
}
printf("\nElement at top of the stack: %d\n" ,peek());
return 0;
}

Output
Stack Elements:
44 10 62 123 15 0 0 0
Element at top of the stack: 15
isFull()
isFull() operation checks whether the stack is full. This operation is used to check the status of the stack
with the help of top pointer.

Algorithm
1. START
2. If the size of the stack is equal to the top position of the stack, the stack is full. Return 1.
3. Otherwise, return 0.
4. END
Example
Following are the implementations of this operation in various programming languages −
#include <stdio.h>
int MAXSIZE = 8;
int stack[8];
int top = -1;

/* Check if the stack is full */


int isfull(){
if(top == MAXSIZE)
return 1;
else
return 0;
}

/* Main function */
int main(){
printf("Stack full: %s\n" , isfull()?"true":"false");
return 0;
}

Output
Stack full: false
isEmpty()
The isEmpty() operation verifies whether the stack is empty. This operation is used to check the status of
the stack with the help of top pointer.

Algorithm
1. START
2. If the top value is -1, the stack is empty. Return 1.
3. Otherwise, return 0.
4. END
Example
Following are the implementations of this operation in various programming languages −
#include <stdio.h>
int MAXSIZE = 8;
int stack[8];
int top = -1;

/* Check if the stack is empty */


int isempty() {
if(top == -1)
return 1;
else
return 0;
}

/* Main function */
int main() {
printf("Stack empty: %s\n" , isempty()?"true":"false");
return 0;
}

Output
Stack empty: true
Data Structure and Algorithms - Hash Table
Hash Table is a data structure which stores data in an associative manner. In a hash table, data is stored
in an array format, where each data value has its own unique index value. Access of data becomes very
fast if we know the index of the desired data.

Thus, it becomes a data structure in which insertion and search operations are very fast irrespective of the
size of the data. Hash Table uses an array as a storage medium and uses hash technique to generate an
index where an element is to be inserted or is to be located from.

Hashing
Hashing is a technique to convert a range of key values into a range of indexes of an array. We're going
to use modulo operator to get a range of key values. Consider an example of hash table of size 20, and
the following items are to be stored. Item are in the (key,value) format.

• (1,20)
• (2,70)
• (42,80)
• (4,25)
• (12,44)
• (14,32)
• (17,11)
• (13,78)
• (37,98)

Sr.No. Key Hash Array Index

1 1 1 % 20 = 1 1

2 2 2 % 20 = 2 2

3 42 42 % 20 = 2 2

4 4 4 % 20 = 4 4
5 12 12 % 20 = 12 12

6 14 14 % 20 = 14 14

7 17 17 % 20 = 17 17

8 13 13 % 20 = 13 13

9 37 37 % 20 = 17 17

Linear Probing
As we can see, it may happen that the hashing technique is used to create an already used index of the
array. In such a case, we can search the next empty location in the array by looking into the next cell until
we find an empty cell. This technique is called linear probing.

Sr.No. Key Hash Array Index After Linear Probing, Array Index

1 1 1 % 20 = 1 1 1

2 2 2 % 20 = 2 2 2

3 42 42 % 20 = 2 2 3

4 4 4 % 20 = 4 4 4

5 12 12 % 20 = 12 12 12

6 14 14 % 20 = 14 14 14

7 17 17 % 20 = 17 17 17

8 13 13 % 20 = 13 13 13

9 37 37 % 20 = 17 17 18

Basic Operations
Following are the basic primary operations of a hash table.

• Search − Searches an element in a hash table.


• Insert − inserts an element in a hash table.
• delete − Deletes an element from a hash table.

DataItem
Define a data item having some data and key, based on which the search is to be conducted in a hash
table.

struct DataItem {
int data;

int key;

};

Hash Method
Define a hashing method to compute the hash code of the key of the data item.

int hashCode(int key){

return key % SIZE;

Search Operation
Whenever an element is to be searched, compute the hash code of the key passed and locate the element
using that hash code as index in the array. Use linear probing to get the element ahead if the element is
not found at the computed hash code.

Example

struct DataItem *search(int key) {

//get the hash

int hashIndex = hashCode(key);

//move in array until an empty

while(hashArray[hashIndex] != NULL) {

if(hashArray[hashIndex]->key == key)

return hashArray[hashIndex];

//go to next cell

++hashIndex;

//wrap around the table

hashIndex %= SIZE;

}
return NULL;

Insert Operation
Whenever an element is to be inserted, compute the hash code of the key passed and locate the index
using that hash code as an index in the array. Use linear probing for empty location, if an element is found
at the computed hash code.

Example

void insert(int key,int data) {

struct DataItem *item = (struct DataItem*) malloc(sizeof(struct DataItem));

item->data = data;

item->key = key;

//get the hash

int hashIndex = hashCode(key);

//move in array until an empty or deleted cell

while(hashArray[hashIndex] != NULL && hashArray[hashIndex]->key != -1) {

//go to next cell

++hashIndex;

//wrap around the table

hashIndex %= SIZE;

hashArray[hashIndex] = item;

Delete Operation
Whenever an element is to be deleted, compute the hash code of the key passed and locate the index
using that hash code as an index in the array. Use linear probing to get the element ahead if an element
is not found at the computed hash code. When found, store a dummy item there to keep the performance
of the hash table intact.
Example

struct DataItem* delete(struct DataItem* item) {

int key = item->key;

//get the hash

int hashIndex = hashCode(key);

//move in array until an empty

while(hashArray[hashIndex] !=NULL) {

if(hashArray[hashIndex]->key == key) {

struct DataItem* temp = hashArray[hashIndex];

//assign a dummy item at deleted position

hashArray[hashIndex] = dummyItem;

return temp;

//go to next cell

++hashIndex;

//wrap around the table

hashIndex %= SIZE;

return NULL;

You might also like