0% found this document useful (0 votes)
4 views31 pages

ITDS 083

The document is a lab file for a Data Structure course at Delhi Technological University, detailing various programming experiments in C++. It includes topics such as string manipulation, pointers, dynamic memory allocation, file operations, searching and sorting algorithms, and matrix operations. Each section contains code examples and explanations of concepts related to data structures and algorithms.

Uploaded by

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

ITDS 083

The document is a lab file for a Data Structure course at Delhi Technological University, detailing various programming experiments in C++. It includes topics such as string manipulation, pointers, dynamic memory allocation, file operations, searching and sorting algorithms, and matrix operations. Each section contains code examples and explanations of concepts related to data structures and algorithms.

Uploaded by

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

DELHI TECHNOLOGICAL UNIVERSITY

(Formerly Delhi College of Engineering)


Shahbad Daulatpur, Bawana Road, Delhi 110042

DEPARTMENT OF INFORMATION TECHNOLOGY

IT-201
DATA STRUCTURE
LAB FILE

Submitted by:

Kshitij Dayal
2K20/ME/127
Experiment 1 (Programs on Strings and Passing Pointers to Functions &
Array)
C++ string class internally uses char array to store character but all memory management,
allocation, and null termination is handled by string class itself that is why it is easy to use.
The length of the C++ string can be changed at runtime because of dynamic allocation of
memory similar to vectors. As string class is a container class, we can iterate over all its
characters using an iterator similar to other containers like vector, set and maps, but
generally, we use a simple for loop for iterating over the characters and index them using
the [] operator.
C++ string class has a lot of functions to handle string easily. Most useful of them are
demonstrated in below code.

Pointers are symbolic representations of addresses. They enable programs to simulate


call-by-reference as well as to create and manipulate dynamic data structures. Iterating
over elements in arrays or other data structures is one of the main use of pointers.
The address of the variable you’re working with is assigned to the pointer variable that
points to the same data type (such as an int or string).

How to use a pointer?


 Define a pointer variable
 Assigning the address of a variable to a pointer using the unary operator (&)
which returns the address of that variable.
 Accessing the value stored in the address using unary operator (*) which
returns the value of the variable located at the address specified by its
operand.
The reason we associate data type with a pointer is that it knows how many bytes the
data is stored in. When we increment a pointer, we increase the pointer by the size of the
data type to which it points.

Problem 1 WAP with function to swap two numbers using call by reference. (C++)
Call-by-reference is a location or address of actual arguments passed to formal arguments.
Following program shows that the swapping of two numbers using call-by-reference.
CODE
#include<iostream>
using namespace std;
void swap (int &num1, int &num2) //&num1 and &bnum2 are Reference variables
{
int temp;
temp=num1;
num1=num2;
num2=temp;
}
int main()
{
//input
int a=5,b=10;
cout<<"\n Before swapping"<<"\n A = "<<a<<"\n B = "<<b<<endl;
swap(a,b);
cout<<"\n After swapping"<<"\n A = "<<a<<"\n B = "<<b<<endl;
return 0;
}
Output a=10,b=5
Problem 2 WAP with function to swap two integer arrays of same size using call by
reference.
#include <iostream>
using namespace std;
void swap(int array1[], int array2[])
{
int temp,i;
for(i=0; i<5; ++i)
{
temp = array1[SIZE];
array1[SIZE] = array2[SIZE];
array2[SIZE] = temp;
}
cout << "\nThe swapped arrays are as shown below: " << endl;
cout << " Array 1 is: ";
for (int i = 0; i < 5; ++i) {
cout << array1[i] << " ";
}
cout << "\n Array 2 is: ";
for (int i = 0; i < 5; ++i) {
cout << array2[i] << " ";
}
}
int main() {
int array1[SIZE] = {10,20,30,40,50};
int array2[SIZE] = {60,70,80,90,100};
swap(array1, array2);
return 0;
}
//output array1={60,70,80,90,100}
Array1={10,20,30,40,50}

Problem 3 WAP to reverse an array by swapping (without using additional memory).

#include<bits/stdc++.h>
using namespace std;
void Swap(int &arr){
while(l<h){
int temp=arr[l];
arr[l]=arr[h];
arr[h]=temp;
l++;
h--;
int l=0,h=arr.size(-1);
Int main()
{
Int arr[10]={1,2,3,4,5,6,7,8,9,10};
Swap(arr);
return 0;
}
WAP with function to swap two strings using pointers.
#include<stdio.h>
void swap1(char **str1_ptr, char **str2_ptr)
{
char *temp = *str1_ptr;
*str1_ptr = *str2_ptr;
*str2_ptr = temp;
}
int main()
{
char *str1 = "geeks";
char *str2 = "forgeeks";
swap1(&str1, &str2);
printf("str1 is %s, str2 is %s", str1, str2);
getchar();
return 0;
}
Output array={10,9,8,7,6,5,4,3,2,1
Experiment 2 (Dynamic Memory Allocation and File Operations)
1. ios:-
ios stands for input output stream.

This class is the base class for other classes in this class hierarchy.

This class contains the necessary facilities that are used by all the other derived

classes for input and output operations.
2. istream:-
 istream stands for input stream.
 This class is derived from the class ‘ios’.
 This class handle input stream.
 The extraction operator(>>) is overloaded in this class to handle input streams
from files to the program execution.
 This class declares input functions such as get(), getline() and read().

3. ostream:-
ostream stands for output stream.

This class is derived from the class ‘ios’.

This class handle output stream.

The insertion operator(<<) is overloaded in this class to handle output streams

to files from the program execution.
 This class declares output functions such as put() and write().
4. streambuf:-
This class contains a pointer which points to the buffer which is used to manage

the input and output streams.
5. fstreambase:-
This class provides operations common to the file streams. Serves as a base for

fstream, ifstream and ofstream class.
 This class contains open() and close() function.
6. ifstream:-
This class provides input operations.

It contains open() function with default input mode.

Inherits the functions get(), getline(), read(), seekg() and tellg() functions from

the istream.
7. ofstream:-
This class provides output operations.

It contains open() function with default output mode.

Inherits the functions put(), write(), seekp() and tellp() functions from the

ostream.
8. fstream:-
 This class provides support for simultaneous input and output operations.
 Inherits all the functions from istream and ostream classes through iostream.
9. filebuf:-
 Its purpose is to set the file buffers to read and write.
 We can also use file buffer member function to determine the length of the file.

In C++, files are mainly dealt by using three classes fstream, ifstream, ofstream available in
fstream headerfile.
ofstream: Stream class to write on files
ifstream: Stream class to read from files
fstream: Stream class to both read and write from/to files.

C malloc() method

The “malloc” or “memory allocation” method in C is used to dynamically


allocate a single large block of memory with the specified size. It returns a
pointer of type void which can be cast into a pointer of any form. It doesn’t
Initialize memory at execution time so that it has initialized each block with
the default garbage value initially.

Problem 1 WAP to find the Median of the elements after merging the two sorted Arrays of
same size.

CODE:

#inlcude<bits/stdc++.h>
Using numspace std;
Int Median(int a,int b){
Vector<int>c;
While(a.size()!=0 && b.size()!=0){
If(a.front()>b.front())
c.push_back(b.front());
b.pop_front();

else{
c.push_back(a.front());
a.pop_front();
if(a.size()!=0){
c.push_back(a.front());
a.pop_front();
}
If(b.size()!=0){
c.push_back(b.front());
b.pop_front();
}
Int i=n;
Return c[i];
}
Int main(){
Int n;
Cin>>n;
//input
Vector<int>a={1,3,5,7,9};
Vector<int>b={2,4,6,8,10};
Median(a,b);
}
Output median =(5+6)/2=5.5

Problem 2 WAP to store an information in array of structure, dynamically, and also give a
function to display the current information. The program should give user a choice for
inserting a data or to display the current data. Implement the program for Student
structures (contains student_name, student_roll_no, total_marks).

#include <iostreamm >


struct student {
char firstName[50];
int roll;
float marks;
} s[5];

int main() {
int i;
cout<<("Enter information of students:\n");

// storing information
for (i = 0; i < 5; ++i) {
s[i].roll = i + 1;
cout<<”For roll number ", s[i].roll);
cout<<("Enter first name: ");
cin>>s[i].firstName;
cout<<"Enter marks:";
cin>>s[i].marks;
}
Cout<<” Displaying Information”;

// displaying information
for (i = 0; i < 5; ++i) {
printf("\nRoll number: %d\n", i + 1);
cout<<”First Name”;
puts(s[i].firstName);
printf("Marks: %.1f", s[i].marks);
cout<<endl;
}
return 0;
WAP a program to store data of an employee in a structure variable
#include <iostream>
using namespace std;

struct Employee {
char name[50];
int salary;
int employeeCode;
char dept[5];
};

int main() {
Employee e;

cout << "Enter name of employee : ";


cin.getline(e.name, 50);
cout << "Enter department : ";
cin.getline(e.dept, 5);
cout << "Enter salary of employee : ";
cin >> e.salary;
cout << "Enter employee code : ";
cin >> e.employeeCode;

// Printing employee details


cout << "\n*** Employee Details ***" << endl;
cout << "Name : " << e.name << endl << "Salary : " << e.salary << endl;
cout << "Employee Code : " << e.employeeCode << endl << "Department : " << e.dept;
return 0;
}

WAP to Create a new file, Open an existing file, read the file to search a given word, write
into the file and close the file.
#include <iostream>
#include <fstream>
using namespace std;
int main() {
fstream my_file;
my_file.open("my_file", ios::out);
if (!my_file) {
cout << "File not created!";
}
else {
cout << "File created successfully!";
my_file.close();
}
return 0;
}
Experiment 3 Searching and Sorting in Non-decreasing order)

Searching Algorithms are designed to check for an element or retrieve an element from any
data structure where it is stored. Based on the type of search operation, these algorithms are
generally classified into two categories:
1. Sequential Search: In this, the list or array is traversed sequentially and every
element is checked. For example Linear Search.
2. Interval Search: These algorithms are specifically designed for searching in
sorted data-structures. These type of searching algorithms are much more
efficient than Linear Search as they repeatedly target the center of the search
structure and divide the search space in half. For Example: Binary Search.

Problem 1 WAP to implement Linear search and Binary search on 1D array of Integers.

#include <iostream>
using namespace std;

int search(int arr[], int N, int x)


{
int i;
for (i = 0; i < N; i++)
if (arr[i] == x)
return i;
return -1;
}

// Driver's code
int main(void)
{
int arr[] = { 2, 3, 4, 10, 40 };
int x = 10;
int N = sizeof(arr) / sizeof(arr[0]);

// Function call
int result = search(arr, N, x);
(result == -1)
? cout << "Element is not present in array"
: cout << "Element is present at index " << result;
return 0;
}
Time Complexity O(N)
Space Complexity O(1)
WAP to implement Insertion and Selection sort on 1D array of strings

Selection Sort
#include <bits/stdc++.h>
#include <string.h>
using namespace std;
#define MAX_LEN 100
void selectionSort(char arr[][MAX_LEN], int n)
{
int i, j, min_idx;
char minStr[MAX_LEN];
for (i = 0; i < n-1; i++)
{
int min_idx = i;
strcpy(minStr, arr[i]);
for (j = i + 1; j < n; j++)
{
if (strcmp(minStr, arr[j]) > 0)
{
strcpy(minStr, arr[j]);
min_idx = j;
}
}
if (min_idx != i)
{
char temp[MAX_LEN];
strcpy(temp, arr[i]); //swap item[pos] and item[i]
strcpy(arr[i], arr[min_idx]);
strcpy(arr[min_idx], temp);
}
}
}
Input : paper true soap floppy flower
Output: floppy, flower, paper, soap, true
WAP to implement Merge Sort on 1D array of Student structures (contains student_name,
student_roll_no, total_marks) with key as student_roll_no.

#include<stdio.h>
struct student
{
int rollno;
char name[20];
char college[40];
};
void main()
{
struct student s[20],temp;
int i,j,n;
clrscr();
printf("\nEnter no. of Students : ");
scanf("%d",&n);
printf("\nEnter the rollno,name,college name,score ");
for(i=0;i<n;i++)
scanf("%d%s%s%d",&s[i].rollno,s[i].name,s[i].college,&s[i].score);
for(i=0;i<=n-1;i++)
{
for(j=0;j<=n-1;j++)
{
if(s[j].score<s[j+1].score)
{
temp=s[j];
s[j]=s[j+1];
s[j+1]=temp;
}
}
}
printf("\nThe Merit List is :\n");
for(j=0;j<n;j++)
printf("%d\t%s\t%s\t%d\n",s[j].rollno,s[j].name,s[j].college,s[j].score);
getch();
}
Input Rohit Dav 203
Sumit Dav 202
Ritesh Dav 201
Rahul Dav 205
Rajesh Dav 204

Output Ritesh Dav 201


Sumit Dav 202
Rohit Dav 203
Rajesh Dav 204
Rahul Dav 205
Experiment 4 (Sparse Arrays and Matrix Operations)

Problem 1 WAP to store and display a Lower-Right triangular matrix in RMO and CMO
fashion.
Problem 2 WAP to store and display an Upper-Right triangular matrix in RMO and CMO
fashion.
Given a lower triangular matrix Mat[][], the task is to store the matrix using row-major
mapping.
Lower Triangular Matrix: A lower triangular matrix is a square matrix in which the lower
triangular part of a matrix consists of non-zero elements and the upper triangular part
consists of 0s. The lower triangular matrix for a 2D matrix Mat[][] is mathematically
defined as:
 If i < j, set Mat[i][j] = 0.
 If i >= j, set Mat[i][j] > 0.

#include<iostream>
using namespace std;
void lower(int matrix[3][3], int row, int col)
{
int i, j;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (i < j)
{
cout << "0" << " ";
}
else
cout << matrix[i][j] << " ";
}
cout << endl;
}
}
void upper(int matrix[3][3], int row, int col)
{
int i, j;

for (i = 0; i < row; i++)


{
for (j = 0; j < col; j++)
{
if (i > j)
{
cout << "0" << " ";
}
else
cout << matrix[i][j] << " ";
}
cout << endl;
}
}

int main()
{
int matrix[3][3] = {{1, 2, 3},
{4, 5, 6},
{7, 8, 9}};
int row = 3, col = 3;

cout << "Lower triangular matrix: \n";


lower(matrix, row, col);

cout << "Upper triangular matrix: \n";


upper(matrix, row, col);

return 0;
}
Input : matrix[3][3] = {1 2 3
4 5 6
7 8 9}
Output :
Lower : 1 0 0 Upper : 1 2 3
4 5 0 0 5 6
7 8 9 0 0 9

Input : matrix[3][3] = {7 8 9
3 2 1
6 5 4}
Output :
Lower : 7 0 0 Upper : 7 8 9
3 2 0 0 2 1
6 5 4 0 0 4

WAP to store and display a Tri-Diagonal matirx in RMO and CMO fashion.
What does it mean by a tridiagonal matrix?
If we look at the elements, non-zero elements are present in the main diagonal, lower
diagonal, and upper diagonal and the rest of the elements are all zeros. Let us define the
property of this matrix based on indices of the matrix. If we observe the indices of
elements of:
1. Main Diagonal: row number is equal to column number (i = j).
2. Lower Diagonal: row number – column number = 1 (i – j = 1).
3. Upper Diagonal: row number – column number = -1 (i – j = -1).
struct Matrix
{
int *B;
int n;
};
void Set (struct Matrix *m, int i, int j, int y)
{
if (i - j == 1)
{
m->B[i - 1] = y;
}
if (i - j == 0)
{
m->B[m->n - 1 + i - 1] = y;
}
if (i - j == -1)
{
m->B[(2 * m->n) - 1 + i - 1] = y;
}
}
int Get (struct Matrix m, int i, int j)
{
if (i - j == 1)
{
return m.B[i - 1];
}
if (i - j == 0)
{
return m.B[m.n - 1 + i - 1];
}
if (i - j == -1)
{
return m.B[(2 * m.n) - 1 + i - 1];
}
return 0;
Experiment 5 (Stacks and Queues)
Stack
It is a linear data structure that follows a particular order in which the operations are
performed.
LIFO( Last In First Out ):
This strategy states that the element that is inserted last will come out first. You can take a
pile of plates kept on top of each other as a real-life example. The plate which we put last
is on the top and since we remove the plate that is at the top, we can say that the plate
that was put last comes out first.
Basic Operations on Stack
In order to make manipulations in a stack, there are certain operations provided to us.
 push() to insert an element into the stack
 pop() to remove an element from the stack
 top() Returns the top element of the stack.
 isEmpty() returns true is stack is empty else false
 size() returns the size of stack

Queues are a type of container adapters that operate in a first in first out (FIFO) type of
arrangement. Elements are inserted at the back (end) and are deleted from the front.
Queues use an encapsulated object of deque or list (sequential container class) as its
underlying container, providing a specific set of member functions to access its elements.

Problem 1 WAP to implement Stack ADT using Arrays


int a[MAX]; // Maximum size of Stack
Stack() { top = -1; }
bool push(int x);
int pop();
int peek();
bool isEmpty();
};
bool Stack::push(int x)
{
if (top >= (MAX - 1)) {
cout << "Stack Overflow";
return false;
}
else {
a[++top] = x;
cout << x << " pushed into stack\n";
return true;
}
}
int Stack::pop()
{
if (top < 0) {
cout << "Stack Underflow";
return 0;
}
else {
int x = a[top--];
return x;
}
}
int Stack::peek()
{
if (top < 0) {
cout << "Stack is Empty";
return 0;
}
else {
int x = a[top];
return x;
}
}
bool Stack::isEmpty()
{
return (top < 0);
}

Problem 2 WAP to evaluate a given postfix expression using stack ADT.


The Postfix notation is used to represent algebraic expressions. The
expressions written in postfix form are evaluated faster compared to infix
notation as parenthesis is not required in postfix.
#include<bits/stdc++.h>
using namespace std;
int evaluatePostfix(char* exp)
{
struct Stack* stack = createStack(strlen(exp));
int i;
if (!stack) return -1;
for (i = 0; exp[i]; ++i)
{
if (isdigit(exp[i]))
push(stack, exp[i] - '0');
else
{
int val1 = pop(stack);
int val2 = pop(stack);
switch (exp[i])
{
case '+': push(stack, val2 + val1); break;
case '-': push(stack, val2 - val1); break;
case '*': push(stack, val2 * val1); break;
case '/': push(stack, val2/val1); break;
}
}
}
return pop(stack);
}
int main()
{
char exp[] = "231*+9-";
cout<<"postfix evaluation: "<< evaluatePostfix(exp);
return 0;
}

Input: str = “2 3 1 * + 9 -“
Output: -4

Problem 3 WAP to check the given string is palindrome using stack.


#include <bits/stdc++.h>
using namespace std;
bool isPalindrome(string s)
{
int length = s.size();
stack<char> st;
int i, mid = length / 2;
for (i = 0; i < mid; i++) {
st.push(s[i]);
}
if (length % 2 != 0) {
i++;
}
char ele;
while (s[i] != '\0')
{
ele = st.top();
st.pop();
if (ele != s[i])
return false;
i++;
}
return true;
}
int main()
{
string s = "madam";
if (isPalindrome(s)) {
cout << "Yes";
}
else {
cout << "No";
}
return 0;
}

Input: str = “shreyansh”


Output: No
Input: str = “madam”
Output: Yes

Problem 4 WAP to check the given expression is correctly parenthesized.

#include <bits/stdc++.h>
using namespace std;
bool areBracketsBalanced(string expr)
{
stack<char> temp;
for (int i = 0; i < expr.length(); i++) {
if (temp.empty()) {
temp.push(expr[i]);
}
else if ((temp.top() == '(' && expr[i] == ')')
|| (temp.top() == '{' && expr[i] == '}')
|| (temp.top() == '[' && expr[i] == ']')) {
temp.pop();
}
else {
temp.push(expr[i]);
}
}
if (temp.empty()) {

return true;
}
return false;
}
int main()
{
string expr = "{()}[]";
if (areBracketsBalanced(expr))
cout << "Balanced";
else
cout << "Not Balanced";
return 0;
}
Input: exp = “[()]{}{[()()]()}”
Output: Balanced
Explanation: all the brackets are well-formed
Input: exp = “[(])”
Output: Not Balanced
Explanation: 1 and 4 brackets are not balanced
Experiment 6 (Singly Linked List)
Like arrays, Linked List is a linear data structure. Unlike arrays, linked list elements are not
stored at a contiguous location; the elements are linked using pointers. They include a
series of connected nodes. Here, each node stores the data and the address of the next
node.

Arrays can be used to store linear data of similar types, but arrays have the following
limitations:
 The size of the arrays is fixed: So we must know the upper limit on the number
of elements in advance. Also, generally, the allocated memory is equal to the
upper limit irrespective of the usage.
 Insertion of a new element / Deletion of a existing element in an array of
elements is expensive: The room has to be created for the new elements and
to create room existing elements have to be shifted but in Linked list if we have
the head node then we can traverse to any node through it and insert new
node at the required position.
Problem 1 WAP to implement Stack ADT using Linked list with the basic operations as
Create(), IsEmpty(), Push(), Pop(), IsFull() with appropriate prototype to a functions.

#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node* link;
Node(int n)
{
this->data = n;
this->link = NULL;
}
};
class Stack {
Node* top;
public:
Stack() { top = NULL; }
void push(int data)
{
Node* temp = new Node(data);
if (!temp) {
cout << "\nStack Overflow";
exit(1);
}
temp->data = data;
temp->link = top;
top = temp;
}
bool isEmpty()
{
return top == NULL;
}
int peek()
{
if (!isEmpty())
return top->data;
else
exit(1);
}
void pop()
{
Node* temp;
if (top == NULL) {
cout << "\nStack Underflow" << endl;
exit(1);
}
else {
temp = top;
top = top->link;
free(temp);
}
}
void display()
{
Node* temp;
if (top == NULL) {
cout << "\nStack Underflow";
exit(1);
}
else {
temp = top;
while (temp != NULL) {
cout << temp->data;
temp = temp->link;
if (temp != NULL)
cout << " -> ";
}
}
}
};
Problem 2 WAP to swap elements in pairs in the given linked list. (e.g.: 1->2->3->4->5-
>null, then result should be 2->1->4->3->5->null.)

class Solution {
public:
ListNode* swapPairs(ListNode* head) {
if(head==NULL||head->next==NULL){
return head;
}
ListNode *curr=head;
ListNode *prev=new ListNode;
while((curr!=NULL)&&(curr->next!=NULL)){
prev->next=curr->next;
curr->next=curr->next->next;
prev->next->next=curr;
curr=curr->next;
prev=prev->next;
}
return prev->next;
}
};
Input =1->2->3->4->5->null
Output=2->1->4->3->5->null.)
Problem 3 WAP to find second last node of the given linked list.

#include <bits/stdc++.h>
using namespace std;
ListNode* seondlast(ListNode* head){
ListNode* temp=head;
While(temp->next->next!=NULL){
temp=temp->next;
}
Return temp;
}
Input=1->2->3->4->5->null
Output=4
Problem 4 WAP to concatenate two singly linked list in sorted order either ascending or
descending.

#include <bits/stdc++.h>
using namespace std;
ListNode* headsorted(ListNode* head1,ListNode* head2){
ListNode* temp=newNode(0);
ListNode* ans=temp;
While(head1->next!=NULL && head2->next!=NULL){
If(head1->data<head2->data){
Temp->next=head1;
Temp=temp->next;
}
Else{
Temp->next=head2;
Temp=temp->next;
}
While(head1->next!=NULL){
Temp->next=head1;
Temp=temp->next;
While(head2->next!=NULL){
Temp->next=head2;
Temp=temp->next;
}
Return ans;
Input =1->3->5->7->9->null and 2->4->6->8->10null
Output=1-->2->3->4->5->->6->7->8->9->10->null

Problem WAP to print alternate nodes from the list.


#include <bits/stdc++.h>
using namespace std;
ListNode* alternatenodehead(ListNode* head){
ListNode* temp=head;
ListNode* ans=temp;
While(head->next->next!=NULL){
temp->next=head;
Head=head->next->next;
}
Return head;
input=1-->2->3->4->5->->6->7->8->9->10->null
output=1,3,5,7,9
WAP to find first common element between two linked list.

#include <bits/stdc++.h>
using namespace std;
int firstCommon(struct Node* head1, struct Node* head2)
{
// Traverse through every node of first list
for (; head1 != NULL; head1=head1->next)
for (Node *p = head2; p != NULL; p = p->next)
if (p->data == head1->data)
return head1->data;
return 0;
}
Input=L1=13->7->9->4->8
L2=11->10->4->8->9
Output=4
Experiment 7 (Circular Singly Linked List and Doubly Linked List)
Circular Singly Linked List
In a singly linked list, for accessing any node of the linked list, we start traversing from the
first node. If we are at any node in the middle of the list, then it is not possible to access
nodes that precede the given node. This problem can be solved by slightly altering the
structure of a singly linked list. In a singly linked list, the next part (pointer to the next
node) of the last node is NULL. If we utilize this link to point to the first node, then we can
reach the preceding nodes.
Doubly linked list
A Doubly Linked List (DLL) contains an extra pointer, typically called the previous pointer,
together with the next pointer and data which are there in the singly linked list.
Advantages of DLL over the singly linked list:
 A DLL can be traversed in both forward and backward directions.
 The delete operation in DLL is more efficient if a pointer to the node to be
deleted is given.
 We can quickly insert a new node before a given node.
 In a singly linked list, to delete a node, a pointer to the previous node is
needed. To get this previous node, sometimes the list is traversed. In DLL, we
can get the previous node using the previous pointer.

Problem1 WAP to create a Circular Singly Linked List


struct Node* addToEmpty(struct Node* last, int data)
{
if (last != NULL)
return last;
struct Node* temp
= (struct Node*)malloc(sizeof(struct Node));
temp->data = data;
last = temp;
temp->next = last;
return last;
}
struct Node* addBegin(struct Node* last, int data)
{
if (last == NULL)
return addToEmpty(last, data);
struct Node* temp
= (struct Node*)malloc(sizeof(struct Node));
temp->data = data;
temp->next = last->next;
last->next = temp;
return last;
}
struct Node* addEnd(struct Node* last, int data)
{
if (last == NULL)
return addToEmpty(last, data);
struct Node* temp
= (struct Node*)malloc(sizeof(struct Node));
temp->data = data;
temp->next = last->next;
last->next = temp;
last = temp;
return last;
}

Problem 2 WAP to implement doubly linked list


class Node {
public:
int data;
Node* next;
Node* prev;
};

void insertAfter(Node* prev_node, int new_data)


{
if (prev_node == NULL) {
cout << "the given previous node cannot be NULL";
return;
}
Node* new_node = new Node();
new_node->data = new_data;
new_node->next = prev_node->next;
prev_node->next = new_node;
new_node->prev = prev_node;
if (new_node->next != NULL)
new_node->next->prev = new_node;
}
Void removekeyvalue(Node* head,int key){
Node* temp=head;
While(temp->next!=NULL){
If(temp->data!=key){
Temp=temp->next;
}
Else{
Node*t1=temp->prev;
Node* t=temp->prev;
t->next=t->next->next;
t=t->next;
t->prev=t1;
}
Node *merge(Node *first, Node *second)
{
if (!first)
return second;
if (!second)
return first;
if (first->data < second->data)
{
first->next = merge(first->next,second);
first->next->prev = first;
first->prev = NULL;
return first;
}
else
{
second->next = merge(first,second->next);
second->next->prev = second;
second->prev = NULL;
return second;
}
}
Node *split(Node *head)
{
Node *fast = head,*slow = head;
while (fast->next && fast->next->next)
{
fast = fast->next->next;
slow = slow->next;
}
Node *temp = slow->next;
slow->next = NULL;
return temp;
}

WAP to represent various sparse matrices using linked list and give addition function to add two
sparse matrices.

Why to use Sparse Matrix instead of simple matrix ?


 Storage: There are lesser non-zero elements than zeros and thus lesser
memory can be used to store only those elements.
 Computing time: Computing time can be saved by logically designing a data
structure traversing only non-zero elements..
Using Linked Lists
In linked list, each node has four fields. These four fields are defined as:

 Row: Index of row, where non-zero element is located


 Column: Index of column, where non-zero element is located
 Value: Value of the non zero element located at index – (row,column)
 Next node: Address of the next node

Input: { 0 , 0 , 3 , 0 , 4 },
{ 0 , 0 , 5 , 7 , 0 },
{ 0 , 0 , 0 , 0 , 0 },
{ 0 , 2 , 6 , 0 , 0 }

#include<iostream>
using namespace std;
class Node
{
public:
int row;
int col;
int data;
Node *next;
};
void printList(Node *start)
{
Node *ptr = start;
cout << "row_position:";
while (ptr != NULL)
{
cout << ptr->row << " ";
ptr = ptr->next;
}
cout << endl;
cout << "column_position:";

ptr = start;
while (ptr != NULL)
{
cout << ptr->col << " ";
ptr = ptr->next;
}
cout << endl;
cout << "Value:";
ptr = start;
while (ptr != NULL)
{
cout << ptr->data << " ";
ptr = ptr->next;
}
}
Output:
row_position:0 0 1 1 3 3
column_position:2 4 2 3 1 2
Value:3 4 5 7 2 6
Experiment 8 (Binary Trees, BST, Heaps, Heap sort and Threaded Binary Trees)

A tree is a popular data structure that is non-linear in nature. Unlike other data structures
like array, stack, queue, and linked list which are linear in nature, a tree represents a
hierarchical structure. The ordering information of a tree is not important. A tree contains
nodes and 2 pointers. These two pointers are the left child and the right child of the
parent node. Let us understand the terms of tree in detail.
 Root: The root of a tree is the topmost node of the tree that has no parent
node. There is only one root node in every tree.
 Edge: Edge acts as a link between the parent node and the child node.
 Leaf: A node that has no child is known as the leaf node. It is the last node of
the tree. There can be multiple leaf nodes in a tree.
 Subtree: The subtree of a node is the tree considering that particular node as
the root node.
 Depth: The depth of the node is the distance from the root node to that
particular node.
 Height: The height of the node is the distance from that node to the deepest
node of that subtree.
 Height of tree: The Height of the tree is the maximum height of any node. This
is same as the height of root node

Binary Tree: A tree whose elements have at most 2 children is called a binary tree. Since
each element in a binary tree can have only 2 children, we typically name them the left
and right child.
Binary Tree Representation: A tree is represented by a pointer to the topmost node of the
tree. If the tree is empty, then the value of the root is NULL.
A Tree node contains the following parts.
1. Data
2. Pointer to the left child
3. Pointer to the right child

A binary Search Tree is a node-based binary tree data structure which has the following
properties:
 The left subtree of a node contains only nodes with keys lesser than the node’s
key.
 The right subtree of a node contains only nodes with keys greater than the
node’s key.
 The left and right subtree each must also be a binary search tree.
There must be no duplicate nodes.

You might also like