Dsa Notes
Dsa Notes
List of Tables iv
2 Introduction to LinkedList 10
2.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.2 LinkedList . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2.1 Advantages of linked list . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2.2 Types of Linked list . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.3 Singly linked list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.4 Operations on Singly linked list . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.4.1 Create List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.4.1.1 Java Program to Create a new Node and Linked List . . . . . 14
2.4.2 Traversing / Display a Linked List . . . . . . . . . . . . . . . . . . . . 16
2.4.3 Insertion in Singly Linked List . . . . . . . . . . . . . . . . . . . . . . 24
i
2.4.3.1 Insertion of a node at first position of a singly linked list . . . 24
2.4.3.2 Insertion of a node at the end of a singly linked list . . . . . . 25
2.4.3.3 Insertion of a node at any index position of a single linked list 26
2.4.4 Delete Node from Single Linked List . . . . . . . . . . . . . . . . . . 30
2.4.4.1 Delete node from begining . . . . . . . . . . . . . . . . . . 30
2.4.4.2 Delete from the End . . . . . . . . . . . . . . . . . . . . . . 30
2.4.4.3 Delete By Position . . . . . . . . . . . . . . . . . . . . . . . 31
2.4.5 Reverse a Linked List . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.5 Doubly LinkedList . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
2.5.1 Create Node in Doubly LinkedList . . . . . . . . . . . . . . . . . . . . 39
2.5.2 Traverse Doubly LinkedList . . . . . . . . . . . . . . . . . . . . . . . 40
2.5.3 Fid size of Doubly LinkedList . . . . . . . . . . . . . . . . . . . . . . 40
2.5.4 Insert Node at Begin of the Doubly LinkedList . . . . . . . . . . . . . 41
2.5.5 Insert Node at End of the Dobly LinkedLIst . . . . . . . . . . . . . . . 41
2.5.6 Insert Node at any position of the Doubly LinkedList . . . . . . . . . . 42
2.5.7 Delete Node from the Beginning of a Doubly LinkedList . . . . . . . . 42
2.5.8 Delete Node from the End of a Doubly LinkedList . . . . . . . . . . . 42
2.5.9 Delete Node from any position of a Doubly LinkedList . . . . . . . . . 43
3 Stack 50
3.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
3.2 Operation on Stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
3.2.1 Working of Stack Data Structure . . . . . . . . . . . . . . . . . . . . . 51
3.3 Array Implementation of Stack . . . . . . . . . . . . . . . . . . . . . . . . . . 51
3.4 Linked List Implementation of Stack . . . . . . . . . . . . . . . . . . . . . . . 58
3.5 Evaluation of Arithmetic Expressions . . . . . . . . . . . . . . . . . . . . . . 61
3.5.1 Infix Notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
3.5.2 Prefix Notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
3.5.3 Postfix Notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
3.6 Converting infix expression to postfix form . . . . . . . . . . . . . . . . . . . 62
3.6.1 Evaluation of a Postfix Expression . . . . . . . . . . . . . . . . . . . . 65
3.7 Questions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
4 Queue 67
4.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
4.1.1 Stack vs Queue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
4.2 Array Implementation of Queue . . . . . . . . . . . . . . . . . . . . . . . . . 67
4.3 LinkedList Implementation of Queue . . . . . . . . . . . . . . . . . . . . . . 71
4.4 Comparisons of queer representation using linked list over the array . . . . . . 71
4.5 Operations on Queue using Linked List . . . . . . . . . . . . . . . . . . . . . 72
List of Figures
iii
List of Tables
iv
Chapter 1
1.1 Introduction
• The concept of programming has been started with nonstructured, linear programs,
known as spaghetti code, in which the logic flow wound through the program like
spaghetti on a plate.
• Next came the concept of modular programming, in which programs were organized
in functions, each of which still used a linear coding technique.
• In the 1970s, the basic principles of structured programming were formulated by com-
puter scientists such as Edsger Dijkstra and Niklaus Wirth.
• Atomic Data
– Atomic data are data that consist of a single piece of information; that is, they
cannot be divided into other meaningful pieces of data.
– For example, the integer 4562 may be considered a single integer value. Of course,
we can decompose it into digits, but the decomposed digits do not have the same
characteristics of the original integer; they are four single digit integers ranging
from 0 to 9.
– In some languages atomic data are known as scalar data because of their numeric
properties.
• Composit Data
– Composite data can be broken out into subfields that have meaning.
1
1.1 Introduction
– As an example of a composite data item, consider your telephone number. A tele-
phone number actually has three different parts. First, there is the area code.
– Then what you can consider to be your phone number is actually two different
data items, a prefix consisting of a three-digit exchange and the number within the
exchange consisting of four digits
Data Type:
• A data type consists of two parts: a set of data and the operations that can be performed
on the data.
• Thus we see that the integer type consists of values (whole numbers in some defined
range) and operations (add, subtract, multiply, divide, and any other operations appropri-
ate for the data.
• Abbreviated ADT. The specification of a data type within some language, independent
of an implementation.
• The interface for the ADT is defined in terms of a type and a set of operations on that
type.
• These implementation details are hidden from the user of the ADT and protected from
outside access, a concept referred to as encapsulation.
2
1.2 Experimental Studies
Data Structure:
• Data structure is a systematic way of organizing and accessing data.
• It is an aggregation of atomic and composite data into a set with defined relationships.
• In this definition structure means a set of rules that holds the data together.
Algorithm:
• An Algorithm is a step-by-step procedure for performing some task in a finite amount
of time.
• An algorithm is a computer program that describes a set of steps applied over a set of
input to produce a set of output.
1. Correctness: The algorithm should be correct. It should be able to process all the
given inputs and provide correct output.
2. Efficiency: The algorithm should be efficient in solving problems. Efficiency is
measured in two parameters. First is Time-Complexity, how quick result is pro-
vided by an algorithm. Second is Space-Complexity, how much RAM or memory
that an algorithm is going to consume to give desired result.
3
1.2 Experimental Studies
• A simple mechanism for collecting such running times in Java is based on use of the
currentTimeMillis method of the System class.
• However, the measured times reported by currentTimeMillis will vary greatly from ma-
chine to machine, and may likely vary from trial to trial, even on the same machine.
• This is because many processes share use of a computer’s central processing unit (or
CPU) and memory system; therefore, the elapsed time will depend on what other pro-
cesses are running on the computer when a test is performed.
• The first algorithm we consider performs repeated string concatenation, based on the +
operator. The second algorithm relies on Java’s StringBuilder class, and is implemented
as method repeat2. It is implemented as method repeat1 in below Code Fragment..
4
1.2 Experimental Studies
• The executed trials to compose strings of increasing lengths to explore the relationship
between the running time and the string length. The results of our experiments are shown
as follows:
Figure 1.3: Results of timing experiment on the methods from Code Fragment
The most striking outcome of these experiments is how much faster the repeat2 algorithm is
relative to repeat1.
5
1.2 Experimental Studies
Challenges of Experimental Analysis: There are three major limitations to their use for
algorithm analysis:
• Experimental running times of two algorithms are difficult to directly compare unless the
experiments are performed in the same hardware and software environments.
• Experiments can be done only on a limited set of test inputs; hence, they leave out the
running times of inputs not included in the experiment (and these inputs may be impor-
tant).
• An algorithm must be fully implemented in order to execute it to study its running time
experimentally.
1. Allows us to evaluate the relative efficiency of any two algorithms in a way that is inde-
pendent of the hardware and software environment.
2. Is performed by studying a high-level description of the algorithm without need for im-
plementation.
Counting Primitive Operations To analyze the running time of an algorithm without per-
forming experiments, we perform an analysis directly on a high-level description of the algo-
rithm (either in the form of an actual code fragment, or language-independent pseudocode).
We define a set of primitive operations such as the following:
• Calling a method
6
1.3 The Seven Functions used for Algorithm Analysis
Measuring Operations as a Function of Input Size
• To capture the order of growth of an algorithm’s running time, we will associate, with
each algorithm, a function f(n) that characterizes the number of primitive operations that
are performed as a function of the input size n.
• An algorithm may run faster on some inputs than it does on others of the same size.
• Thus, we may wish to express the running time of an algorithm as the function of the
input size obtained by taking the average over all possible inputs of the same size.
• In this case, it only makes sense that you be able to recognize and choose the more
efficient algorithm.
f(n) = efficiency
7
1.4 Algorithm Efficiency
1.4.1 Linear Loops
We want to know how many times the body of the loop is repeated in the following code
• Assuming i is an integer, the answer is 1000 times. The number of iterations is directly
proportional to the loop factor 1000.
f(n) = n
• However, the answer is not always as straightforward as it is in the above example. For
instance, consider the following loop. How many times is the body repeated in this loop?
Here the answer is 500 times.
• In this example the number of iterations is half the loop factor. Once again, however,
the higher the factor, the higher the number of loops. The efficiency of this loop is
proportional to half the factor, which makes it
f(n) = n/2
Generalizing the analysis, we can say that the iterations in loops that multiply or divide are
determined by the following formula:
8
1.4 Algorithm Efficiency
f(n) = logn
• When we analyze nested loops, we must determine how many iterations each loop com-
pletes.
• The total is then the product of the number of iterations in the inner loop and the number
of iterations in the outer loop.
We now look at three nested loops: linear logarithmic, quadratic, and dependent quadratic.
9
Chapter 2
Introduction to LinkedList
2.1 Introduction
• Link list is a linear list of linked elements. Like arrays, linked list represents another
linear data structure.
• In arrays, there is always a fixed relationship between the addresses of two consecutive
elements as all the items of an array must be stored contiguously.
• However, note that this contiguity requirement makes expansion or contraction of the
size of the array difficult.
• In linked list, data items may be scattered arbitrarily all over the memory, but we can
achieve fast insertion and deletion in a dynamic situation.
Limitations of Array In many applications, the array is not suitable as it has some drawback.
The drawbacks of Array are listed below:
• The maximum size of the array needs to be predicted beforehand. One cannot change the
size of the array after allocating memory, but, many applications require resizing.
• Most of the space in the array is wasted when programmer allocates arrays with large
size. On the other hand, when program ever needs to process more than the specify size
then the code breaks.
• Storage of the array must be available contiguously. Required storage not always imme-
diately available.
• Insertion and deletion operation may be very slow. The worst case occurs when the first
element is to be deleted or inserted. Almost all the elements of the array need to be
moved.
10
2.2 LinkedList
2.2 LinkedList
Definition: A linked list is a linear ordered collection of finite homogeneous data elements
called node, where the linear order is maintained by means of links or pointers.
• A linked list allocates space for each element separately in its own block of memory
called a "linked list element" or "node".
• A linked list, in its simplest form, is a collection of nodes that collectively form a linear
sequence.
• The list structure is created by the use node object and connect all its nodes together like
the links in a chain.
1. Linked list are dynamic data structures. That is, they can extend or shrink during the
execution of a program.
11
2.3 Singly linked list
2. Storage need not be contiguous.
4. Insertion or deletion is easy and efficient, may be done very fast, in a constant amount of
times, ndependent of the size of the list.
5. The joining of two linked lists can be done by assigning pointer of the second linked list
in the last node of the first linked list.
2. link or next field, contains the address of the next node in the list.
3. head, the linked list instance must keep a reference to the first node of the list, known as
the head.
• A "data" field to store whatever element type the list holds for the user, and a "link or
next" field, which is a pointer, used to link one node to the next node.
• head: The linked list instance must keep a reference to the first node of the list, known
as the head.
12
2.4 Operations on Singly linked list
• tail: The last node of the list is known as the tail.
• The tail of a list can be found by traversing the linked list— starting at the head and
moving from one node to another by following each node’s next reference.
• We can identify the tail as the node having null as its next reference. This process is also
known as link hopping or pointer hopping.
• Traverse: This operation traverse/visit all the elements of the linked list exactly once
• Searching: This operation performs linear searching for a key value in the linked list
• Merging: This operation performs merging of two linked lists in a single linked list
• ’Head‘ is a pointer which holds the address of the HEADER of the linked list.
13
2.4 Operations on Singly linked list
Algorithm 2.4.1 create (Head, item)
[Create new Node]
1: Create the new Node
2: Set Node.data = item
3: Set Node.next = NULL
[Check for empty List]
4: if Head = NULL then
Set Head = Node
5: else
Set Temp = Head
6: while T emp.next , null do
Set Temp = Temp.next
7: end while
8: Temp.next = Node
9: end if
10: Return Head
• In the abov ealgorithm Node represent a new node of the Linked list.
• Assign the value or item to the data part of the Node [Statement-2]
In java we can created a class named Node to represent a node object. The class has two
members -
• the first is the data of integer type.It can be any data value that we want to store in the
Node object.
• the other is the Node class type reference next which referes to the memory of the next
node in the linked list.
• So when we represent any node for the linked list, it refers to an object of Node class
type.
class Node {
public int data;
public Node next;
}
The Node class is used in the createNode(Node head, int item) method. It can be called
repeatedly for creating the nodes.
14
2.4 Operations on Singly linked list
• The node,temp, head are are Node class objects.
15
2.4 Operations on Singly linked list
2.4.2 Traversing / Display a Linked List
This algorithm traverses a linked list and prints the data part of each node of the linked list.
• The ’_HEAD‘ is a pointer which points to the starting node of the linked list
16
2.4 Operations on Singly linked list
Complete Java Program to Create and Traverse a Linked List
Compete java code to create and Traverse a single LinkedList. It use a Node class for the
node, two methods to create and display nodes of the LinkedList
package insertnode;
import java.util.Scanner;
//Class for the contents of a node
class Node{
int data;
Node next;
}
class LinkedList{
//Method t create a new node by using the Node class object
public static Node create(Node head) {
Scanner sc=new Scanner(System.in);
char choice;
int nodeCount=1;
do {
Node node=new Node();
Node temp;
System.out.println("Enter data for the new node");
node.data=sc.nextInt();
node.next=null;
if(head==null)
head=node;
else {
temp=head;
while(temp.next != null) {
temp=temp.next;
}
temp.next=node;
}
System.out.println(nodeCount+" node created");
System.out.println("Would you like to enter another node(y|n)");
choice=sc.next().charAt(0);
if(choice==’y’ || choice==’Y’)
nodeCount++;
}while(choice==’y’ || choice==’Y’);
return head;
}
//Method to display the linked list
public static void display(Node head) {
Node temp;
17
2.4 Operations on Singly linked list
temp=head;
if(head==null)
System.out.println("Empty linked list");
else {
System.out.println("The elements of the linked list are:");
while(temp != null) {
System.out.print(temp.data+"-->");
temp=temp.next;
}
}
}
}
public class LinkedListInsertDriver {
public static void main(String[] args) {
Node head=null;
head=LinkedList.create(head);
LinkedList.display(head);
head=LinkedList.insertBegin(head);
LinkedList.display(head);
}
}
18
2.4 Operations on Singly linked list
Example 2.4.1 Java program to create a generic LinkedList. Insert node at begin end and
at any position
class Node{
int data;
Node next;
Node(int data){
this.data=data;
next=null;
}
}
class LinkedList{
Node head=null;
Node tail=null;
// Insert at end by using head and tail
void insertAtEnd(int item) {
Node node=new Node(item);
if(head==null) {
head=node;
}
else {
tail.next=node;
}
tail=node;
}
/*
void insertAtEnd(int item) {
Node node=new Node(item);
Node temp=null;
if(head==null) {
head=node;
}
else {
temp=head;
while(temp.next!=null) {
temp=temp.next;
}
temp.next=node;
//tail=node;
}
}*/
int size() {
Node temp=head;
19
2.4 Operations on Singly linked list
int count=0;
while(temp!=null) {
count++;
temp=temp.next;
}
return count;
}
void insertAtBegin(int item) {
Node node=new Node(item);
if(head==null) {
head=node;
//tail=node;
}
else {
node.next=head;
head=node;
}
}
void insertAt(int pos,int item) {
Node node=new Node(item);
Node temp=head;
if(pos==1) {
insertAtBegin(item);
return;
}
else if(pos==size()) {
insertAtEnd(item);
return;
}
for(int i=1;i<=pos-1;i++) {
temp=temp.next;
}
node.next=temp.next;
temp.next=node;
}
int getAt(int pos) {
Node temp=head;
for(int i=1;i<=pos;i++) {
temp=temp.next;
}
return temp.data;
}
void display() {
20
2.4 Operations on Singly linked list
Node temp=head;
while(temp!=null) {
System.out.print(temp.data+" --> ");
temp=temp.next;
}
System.out.println();
}
}
public class LinkedListDriver {
public static void main(String[] args) {
LinkedList ll=new LinkedList();
ll.insertAtEnd(4);
ll.insertAtEnd(8);
ll.insertAtEnd(12);
ll.insertAtEnd(5);
ll.insertAtBegin(15);
ll.insertAt(2, 100);
ll.display();
System.out.println("Size="+ll.size());
Java program to create node and assign value using constructor. Link the nodes manually
and use different methods to traverse the node of the linked list
package simplecreate;
class Node{
int data;
Node next;
Node(){}
Node(int data){
this.data=data;
}
}
public class DisplayLinkedList {
//Method to find the length of the linked list
public static int length(Node head) {
int count=0;
while(head!=null) {
count++;
head=head.next;
21
2.4 Operations on Singly linked list
}
return count;
}
//Method to display the linked list
public static void display(Node head) {
Node temp=head;
if(head==null)
return;
while(temp!=null) {
System.out.print(temp.data+"-->");
temp=temp.next;
}
}
//Method for the recursive display of the linked list
public static void recDisplay(Node head) {
if(head==null)
return;
System.out.print(head.data+"-->");
recDisplay(head.next);
}
//Method to reverse display of the linked list using recursive display
public static void reverseDisplay(Node head) {
if(head==null)
return;
reverseDisplay(head.next);
System.out.print(head.data+"-->");
}
public static void main(String[] args) {
Node n1=new Node(5);
Node n2=new Node(3);
Node n3=new Node(2);
Node n4=new Node(7);
Node n5=new Node(10);
22
2.4 Operations on Singly linked list
//Display the Linked list using for loop
System.out.println("\nDisplay the LinkedList using for loop ");
Node temp=n1;
for(int i=0;i<5;i++) {
System.out.print(temp.data+"-->");
temp=temp.next;
}
23
2.4 Operations on Singly linked list
2.4.3 Insertion in Singly Linked List
Insertion operation in a singly linked list can be done in different ways using position.
• Insertion at beginning.
• Insertion at end.
In the following algorithm insertion of node at beginning position is described. The ’_HEAD‘
is a pointer which points to the starting node of the linked list. Node points to the new node.
The following diagrams explain the insertion operation at the beginning of a singly linked
list. At first HEAD points to the first node of the list containing two nodes.
24
2.4 Operations on Singly linked list
Java method to insert a node at the beginning of a linked list
25
2.4 Operations on Singly linked list
2.4.3.3 Insertion of a node at any index position of a single linked list
26
2.4 Operations on Singly linked list
Complete java program to perform node creation and inserction operation in a single
LinkedList
package insertany;
import java.util.Scanner;
class Node{
int regdNo;
float mark;
Node next;
}
public class LinkedList {
//Method to create a Linked List
public static Node createNode(Node head) {
Scanner sc=new Scanner(System.in);
char choice;
do {
Node node=new Node();
Node temp;
System.out.println("Enter Regd.No.");
node.regdNo=sc.nextInt();
System.out.println("Enter mark:");
node.mark=sc.nextFloat();
if(head==null)
head=node;
else {
temp=head;
while(temp.next != null) {
temp=temp.next;
}
temp.next=node;
}
System.out.println("Want to create one more node(y/n) ");
choice=sc.next().charAt(0);
}while(choice==’y’ || choice==’Y’);
return head;
}
//Method to compute the size of the linked list
public static int size(Node head) {
Node temp=head;
int count=0;
while(temp != null) {
count++;
temp=temp.next;
27
2.4 Operations on Singly linked list
}
return count;
}
//Method to display the Linked List
public static void display(Node head) {
Node temp=head;
if(head==null) {
System.out.println("Empty linked list");
return;
}
while(temp != null) {
System.out.print("("+temp.regdNo+", "+temp.mark+")-->");
temp=temp.next;
}
}
//Method to insert a new node at begining of the linked list
public static Node insertAtBeg(Node head) {
Scanner sc=new Scanner(System.in);
Node node=new Node();
System.out.println("Enter mark for new node:");
node.mark=sc.nextFloat();
System.out.println("Enter registration number for new node");
node.regdNo=sc.nextInt();
node.next=head;
head=node;
return head;
}
//Method to insert a new node at end of the linked list
public static Node insertAtEnd(Node head) {
Scanner sc=new Scanner(System.in);
Node node=new Node();
System.out.println("Enter mark for new node:");
node.mark=sc.nextFloat();
System.out.println("Enter registration number for new node");
node.regdNo=sc.nextInt();
node.next=null;
Node temp=head;
while(temp.next != null) {
temp=temp.next;
}
temp.next=node;
return head;
}
28
2.4 Operations on Singly linked list
//Method to insert a new node at any index position of the linked list
public static Node insertAtIndex(Node head) {
Scanner sc=new Scanner(System.in);
Node node=new Node();
Node temp=head;
System.out.println("\nEnter mark for new node:");
node.mark=sc.nextFloat();
System.out.println("Enter registration number for new node:");
node.regdNo=sc.nextInt();
int length=size(head);
29
2.4 Operations on Singly linked list
2.4.4 Delete Node from Single Linked List
Deletion operation in a singly linked list can be done in different ways using position.
Method-1
Method-2
30
2.4 Operations on Singly linked list
prev.next=null;
return head;
}
Method-1
31
2.4 Operations on Singly linked list
return head;
}
package insertop;
import java.util.Scanner;
class Node{
int regdNo;
float mark;
Node next;
}
class LinkedList{
32
2.4 Operations on Singly linked list
33
2.4 Operations on Singly linked list
node.mark=sc.nextInt();
node.next=null;
if(head==null) {
head=node;
}
else {
temp=head;
while(temp.next!=null) {
temp=temp.next;
}
temp.next=node;
}
return head;
}
34
2.4 Operations on Singly linked list
temp=temp.next;
}
System.out.println("Enter the Registration Number: ");
node.regdNo=sc.nextInt();
System.out.println("Enter the Mark: ");
node.mark=sc.nextInt();
node.next=temp.next;
temp.next=node;
}
return head;
}
35
2.4 Operations on Singly linked list
head=prev;
return head;
}
36
2.4 Operations on Singly linked list
}
public class LinkedListInsertDriver {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
LinkedList ll=new LinkedList();
Node head=null;
int option;
while(true) {
System.out.println("0. Exit");
System.out.println("1. Create a Linked List");
System.out.println("2. Display");
System.out.println("3. Insert Node at begin");
System.out.println("4. Insert Node at end");
System.out.println("5. Insert Node at Index position");
System.out.println("6. Search by Registration Number");
System.out.println("7. Reverse Linked List");
System.out.println("8. Delete node from begining of the List");
System.out.println("9. Delete node from end of the List");
System.out.println("10. Delete node at any index of List");
37
2.4 Operations on Singly linked list
break;
case 7:
head=ll.reverse(head);
break;
case 8:
head=ll.deleteBegin(head);
break;
case 9:
head=ll.deleteEnd(head);
break;
case 10:
head=ll.deleteAtAny(head);
break;
default:
System.out.println("Wrong choice");
}
}
}
38
2.5 Doubly LinkedList
2.5 Doubly LinkedList
2.5.1 Create Node in Doubly LinkedList
39
2.5 Doubly LinkedList
2.5.2 Traverse Doubly LinkedList
40
2.5 Doubly LinkedList
2.5.4 Insert Node at Begin of the Doubly LinkedList
Method 2.5.4 Java Method to Insert Node at Begin of the Doubly LinkedList
41
2.5 Doubly LinkedList
}
42
2.5 Doubly LinkedList
43
2.5 Doubly LinkedList
}
return head;
}
package createdl_head;
import java.util.Scanner;
class Node{
int data;
Node prev;
Node next;
Node(){
prev=next=null;
}
}
class LinkedList{
public Node createNodeDL(Node head) {
//System.out.println("Creating linked list.....");
Scanner sc=new Scanner(System.in);
char choice;
do {
Node temp=null;
Node node=new Node();
System.out.println("Enter the item");
node.data=sc.nextInt();
if(head==null) {
head=node;
}
else {
temp=head;
while(temp.next!=null) {
temp=temp.next;
}
temp.next=node;
node.prev=temp;
}
System.out.println("Want to create a node:Y|y");
choice=sc.next().charAt(0);
}while(choice == ’Y’ ||choice == ’y’);
44
2.5 Doubly LinkedList
return head;
}
void displayDL(Node head) {
Node temp=head;
while(temp!=null) {
System.out.print(temp.data+" ");
temp=temp.next;
}
}
//Method to find the size of the doubly linked list
int sizeDL(Node head) {
Node temp=head;
int count=0;
while(temp!=null) {
count++;
temp=temp.next;
}
return count;
}
Node insertAtBeginDL(Node head) {
Scanner sc=new Scanner(System.in);
System.out.println("Insert node at the begining");
Node node=new Node();
System.out.println("Enter the item");
node.data=sc.nextInt();
if(head==null) {
head=node;
}
else {
node.next=head;
head=node;
}
return head;
}
Node insertAtEndDL(Node head) {
Scanner sc=new Scanner(System.in);
System.out.println("Inserting node at end:");
Node temp=null;
Node node=new Node();
System.out.println("Enter the item");
node.data=sc.nextInt();
if(head==null) {
head=node;
45
2.5 Doubly LinkedList
}
else {
temp=head;
while(temp.next!=null) {
temp=temp.next;
}
temp.next=node;
node.prev=temp;
}
return head;
}
Node insertAtIndexDL(Node head) {
Scanner sc=new Scanner(System.in);
Node node=new Node();
System.out.println("Enter the item");
node.data=sc.nextInt();
System.out.println("Enter the position to insert");
int pos=sc.nextInt();
Node temp=head;
for(int i=1;i<pos-1;i++) {
temp=temp.next;
}
node.next=temp.next;
node.prev=temp;
temp.next.prev=node;
temp.next=node;
return head;
}
Node deleteBeginDL(Node head) {
if(head==null) {
System.out.println("Empty list");
return head;
}
else {
System.out.println("Deleting first node: "+head.data);
head=head.next;
head.prev=null;
}
return head;
}
Node deleteEndDL(Node head) {
Node temp=null;
Node ptemp=null;
46
2.5 Doubly LinkedList
if(head==null) {
System.out.println("Empty list");
return head;
}
else {
temp=head;
while(temp.next!=null) {
ptemp=temp;
temp=temp.next;
}
System.out.println("Deleting last node: "+temp.data);
ptemp.next=null;
temp.prev=null;
}
return head;
}
Node deleteAtIndexDL(Node head) {
Scanner sc=new Scanner(System.in);
Node temp=null;
int index;
if(head==null) {
System.out.println("Empty list");
return head;
}
else {
System.out.println("Enter the position to delete:");
index=sc.nextInt();
temp=head;
for(int i=1;i<index-1;i++) {
temp=temp.next;
}
System.out.println("Deleting node at index: "+(index+1)+" data:
"+temp.next.data);
temp.next=temp.next.next;
temp.next.prev=temp;
}
return head;
}
}
public class DoubleLInkedLIstDriver {
47
2.5 Doubly LinkedList
Scanner sc=new Scanner(System.in);
LinkedList ll=new LinkedList();
Node head=null;
int option;
while(true) {
System.out.println("0. Exit");
System.out.println("1. Create a Linked List");
System.out.println("2. Display");
System.out.println("3. Insert Node at begin");
System.out.println("4. Insert Node at end");
System.out.println("5. Insert Node at Index position");
System.out.println("6. Delete node from begining of the List");
System.out.println("7. Delete node from end of the List");
System.out.println("8. Delete node from any position");
System.out.println("7. Reverse Linked List");
48
2.5 Doubly LinkedList
head=ll.deleteEndDL(head);
break;
case 8:
head=ll.deleteAtIndexDL(head);
break;
default:
System.out.println("Wrong choice");
}
}
49
Chapter 3
Stack
3.1 Introduction
• A stack is a one of the most important and useful non-primitive linear data structure in
computer science.
• As all the insertion and deletion in a stack is done from the top of the stack, the lastly
added element will be first to be removed from the stack.
• Real-life examples of the stack are a stack of books, a stack of plates, a stack of cards, a
stack of coins, etc.
Definition: A stack is a sequential collection of objects that are inserted and removed accord-
ing to the last-in, first-out (LIFO) principle.
Note: The most frequently accessed element in the stack is the top most elemental, whereas
the least accessible element is the bottom of the stack.
The stack is an abstract data type since it is defined in terms of operations on it and its im-
plementation is hidden. Therefore, we can implement a stack using either array or linked list.
There are some basic operations that allow us to perform different actions on a stack.
50
3.3 Array Implementation of Stack
• Push: Add an element to the top of a stack
• A pointer called TOP is used to keep track of the top element in the stack.
• When initializing the stack, we set its value to -1 so that we can check if the stack is
empty by comparing TOP == -1.
• On pushing an element, we increase the value of TOP and place the new element in the
position pointed to by TOP
• On popping an element, we return the element pointed to by TOP and reduce its value.
• The top index always keeps track of the last inserted element of the stack, which is the
top of the stack.
• Initially, the top is initialized by -1 (for the zero-based array) when there are no items in
the stack, i.e. stack is empty.
51
3.3 Array Implementation of Stack
class Stack{
Scanner sc=new Scanner(System.in);
int top=-1;
int n;
int stackArr[];
Stack() {
System.out.println("Enter size of the stack array:");
n=sc.nextInt();
stackArr=new int[n];
}
}
boolean isEmpty() {
if(top==-1)
return true;
else
return false;
}
boolean isFull() {
52
3.3 Array Implementation of Stack
if(top==stackArr.length)
return true;
else
return false;
}
void pop() {
if(isEmpty()) {
System.out.println("Stack is empty(Underflow)");
return;
}
else {
System.out.println("Pop element: "+stackArr[top--]);
}
}
void display() {
for(int i=0;i<=top;i++) {
System.out.print(stackArr[i]+" ");
}
System.out.println();
}
Program 3.3.1 Complete Java Program For Stack Operation Using Array
import java.util.Scanner;
class Stack{
53
3.3 Array Implementation of Stack
Scanner sc=new Scanner(System.in);
int top=-1;
int n;
int stackArr[];
Stack() {
System.out.println("Enter size of the stack array:");
n=sc.nextInt();
stackArr=new int[n];
}
boolean isEmpty() {
if(top==-1)
return true;
else
return false;
}
boolean isFull() {
if(top==stackArr.length)
return true;
else
return false;
}
void push(int item) {
if(isFull()) {
System.out.println("Stack is full(Overflow)");
return;
}
else {
stackArr[++top]=item;
}
}
void pop() {
if(isEmpty()) {
System.out.println("Stack is empty(Underflow)");
return;
}
else {
System.out.println("Pop element: "+stackArr[top--]);
}
}
void display() {
for(int i=0;i<=top;i++) {
System.out.print(stackArr[i]+" ");
}
54
3.3 Array Implementation of Stack
System.out.println();
}
}
public class StackDriver {
public static void main(String[] args) {
Stack st=new Stack();
st.push(10);
st.push(8);
st.push(7);
st.push(4);
st.display();
st.pop();
st.display();
}
}
The following program demonstrate the implementation operation using array where the push
and pop method takes the array as argument.
Program 3.3.2 Java Program to demonstrate the Operations on Stack using array
package arraystack;
import java.util.Scanner;
public class ArrayImpStack {
static final int MAX=10; //Capacity of the stack
static boolean isEmpty(int top) {
if(top==-1)
return true;
else
return false;
}
static boolean isFull(int top) {
if(top==MAX-1)
return true;
else
return false;
}
static int push(int S[],int top) {
Scanner sc=new Scanner(System.in);
if(isFull(top)) {
System.out.println("Overflow");
}
55
3.3 Array Implementation of Stack
else {
System.out.println("Enter item:");
int item=sc.nextInt();
S[++top]=item;
}
return top;
}
static int pop(int S[], int top) {
if(isEmpty(top))
System.out.println("Underflow");
else {
System.out.println("pop the top: "+S[top--]);
}
return top;
}
static void display(int S[], int top) {
for(int i=0;i<=top;i++) {
System.out.print(S[i]+" ");
}
System.out.println();
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int stack[]=new int[MAX];
int top=-1;
while(true) {
System.out.println();
System.out.println("0. Exit");
System.out.println("1. Push");
System.out.println("2. Display");
System.out.println("3. Pop");
System.out.println("\nEnter your choice");
int choice=sc.nextInt();
switch(choice) {
case 0:
System.out.println("Exit from Stack Operation");
System.exit(0);
case 1:
top=push(stack,top);
break;
case 2:
System.out.println("The Stack elements are: ");
display(stack, top);
56
3.3 Array Implementation of Stack
break;
case 3:
top=pop(stack, top);
break;
default:
System.out.println("Choice is not matching.....");
break;
}
}
57
3.4 Linked List Implementation of Stack
3.4 Linked List Implementation of Stack
• Another way to represent stack is by using the singly linked list, which is also known as
Linked Stack.
• A linked list is a dynamic data structure and each element of a linked list is a node that
contains a data and a next similar to the linked list.
• The next is a pointer to another node and the data is the value stored in the node.
• All push or pop operations are taking place at the front of the linked list.
• When the stack is empty then HEAD is null. If the stack has at least one node, the first
node is the top of the stack.
• In the push operation, it needs to add a new node to the front of the list.
• The pop operation removes the first node of the linked list when the stack is not empty.
class Node{
int data;
Node next;
}
class Stack{
Node top=null;
int size=0;
public void push(int item) {
Node node=new Node();
node.data=item;
node.next=top;
top=node;
size++;
}
}
58
3.4 Linked List Implementation of Stack
void pop() {
if(top==null) {
System.out.println("Underflow: Stack is empty");
}
System.out.println("Delete top data: "+top.data);
top=top.next;
}
void display() {
Node temp=top;
while(temp != null) {
System.out.print(temp.data);
temp=temp.next;
if(temp != null) {
System.out.print("-->");
}
}
System.out.println();
}
Program 3.4.1 Complete Java Program for Linked List implementation of Stack
class Node{
int data;
Node next;
}
class Stack{
private Node top=null;
private int size=0;
public void push(int item) {
Node node=new Node();
node.data=item;
node.next=top;
top=node;
size++;
}
void display() {
Node temp=top;
while(temp != null) {
System.out.print(temp.data);
59
3.4 Linked List Implementation of Stack
temp=temp.next;
if(temp != null) {
System.out.print("-->");
}
}
System.out.println();
}
int length() {
return size;
}
void pop() {
if(top==null) {
System.out.println("Underflow: Stack is empty");
}
System.out.println("Delete top data: "+top.data);
top=top.next;
}
int peep() {
return top.data;
}
}
public class LinkNodeStack {
public static void main(String[] args) {
Stack st=new Stack();
st.push(5);
st.push(4);
st.push(7);
st.push(3);
st.push(9);
st.push(8);
st.display();
System.out.println("TOP: "+st.peep());
st.pop();
System.out.println("TOP: "+st.peep());
st.display();
}
}
60
3.5 Evaluation of Arithmetic Expressions
3.5 Evaluation of Arithmetic Expressions
• An expression is defined as a number of operands or data items combined with several
operators.
i Infix Notation
ii Prefix Notation
iii Postfix Notation
Op1 operator Op2 where Op1 and Op2 are two operands
• Example: a+b
• In prefix notation, the operations that are to be performed is absolutely determined by the
positions of the operators and operands in the expression.
• Therefore, parentheses are never used when writing expressions in prefix notation.
operator Op1 Op2 where Op1 and Op2 are two operands
• Example: +ab
61
3.6 Converting infix expression to postfix form
3.5.3 Postfix Notation
• In postfix notation, binary operators appear after its two operands. This notation is also
known as Reverse Polish notation.
• Therefore, parentheses are never used when writing expressions in postfix notation. The
general form of the postfix notation is:
Op1 Op2 operator where Op1 and Op2 are two operands
• Example: ab+
• The operators within parentheses having the highest priority will be evaluated first.
• When an expression has two operators with same priority then the expression is evaluated
according to its associativity (left to right or right to left) order.
• The purpose of the stack is to reverse the order of the operators in the expression.
62
3.6 Converting infix expression to postfix form
Algorithm 3.6.1 POSTFIX (Q, P)
[Q is a given infix expression and P is a postfix expression]
1: Push "(" onto stack & add ")" to the end of Q.
2: Scan Q from left to right
3: while S tack , null do
4: If the element is an operand then add it to P.
5: If the element is left parenthesis “(“ then push it onto the stack.
6: If the element is an operator then:
a) Repeatedly pop from stack (until the element on top of the stack has higher or same
precedence than the operator currently scanned) and add it to P.
b) Add the operator to stack.
7: If the element is a right parenthesis ")"then:
a) Repeatedly pop from stack and add to P each operator until a left parenthesis "(" is
found
b) Pop the left parenthesis from the stack.
8: end while
9: Return P
Example 3.6.1 Find the postfix expression of the following infix expression: A + B ∗ C
Add "(" in the Stack and ")" at the end of the expression. It is represented as Initial in the
table and highlighted. The expression will be A + B ∗ C )
Symbol
Sl. No. Stack Postix Expression(P)
Scanned
Initial (
1 A ( A
2 + (+ A
3 B (+ AB
4 * (+* AB
5 C (+* ABC
6 ) Empty Stack ABC*+
Example 3.6.2 Find the postfix expression of the following infix expression: A + B ∗ C/D − E
Add "(" in the Stack and ")" at the end of the expression. It is represented as Initial in the
table and highlighted. The expression will be A + B ∗ C/D − E )
63
3.6 Converting infix expression to postfix form
Symbol
Sl. No. Stack Postix Expression(P)
Scanned
Initial (
1 A ( A
2 + (+ A
3 B (+ AB
4 * (+* AB
5 C (+* ABC
6 / (+/ ABC*
7 D (+/ ABC*D
8 - (- ABC*D/+
9 E (- ABC*D/+E
10 ) Empty Stack ABC*D/+E-
Example 3.6.3 Find the postfix expression of the following infix expression:
Q = A + (B ∗ C − (D/E ↑ F) ∗ G) ∗ H
64
3.6 Converting infix expression to postfix form
65
3.7 Questions
Example 3.6.4 Find the value of following postfix expression: 532 ∗ 8 + ∗
3.7 Questions
1. Convert following infix expression to postfix expression using Stack:
2. Convert following infix expression to postfix expression and evaluate the postfix expres-
sion using Stack
66
Chapter 4
Queue
4.1 Introduction
The queue is also another useful non-primitive linear data structure in computer science. A
real-life example of the queue is line or sequence of people or vehicles awaiting their turn to be
attended to or to proceed.
Definition: A queue is a homogeneous collection of elements in which deletions can take
place only at the front end, known as dequeue and insertions can take place only at the rear end,
known as enqueue.
The element to enter the queue first will be deleted from the queue first. That is why a
queue is called First-In-First-Out (FIFO) system.
Stack Queue
In the stack, items are inserted and deleted at In the queue, items are inserted at one end (called
the one end of the list rear) and deleted at another end (called the front)
Stack is Last-in-First-out system The queue is the First-in-First-out system
class Queue{
int front=-1;
int rear=-1;
int size=0;
int arrQ[]=new int[10];
void enque(int item) {
if(size==arrQ.length-1) {
67
4.2 Array Implementation of Queue
System.out.println("Queue is full");
return;
}
if(front==-1) {
front=rear=0;
arrQ[rear]=item;
}
else {
arrQ[++rear]=item;
}
size++;
}
}
void dequeue() {
int x=arrQ[front];
System.out.println("Remving item: "+x);
front++;
size--;
}
void displayQ() {
for(int i=front;i<=rear;i++) {
System.out.print(arrQ[i]+" ");
}
System.out.println();
}
boolean isEmpty() {
if(size==0) return true;
else return false;
}
boolean isFull(){
if(size==arrQ.length) return true;
else return false;
}
68
4.2 Array Implementation of Queue
Program 4.2.1 Complete Java Program for Operations on Queue
import java.util.Scanner;
class Queue{
int front=-1;
int rear=-1;
int size=0;
int arrQ[];
Queue() {
Scanner sc=new Scanner(System.in);
System.out.println("Enter maximum number of elements");
int n=sc.nextInt();
arrQ=new int[n];
}
void enqueue(int item) {
if(size==arrQ.length) {
System.out.println("Queue is full");
return;
}
if(front==-1) {
front=rear=0;
arrQ[rear]=item;
}
else {
arrQ[++rear]=item;
}
size++;
}
void dequeue() {
int x=arrQ[front];
System.out.println("Removing item: "+x);
front++;
size--;
}
boolean isEmpty() {
if(size==0) return true;
else return false;
}
void displayQ() {
for(int i=front;i<=rear;i++) {
System.out.print(arrQ[i]+" ");
}
System.out.println();
69
4.2 Array Implementation of Queue
}
}
public class QueueArray {
public static void main(String[] args) {
Queue q=new Queue();
System.out.println("size = "+q.size);
q.enqueue(1);
q.enqueue(2);
q.enqueue(3);
q.enqueue(4);
q.displayQ();
System.out.println("size = "+q.size);
q.dequeue();
q.displayQ();
System.out.println("size = "+q.size);
}
}
Output:
Enter maximum number of elements in the Queue
10
size = 0
1
2
3
4
size = 4
Removing item: 1
2
3
4
size = 3
Program 4.2.2
70
4.3 LinkedList Implementation of Queue
4.3 LinkedList Implementation of Queue
• Singly linked list can be used to represent a queue, which is also known as Linked
Queue.
• In this representation, any number of data items can be inserted and deleted.
• The front and rear pointers always keep track of the first node and the last node in the
linked list respectively.
• Initially, front and rear are initialized by null (i.e. front = rear = null), when there are
no items in the queue, that means the queue is empty.
• All insertion operations take place at the end of the Linked queue.
• If the queue contains a single element then front and rear points to new node (i.e. front =
rear = node).
• When a new item is inserted in the queue, a new node is inserted at the end of the linked
list, the rear points to the new node.
• When an item is deleted from the queue, the node from the front of the queue is deleted.
• Now, if front = null then if we try to delete an item, it results in underflow condition. It
indicates that the queue is empty and we cannot delete an item.
• Whenever the queue is found empty, we can reset the front and rear by null.
• The front and rear node reference acting as a pointers in linked list consume additional
memory compared to an array.
• In array implementation, sometimes dequeue operation not possible, although there are
free slots. This drawback can be overcome in linked list representation.
• In array and linked list enqueue and dequeue operations can be done in O(1).
71
4.5 Operations on Queue using Linked List
4.5 Operations on Queue using Linked List
Method 4.5.1 Enqueue operation
class Node{
int data;
Node next;
}
class Queue{
Node front=null; // It is head
Node rear=null; // It is tail
int size=0;
boolean isEmpty() {
if(size==0) return true;
else return false;
72
4.5 Operations on Queue using Linked List
}
void enqueue(int item) {
Node node=new Node();
node.data=item;
node.next=null;
if(rear==null)
front=rear=node;
else {
rear.next=node;
rear=node;
}
size++;
}
void dequeue() {
if(isEmpty()) {
System.out.println("Queue is empty");
return;
}
int x=front.data;
System.out.println("Removing item: "+x);
front=front.next;
size--;
}
void displayQ() {
Node temp=front;
if(size==0) {
System.out.println("No element in the Queue");
return;
}
while(temp != null) {
System.out.print(temp.data+" ");
temp=temp.next;
}
System.out.println();
}
}
public class LinkedQueue {
public static void main(String[] args) {
Queue q=new Queue();
q.displayQ();
System.out.println("size = "+q.size);
q.enqueue(1);
q.enqueue(2);
73
4.5 Operations on Queue using Linked List
q.enqueue(3);
q.enqueue(4);
q.displayQ();
System.out.println("size = "+q.size);
q.dequeue();
q.displayQ();
System.out.println("size = "+q.size);
}
}
Output:
No element in the Queue
size = 0
1 2 3 4
size = 4
Removing item: 1
2 3 4
size = 3
74
4.5 Operations on Queue using Linked List
Appendix Title Here
Write your Appendix content here.
75