0% found this document useful (0 votes)
206 views83 pages

DS Lab Manual

The document is a lab manual for a data structures course. It outlines 14 labs that students will complete, covering topics like arrays, linked lists, stacks, queues, trees, graphs and various sorting algorithms. It also provides learning outcomes for the course and general lab safety procedures and guidelines for students.

Uploaded by

usama sarwer
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)
206 views83 pages

DS Lab Manual

The document is a lab manual for a data structures course. It outlines 14 labs that students will complete, covering topics like arrays, linked lists, stacks, queues, trees, graphs and various sorting algorithms. It also provides learning outcomes for the course and general lab safety procedures and guidelines for students.

Uploaded by

usama sarwer
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/ 83

1

Data Structures
Lab Manual

NAME: _____________________________________

ID: ________________________________________

SECTION: __________________________________

DEGREE: ___________________________________

IQRA UNIVERSITY,

IQRA University, Main Campus, Karachi


2

Data Structure
(LIST OF LABS)
Lab #1_____________________________________________________________5
Revision of Object Oriented Programming in Java (Part 1)
 Class and Object
 Constructor and Methods
 Access Control
 Passing Argument by reference.

Lab # 2_____________________________________________________________10
Revision of Object Oriented Programming in Java (Part 2)
 Arrays in Java
o Searching values in java
 Binary Search & Linear Search
o Sorting Array
o Matrix Multiplication Using 2D Arrays
 Generic Class in Java

Lab # 3____________________________________________________________16
Evaluate buit-in Arraylist and Vector and also develop Array List Using Generic
Array in Java Programming Language.

Lab # 4___________________________________________________________ 21

Develop Basic (Singly), doubly and Circular Linked List in Java.

Lab # 5____________________________________________________________ 29
Understand Recursion technique in java.

Lab # 6____________________________________________________________32
Develop Stack & Queue Using Generic Array in Java Programming Language

Lab # 7____________________________________________________________37

Implement insertion sorting ,bubble sorting and selection sorting in java

Lab # 8____________________________________________________________41

IQRA University, Main Campus, Karachi


3

Implement Divide & Conquer approach for sorting in java.

Lab # 9_____________________________________________________________47

Develop Binary Search Tree and implement in-order, post-order, pre-order traversing
techniques.

Lab # 10_____________________________________________________________54

Perform insert operation on AVL Tree.

Lab # 11_____________________________________________________________59

Perform delete operation on AVL Tree.

Lab # 12_____________________________________________________________65
Implement Hash Table in java.

Lab # 13____________________________________________________________68
Using HashTable and LinkedList Class, Develop HashMap in Java

Lab # 14____________________________________________________________75

Implementation of graph in Java

IQRA University, Main Campus, Karachi


4

Learning Outcomes:

Sr. No Course Learning Outcomes


Implement various data structures and their algorithms, and
LO_1
apply them in implementing simple applications.
Analyze simple algorithms and determine their
LO_2
complexities
Apply the knowledge of data structures to other application
LO_3 domains.
Design new data structures and algorithms to solve
LO_4 problems.
Ability to describe stack, queue,link list,graphs and tree concepts also summrize
LO_5 searching and sorting techniques

IQRA University, Main Campus, Karachi


5

FACULTY OF ENGINEERING SCIENCES AND TECHNOLOGY


General Laboratory Procedure
While there is no specific document to be submitted at the beginning of the Lab –unless your
instructor advises you otherwise-, you are expected to read the experiment fully before you
come to the laboratory? Interestingly, you can even try parts of the experiment at home. Here is
a list of programs that will equip you with a virtual lab at your home:
Troubleshooting
Things will not always go as expected; this is the nature of the learning process. While
conducting the Experiment think before you do anything. If you do so you will avoid wasting
time going down dead-end streets. Be logical and systematic. First, look for obvious errors that
are easy to fix. Is your measuring device correctly set and connected? Are you looking at the
proper scale? Is the power supply set for the correct voltage? Is the signal generator correctly
set and connected? How are the variables in the code set? Is there a syntax error? And so on.
Next, check for obvious misconnections or broken connections, at least in simple circuits.
As you work through your circuit, use your Lab Manual record tests and changes that you make
as you go along; don't rely on your memory for what you have tried. Identify some test points
in the system at which you know what the signal should be and work your way backwards from
the output through the test points until you find a good signal. Neatness
When you have finished for the day, return all modules to their proper storage bins, return all
test leads and probes to their storage racks, return all equipment to its correct location, and
clean up the lab station. If appropriate switch off the unneeded equipment. Save your files in
the Computer and on any USB device for your records because you might not get the same PC
System again for the next experiment. Also email your file contents to your email address as a
backup.
Laboratory Safety

Always pay attention to what you are doing and you’re surrounding during the experiments,
notify the Instructor for any unlikely event or mishap, and leave the Laboratory with the
permission of Instructor immediately.
All students must read and understand the information in this document with regard to
laboratory safety and emergency procedures prior to the first laboratory session.
Your personal laboratory safety depends mostly on YOU. Efforts have been made to
address situations that may pose a hazard in the lab but the information and instructions
provided cannot be considered allinclusive.
Students must adhere to written and verbal safety instructions throughout the academic term.
Since additional instructions may be given at the beginning of laboratory sessions, it is
important that all students arrive at each session on time. With good judgment, the chance of
an accident in this course is very small. Nevertheless, research and teaching workplaces (labs,
shops, etc.) are full of potential hazards that can cause serious injury and or damage to the
equipment. Working alone and unsupervised in laboratories is forbidden if you are working
with hazardous substances or equipment. With prior approval, at least two people should be
present so that one can shut down equipment and call for help in the event of an emergency.
Safety training and/or information should be provided by a faculty member, teaching assistant,

IQRA University, Main Campus, Karachi


6

lab safety contact, or staff member at the beginning of a new assignment or when a new hazard
is introduced into the workplace.
Emergency Response
1. It is your responsibility to read safety and fire alarm posters and follow the instructions
during an emergency
2. Know the location of the fire extinguisher, eye wash, and safety shower in your lab and
know how to use them.
3. Notify your instructor immediately after any injury, fire or explosion, or spill.
4. Know the building evacuation procedures.
Common Sense
Good common sense is needed for safety in a laboratory. It is expected that each student will
work in a responsible manner and exercise good judgment and common sense. If at any time
you are not sure how to handle a particular situation, ask your Teaching Assistant or Instructor
for advice DO NOT TOUCH ANYTHING WITH WHICH YOU ARE NOT
COMPLETELY FAMILIAR!!! It is always better to ask questions than to risk harm to
yourself or damage to the equipment.
Personal and General laboratory safety
1. Never eat, drink, or smoke while working in the laboratory.
2. Read labels carefully.
3. Do not use any equipment unless you are trained and approved as a user by your supervisor.
4. Wear safety glasses or face shields when working with hazardous materials and/or
equipment.
5. Wear gloves when using any hazardous or toxic agent.
6. Clothing: When handling dangerous substances, wear gloves, laboratory coats, and safety
shield or glasses. Shorts and sandals should not be worn in the lab at any time. Shoes are
required when working in the machine shops.
7. If you have long hair or loose clothes, make sure it is tied back or confined.
8. Keep the work area clear of all materials except those needed for your work. Coats should
be hung in the hall or placed in a locker. Extra books, purses, etc. should be kept away from
equipment that requires air flow or ventilation to prevent overheating.
9. Disposal - Students are responsible for the proper disposal of used material if any in
appropriate containers.
10. Equipment Failure - If a piece of equipment fails while being used, report it
immediately to your lab assistant or tutor. Never try to fix the problem yourself because you
could harm yourself and others.
11. If leaving a lab unattended, turn off all ignition sources and lock the doors.
12. Never pipette anything by mouth.
13. Clean up your work area before leaving.
14. Wash hands before leaving the lab and before eating.
15. Unauthorized person(s) shall not be allowed in a laboratory for any reason Electrical
safety
1. Obtain permission before operating any high voltage equipment.
2. Maintain an unobstructed access to all electrical panels.
3. Wiring or other electrical modifications must be referred to the Electronics Shop or the
Building Coordinator.
4. Avoid using extension cords whenever possible. If you must use one, obtain a heavy- duty
one that is electrically grounded, with its own fuse, and install it safely. Extension cords
should not go under doors, across aisles, be hung from the ceiling, or plugged into other
extension cords.
5. Never, ever modify, attach or otherwise change any high voltage equipment.
6. Always make sure all capacitors are discharged (using a grounded cable with an insulating
handle) before touching high voltage leads or the "inside" of any equipment even after it has

IQRA University, Main Campus, Karachi


7

been turned off. Capacitors can hold charge for many hours after the equipment has been
turned off.
7. When you are adjusting any high voltage equipment or a laser which is powered with a high
voltage supply, USE ONLY ONE HAND. Your other hand is best placed in a pocket or
behind your back. This procedure eliminates the possibility of an accident where high
voltage current flows up one arm, through your chest, and down the other arm.
8. Discard damaged cords, cords that become hot, or cords with exposed wiring.
9. Before equipment is energized ensure, (1) circuit connections and layout have been checked
by a Teaching Assistant (TA) and (2) all colleagues in your group give their assent.
10.Know the correct handling, storage and disposal procedures for batteries, cells, capacitors,
inductors and other high energy-storage devices.
11.Experiments left unattended should be isolated from the power supplies. If for a special
reason, it must be left on, a barrier and a warning notice are required.
12.Equipment found to be faulty in any way should be reported to the Lab Engineer
immediately and taken out of service until inspected and declared safe.
13.Voltages above 50 V rms AC and 120 V DC are always dangerous. Extra precautions should
be considered as voltage levels are increased.
14.Never make any changes to circuits or mechanical layout without first isolating the circuit
by switching off and removing connections to power supplies.
15.Know what you must do in an emergency.
16.Emergency Power Off: Every lab is equipped with and Emergency Power Off System.
17.Only authorized personnel are permitted to reset power once the Emergency Power Off
system has been engaged.
Electrical Emergency Response
The following instructions provide guidelines for handling two types of electrical emergencies:
1. When someone suffers serious electrical shock, he or she may be knocked unconscious. If
the victim is still in contact with the electrical current, immediately turn off the electrical
power source. If you cannot disconnect the power source, depress the Emergency Power Off
switch.
2. Do not touch a victim that is still in contact with a live power source; you could be
electrocuted.
3. Have someone call for emergency medical assistance immediately. Administer first-aid, as
appropriate.
4. If an electrical fire occurs, try to disconnect the electrical power source, if possible. If the
fire is small and you are not in immediate danger; and you have been properly trained in
fighting fires, use the correct type of fire extinguisher to extinguish the fire. When in doubt,
push in the Emergency Power Off button.
5. NEVER use water to extinguish an electrical fire. Mechanical safety
1. When using compressed air, use only approved nozzles and never direct the air towards any
person.
2. Guards on machinery must be in place during operation.
3. Exercise care when working with or near hydraulically- or pneumatically-driven equipment.
Sudden or unexpected motion can inflict serious injury. Additional Safety
Guidelines 1. Never do unauthorized experiments.
2. Never work alone in laboratory.
3. Keep your lab space clean and organized.
4. Do not leave an on-going experiment unattended.
5. Always inform your instructor if you break a thermometer. Do not clean mercury
yourself!!
6. Never taste anything. Never pipette by mouth; use a bulb.
7. Never use open flames in laboratory unless instructed by TA.
8. Check your glassware for cracks and chips each time you use it. Cracks could cause
the glassware to fail during use and cause serious injury to you or lab mates.

IQRA University, Main Campus, Karachi


8

9. Maintain unobstructed access to all exits, fire extinguishers, electrical panels, emergency
showers, and eye washes.
10. Do not use corridors for storage or work areas.
11. Do not store heavy items above table height. Any overhead storage of supplies on top
of cabinets should be limited to lightweight items only. Also, remember that a 36" diameter
area around all fire sprinkler heads must be kept clear at all times.
12. Areas containing lasers, biohazards, radioisotopes, and carcinogens should be posted
accordingly. However, do not post areas unnecessarily and be sure that the labels are
removed when the hazards are no longer present.
13. Be careful when lifting heavy objects. Only shop staff may operate forklifts or cranes.
14. Clean your lab bench and equipment, and lock the door before you leave the
laboratory. Clothing
1. Dress properly during a laboratory activity.
2. Long hair, dangling jewelry, and loose or baggy clothing are a hazard in the laboratory.
3. Long hair must be tied back, and dangling jewelry and baggy clothing
must be secured.
4. Shoes must completely cover the foot.
5. No sandals allowed on lab days.
6. A lab coat or smock should be worn during laboratory experiments.
Accidents and Injuries 1. Do not panic.
2.Report any accident (spill, breakage, etc.) or injury (cut, burn, etc.) to the
teacher immediately, no matter how trivial it seems.
3.If you or your lab partner is hurt, immediately (and loudly) yell out the
teacher's name to get the teacher's attention.

General Warning Signs

IQRA University, Main Campus, Karachi


9

Data Structures
LAB-1

Name ____________________
Roll No ___________________
Date ______________________
Marks Obtained ____________
Signature___________________

IQRA University, Main Campus, Karachi


10

Revision of Object Oriented Programming in Java (Part 1)

Objective:
 Class and Object
 Constructor and Methods
 Access Control
 Passing Argument by reference.

CLASS & OBJECT:


In more complex Java programs, the primary “actors” are objects. Every object is an instance
of a class, which serves as the type of the object and as a blueprint, defining the data which
the object stores and the methods for accessing and modifying that data. The critical
members of a class in Java are the following:

Instance variables:
Which are also called fields, represent the data associated with an object of a class. Instance
variables must have a type, which can either be a base type (such as int, float, or double) or
any class type (also known as a reference type for reasons we soon explain).

Methods:
in Java are blocks of code that can be called to perform actions (similar to functions and
procedures in other high-level languages). Methods can accept parameters as arguments, and
their behavior may depend on the object upon which they are invoked and the values of any
parameters that are passed. A method that returns information to the caller without changing
any instance variables is known as an accessor method, while an update.

Example
public class Counter { 2 private int count; // a simple integer instance variable
public Counter( ) { } // default constructor (count is 0)
public Counter(int initial) { count = initial; } // an alternate constructor
public int getCount( ) { return count; } // an accessor method
public void increment( ) { count++; } // an update method
public void increment(int delta) { count += delta; } // an update method
public void reset( ) { count = 0; } // an update method

Access Control:

The access modifiers in java specify accessibility (scope) of a data member, method,
constructor or class.There are 4 types of java access modifiers:

1. Private

IQRA University, Main Campus, Karachi


11

2. default
3. protected
4. public
Methods:
Methods in Java are conceptually similar to functions and procedures in other highlevel languages. In
general, they are "chunks" of code that can be called on a particular object (from some class).
Methods can accept parameters as arguments, and their behavior depends on the object they belong to
and the values of any parameters that are passed. Every method in Java is specified in the body of
some class. A method definition has two parts: the signature, which defines the and parameters for a
method, and the body, which defines what the method does.

The syntax for defining a method is as follows:

modifiers type name(type0 parameter0, …, typen−1 parametern−1) {

// method body …

Constructors:
A constructor is a special kind of method that is used to initialize newly created objects. Java has a
special way to declare the constructor and a special way to invoke the constructor. First, let's look at
the syntax for declaring a constructor.

Class demo{

modifiers demo(type0 parameter0, …, typen−1 parametern−1) {

// constructor body …

Creating an Object:
As mentioned previously, a class provides the blueprints for objects. So basically, an object
is created from a class. In Java, the new keyword is used to create new objects.

public class CounterDemo {

public static void main(String[ ] args)


{
Counter c; // declares a variable; no counter yet constructed

IQRA University, Main Campus, Karachi


12

c = new Counter( ); // constructs a counter; assigns its reference to c


c.increment( ); // increases its value by one
c.increment(3); // increases its value by three more
int temp = c.getCount( ); // will be 4
c.reset( ); // value becomes 0
Counter d = new Counter(5);// declares and constructs a counter having value 5
d.increment( ); // value becomes 6
Counter e = d; // assigns e to reference the same object as d
temp = e.getCount( ); // will be 6 (as e and d reference the same counter)
e.increment(2); // value of e (also known as d) becomes 8
}
}

Pass by value - In this case actual parameter is evaluated and its value is copied into memory
(stack) used by the parameters of the method.

Pass by reference - In this case the memory address of the actual parameter is copied in the
parameter of the method. Thus anytime method is using its parameter it is actually using the
actual parameter.

Lab Tasks 1:

Develop Java Class IU_Mark_Sheet with following Constructor and Methods.

Constructor:
 IU_Mark_Sheet(String Student, String Registration Number);

Methods:
 Void Subject_Name(String Subject[]);
 Void Subject_Max_Mark(double MaxMark[]);
 Void Subject_Scored_Mark(double ScoredMark[]);
 Double StudentGPA();

Assignment:
Program Statement:

You are required to model a vehicle parking lot system. The parking lot has a facility to park
cars and scooters. The parking lot contains four parking lanes-two for cars and two for
scooters.

IQRA University, Main Campus, Karachi


13

Each lane can hold ten vehicles. There is an operator with a console at the East end of the
parking lot. The system should be able to handle following scenarios.

Arrival of a vehicle:

1. Type of vehicle (car or scooter) and Registration No. of vehicle should be entered

2. Program should display suitable parking slot

3. Vehicles arrive at East end, leave from West end

Departure of Car:

1. If not western most, all cars should be moved to the west

2. When the car is driven out, rest of the cars should be moved to the left

3. Vehicle data should be updated

Departure of Scooter:

1. Scooters should be able to drive out at random

2. Vehicle data should be updated

Note that when desired the operator must be able to obtain information like number of
vehicles, number of scooters or number of cars currently parked in the parking lot. Also, the
system should be able to display all the parking lots (currently occupied) if desired.

IQRA University, Main Campus, Karachi


14

Data Structures

LAB-2

Name ____________________
Roll No ___________________
Date ______________________
Marks Obtained ____________
Signature___________________

IQRA University, Main Campus, Karachi


15

Revision of Object Oriented Programming in Java (Part 2)

Objective:
 Arrays in Java
o Searching values in java
o Sorting Array
o Vector Multiplication Using two integer Arrays
 Generic Class in Java
Array in Java:
Java provides a data structure, the  array, keep track of an ordered sequence of related values or
objects. For example, we may want a video game to keep track of the top ten scores for that
game. Rather than using ten different variables for this task, we would prefer to use a single name
for the group and use index numbers to refer to the high scores in that group. Similarly, we may
want a medical information system to keep track of the patients currently assigned to beds in a
certain hospital. Again, we would rather not have to introduce 200 variables in our program just
because the hospital has 200 beds.
Example:
The following code snippets are examples of this syntax −

double[] IUList;// preferred way.


or
double IUList[];// works but not preferred way.

Following statement declares an array variable, myList, creates an array of 10 elements of


double type and assigns its reference to myList –

double[] IUList = new double[10];


Here is a complete example showing how to create, initialize, and process arrays −

public class TestArray {

public static void main(String[] args) {


double[] IUList = {1.9, 2.9, 3.4, 3.5};

// Print all the array elements


for (int i = 0; i < IUList.length; i++) {
System.out.println(IUList[i] + " ");
}

// Summing all elements


double total = 0;
for (int i = 0; i < IUList.length; i++) {
total += IUList[i];
}
System.out.println("Total is " + total);

IQRA University, Main Campus, Karachi


16

// Finding the largest element


double max = IUList[0];
for (int i = 1; i < IUList.length; i++) {
if (IUList[i] > max) max = IUList[i];
}
System.out.println("Max is " + max);
}
}

Passing Arrays to Methods:


Just as you can pass primitive type values to methods, you can also pass arrays to methods.
For example, the following method displays the elements in an int array –

Example
public static void printArray(int[] array){
for(int i =0; i < array.length; i++){
System.out.print(array[i]+" ");
}
}

Lab Tasks 1:

 Develop Method in java which can find the smallest and the largest value from integer
Array.
o int[] TwoExtreamValue(int A[]).
 Develop Method in java which can sort integer array using bubble sort.
o Int[] SortArray(int A[]).

 Vector Multiplication Using two integer Arrays


o int VectorMultiplication(int A[],int B[]).

Binary Search and Linear Search:

In this section, we describe a classic recursive algorithm, binary search, used to efficiently
locate a target value within a sorted sequence of n elements stored in an array. This is among
the most important of computer algorithms, and it is the reason that we so often store data in
sorted order.

When the sequence is unsorted, the standard approach to search for a target value is to use a
loop to examine every element, until either finding the target or exhausting the data set. This
algorithm is known as linear search, or sequential search, and it runs in O(n) time (i.e.,
linear time) since every element is inspected in the worst case.

///** Implementaion of Linar search on an Unsorted array

IQRA University, Main Campus, Karachi


17

import java.util.Scanner;

public class LinearSearch {


public static void main(String[] args) {
int[] arr = {5, 6, 1, 10, 7, 11, 14};
int item,flag=0;
Scanner sc = new Scanner(System.in);
System.out.println("Enter Item ?");
item = sc.nextInt();
for(int i = 0; i<10; i++)
{
if(arr[i]==item)
{
flag = i+1;
break;
}
else
flag = 0;
}
if(flag != 0)
{
System.out.println("Item found at location" + flag);
}
else
System.out.println("Item not found");

}
}

/** Implementaion of Binary search on a Sorted array


* Returns true if the target value is found in the indicated portion of the data
array.
* This search only considers the array portion from data[low] to data[high]
inclusive.
*/
public static boolean binarySearch(int[ ] data, int target, int low, int high) {
if (low > high)
return false; // interval empty; no match
else {
int mid = (low + high) / 2;
if (target == data[mid])
return true; // found a match
else if (target < data[mid])
return binarySearch(data, target, low, mid − 1); // recur left of the middle
else
return binarySearch(data, target, mid + 1, high); // recur right of the middle
}
}

IQRA University, Main Campus, Karachi


18

Generic Classes:
Java includes a generics framework for using abstract types in a way that avoids many
explicit casts. A generic type is a type that is not defined at compilation time, but becomes
fully specified at run time. The generics framework allows us to define a class in terms of a
set of formal type parameters, with could be used, for example, to abstract the types of some
internal variables of the class. Angle brackets are used to enclose the list of formal type
parameters. Although any valid identifier can be used for a formal type parameter, single-
letter uppercase names are conventionally used. Given a class that has been defined with
such parameterized types, we instantiate an object of this class by using actual type
parameters to indicate the concrete types to be used .

Following example illustrates how we can define a generic class −

public classBox<T>{
private T t;

public void add(T t){


this.t = t;
}

public T get(){
return t;
}

public static void main(String[] args){


Box<Integer> integerBox =new Box<Integer>();
Box<String> stringBox =new Box<String>();

integerBox.add(newInteger(10));
stringBox.add(newString("Hello World"));

System.out.printf("Integer Value :%d\n\n", integerBox.get());


System.out.printf("String Value :%s\n", stringBox.get());
}
}
This will produce the following result −

Output
Integer Value :10
String Value :Hello World

IQRA University, Main Campus, Karachi


19

Lab Tasks 2:

Develop Generic Class which can set Data type of Single dimension array.

Reading Assignment:
Read the following fundamental concept of object oriented programming language.

1. Abstraction and Interface


2. Inheritance and Polymorphism

IQRA University, Main Campus, Karachi


20

Data Structures

LAB-3

Name ____________________
Roll No ___________________
Date ______________________
Marks Obtained ____________
Signature___________________

IQRA University, Main Campus, Karachi


21

Evaluate buit-in Arraylist and Vector and develop Array List


Using Generic Array in Java Programming Language.

Objective:
 ArrayList
 Vector
ArrayList::

The ArrayList class extends AbstractList and implements the List interface. ArrayList
supports dynamic arrays that can grow as needed.

Standard Java arrays are of a fixed length. After arrays are created, they cannot grow or
shrink, which means that you must know in advance how many elements an array will hold.

Array lists are created with an initial size. When this size is exceeded, the collection is
automatically enlarged. When objects are removed, the array may be shrunk.

The Vector:

The Vector class is similar to a traditional Java array, except that it can grow as necessary to
accommodate new elements.

Like an array, elements of a Vector object can be accessed via an index into the vector.

Buit-in Vector supports the following fundamental methods:

 Vector( ): This constructor builds an empty array list.


 Vector(int capacity): This constructor builds an array list that has the specified
initial capacity.
 void add(int index, Object element): Inserts the specified element at the specified
position index in this list. 
 boolean add(Object o) :Appends the specified element to the end of this list.
 void clear() :Removes all of the elements from this list.
 boolean contains(Object o) :Returns true if this list contains the specified element.
 Object get(int index) :Returns the element at the specified position in this list.
 int indexOf(Object o) :Returns the index in this list of the first occurrence of the
specified element, or -1 if the List does not contain this element.
 Object remove(int index) :Removes the element at the specified position in this list.

IQRA University, Main Campus, Karachi


22

 int size(): Returns the number of elements in this list.


 Object[] toArray(Object[] a) :Returns an array containing all of the elements in this
list in the correct order; the runtime type of the returned array is that of the specified
array.
 void trimToSize() :Trims the capacity of this ArrayList instance to be the list's
current size.

Buit-in ArrayList supports the following fundamental methods:

 ArrayList( ): This constructor builds an empty array list.


 ArrayList(int capacity): This constructor builds an array list that has the specified
initial capacity.
 void add(int index, Object element): Inserts the specified element at the specified
position index in this list. 
 boolean add(Object o) :Appends the specified element to the end of this list.
 void clear() :Removes all of the elements from this list.
 boolean contains(Object o) :Returns true if this list contains the specified element.
 Object get(int index) :Returns the element at the specified position in this list.
 int indexOf(Object o) :Returns the index in this list of the first occurrence of the
specified element, or -1 if the List does not contain this element.
 Object remove(int index) :Removes the element at the specified position in this list.
 int size() :Returns the number of elements in this list.
 Object[] toArray(Object[] a) :Returns an array containing all of the elements in this
list in the correct order; the runtime type of the returned array is that of the specified
array.
 void trimToSize() :Trims the capacity of this ArrayList instance to be the list's
current size.

IQRA University, Main Campus, Karachi


23

Task 1:

Develop your own ArrayList in Java having following methods:

 add ()
 remove()
 get()
 contain()
 is_empty()
 IndexOff()
 ToArray()
 TrimToSize()

Basic Code:
1. public class CreateArraylist<T>
2. {
3. private T[] asArray;
4. @SuppressWarnings("unchecked")
5. public CreateArraylist()
6. {
7. asArray=(T[]) new Object[0];
8. }
9. public void add(T t)
10. {
11. @SuppressWarnings("unchecked")
12. T[] temp =(T[]) new Object[asArray.length +1];
13.
14. // copy everything over to the new array
15. for(int i =0; i < asArray.length; i++)
16. {
17. temp[i]= asArray[i];
18. }
19.
20. // add the new element
21. temp[asArray.length]= t;
22. asArray= temp;
23. }
24.
25. public void remove(int index)
26. {
27. if(index <0|| index >= asArray.length)return;
28. @SuppressWarnings("unchecked")
29. T[] temp =(T[]) new Object[asArray.length -1];
30.
31. boolean found =false;

IQRA University, Main Campus, Karachi


24

32. // copy everything over to the new element


33. for(int i =0; i < asArray.length; i++)
34. {
35. // don't copy if the indices are the same
36. if(i == index)
37. {
38. found=true;
39. continue;
40. }
41. temp[i -(found ?1:0)]= asArray[i];// it's i - 1 after the removed object so
then it doesn't leave a gap and it doesn't go over the array's length
42. }
43. asArray= temp;
44. }
45.
46. public T get(int index)
47. {
48. return asArray[index];
49. }
50. }

IQRA University, Main Campus, Karachi


25

Data Structures

LAB-4

Name ____________________
Roll No ___________________
Date ______________________
Marks Obtained ____________
Signature___________________

IQRA University, Main Campus, Karachi


26

Linked List

Objective:
Develop Basic (Singly) , doubly and Circular Linked List in Java.

Description:
A linked list, in its simplest form, is a collection of nodes that together form a linear ordering.
The ordering is determined as in the children's game "Follow the Leader," in that each node is an
object that stores a reference to an element and a reference, called next, to another node.

Example of a singly linked list

Implementing a Singly Linked List Class

In this section, we present a complete implementation of a SinglyLinkedList class, supporting the


following methods:
size( ): Returns the number of elements in the list.
isEmpty( ): Returns true if the list is empty, and false otherwise.
first( ): Returns (but does not remove) the first element in the list.
last( ): Returns (but does not remove) the last element in the list.
addFirst(e): Adds a new element to the front of the list.
addLast(e): Adds a new element to the end of the list.
removeFirst( ): Removes and returns the first element of the list.

public class LinkedList


{
// reference to the head node.
private Node head;
private int listCount;

// LinkedList constructor
public LinkedList()
{

IQRA University, Main Campus, Karachi


27

// this is an empty list, so the reference to the head node


// is set to a new node with no data
head = new Node(null);
listCount = 0;
}

public void add(Object data)


// post: appends the specified element to the end of this list.
{
Node temp = new Node(data);
Node current = head;
// starting at the head node, crawl to the end of the list
while(current.getNext() != null)
{
current = current.getNext();
}
// the last node's "next" reference set to our new node
current.setNext(temp);
listCount++;// increment the number of elements variable
}

public void add(Object data, int index)


// post: inserts the specified element at the specified position in this
list.
{
Node temp = new Node(data);
Node current = head;
// crawl to the requested index or the last element in the list,
// whichever comes first
for(int i = 1; i < index && current.getNext() != null; i++)
{
current = current.getNext();
}
// set the new node's next-node reference to this node's next-node
reference
temp.setNext(current.getNext());
// now set this node's next-node reference to the new node
current.setNext(temp);
listCount++;// increment the number of elements variable
}

public Object get(int index)


// post: returns the element at the specified position in this list.
{
// index must be 1 or higher
if(index <= 0)
return null;

Node current = head.getNext();


for(int i = 1; i < index; i++)
{
if(current.getNext() == null)
return null;

current = current.getNext();

IQRA University, Main Campus, Karachi


28

}
return current.getData();
}

public boolean remove(int index)


// post: removes the element at the specified position in this list.
{
// if the index is out of range, exit
if(index < 1 || index > size())
return false;

Node current = head;


for(int i = 1; i < index; i++)
{
if(current.getNext() == null)
return false;

current = current.getNext();
}
current.setNext(current.getNext().getNext());
listCount--; // decrement the number of elements variable
return true;
}

public int size()


// post: returns the number of elements in this list.
{
return listCount;
}

public String toString()


{
Node current = head.getNext();
String output = "";
while(current != null)
{
output += "[" + current.getData().toString() + "]";
current = current.getNext();
}
return output;
}

private class Node


{
// reference to the next node in the chain,
// or null if there isn't one.
Node next;
// data carried by this node.
// could be of any type you need.
Object data;

// Node constructor
public Node(Object _data)

IQRA University, Main Campus, Karachi


29

{
next = null;
data = _data;
}

// another Node constructor if we want to


// specify the node to point to.
public Node(Object _data, Node _next)
{
next = _next;
data = _data;
}

// these methods should be self-explanatory


public Object getData()
{
return data;
}

public void setData(Object _data)


{
data = _data;
}

public Node getNext()


{
return next;
}

public void setNext(Node _next)


{
next = _next;
}
}
}

Doubly Linked List:


Doubly linked list allows us to go in both directions (Forward and reverse) in a linked list and
allow for a great variety of quick update operations, including insertion and removal at both
ends, and in the middle. A node in a doubly linked list stores two references—a next link
which points to the next node in the list, and a prev link, which points to the previous node in
the list.

IQRA University, Main Campus, Karachi


30

Code Example:
public class DoublyLinkList<T>{

private static classNode<T>{


private T data;
private Node next;
private Node prev;

public Node(T data){


this.data = data;
}

public void displayNode(){


System.out.print(data +" ");
}

@Override
public String toString(){
return data.toString();
}
}

public Node first =null;


public Node last =null;

public void addFirst(T data){


Node newNode =new Node(data);

if(isEmpty()){
newNode.next =null;
newNode.prev =null;
first= newNode;
last= newNode;

}else{
first.prev = newNode;
newNode.next = first;
newNode.prev =null;
first= newNode;
}
}

public boolean isEmpty(){


return(first ==null);
}

public void displayList(){


Node current = first;
while(current !=null){
current.displayNode();
current= current.next;
}
System.out.println();
}

IQRA University, Main Campus, Karachi


31

public void removeFirst(){


if(!isEmpty()){
Node temp = first;

if(first.next ==null){
first=null;
last=null;
}else{
first= first.next;
first.prev =null;
}
System.out.println(temp.toString()+" is popped from the list");
}
}

public void removeLast(){


Node temp = last;

if(!isEmpty()){

if(first.next ==null){
first=null;
last=null;
}else{
last= last.prev;
last.next =null;
}
}
System.out.println(temp.toString()+" is popped from the list");
}
}

Circular LinkedList:
Linked lists are traditionally viewed as storing a sequence of items in a linear order, from first to
last. However, there are many applications in which data can be more naturally viewed as having
a cyclic order, with well-defined neighboring relationships, but no fixed beginning or end.

For example, many multiplayer games are turn-based, with player A taking a turn, then player B,
then player C, and so on, but eventually back to player A again, and player B again, with the
pattern repeating. As another example, city buses and subways often run on a continuous loop,
making stops in a scheduled order, but with no designated first or last stop per se.

IQRA University, Main Campus, Karachi


32

Code Example:
public class CircularLinkedList{
private Link first;
private Link current;

public Link getCurrent(){


return current;
}

public void setCurrent(int data){

public void advance(){


current= current.next;
}

public void insert(int data){


Link newLink =new Link(data);
if(first ==null){
first= current = newLink;
}else{
current.next = newLink;
}
current= newLink;
newLink.next = first;
}
...
}

Lab Tasks:
Write a program in java to insert a new node at the middle of Singly Linked List.

IQRA University, Main Campus, Karachi


33

Data Structures

LAB-5

Name ____________________
Roll No ___________________
Date ______________________
Marks Obtained ____________
Signature___________________

IQRA University, Main Campus, Karachi


34

Recursion In java

Objective:

Understand the concept of recursion and its implementation in java.

Description:
We have seen that repetition can be achieved by writing loops, such as for loops and
while loops. Another way to achieve repetition is through recursion, which occurs when a
function calls itself. We have seen examples of methods calling other methods, so it should
come as no surprise that most modern programming languages, including Java, allow a
method to call itself. In this section, we will see why this capability provides an elegant and
powerful alternative for performing repetitive tasks.

The Factorial function:

To illustrate recursion, let us begin with a simple example of computing the value of the
factorial function. The factorial of a positive integer n, denoted n!, is defined as the product
of the integers from 1 to n. If n = 0, then n! is defined as 1 by convention. More formally, for
any integer n ≥ 0,

n!={n . ( n−1 ) . ( n−2 ) … 3.2.1


1 if n=0
if n ≥ 1

For example, 5! = 5·4·3·2·1 = 120. To make the connection with methods clearer, we use the
notation factorial(n) to denote n!.

The factorial function can be defined in a manner that suggests a recursive formulation. To
see this, observe that
factorial(5) = 5 · (4 · 3 · 2 · 1) = 5 · factorial(4).

Thus, we can define factorial(5) in terms of factorial(4). In general, for a positive


integer n, we can define factorial(n) to be n·factorial(n − 1). This leads to the
following recursive definition.

Factorial(n)={n . factorial( n−1)


1 if n=0
if n ≥ 1

This definition is typical of many recursive definitions. First, it contains one or more base
cases, which are defined nonrecursively in terms of fixed quantities. In this case, n = 0 is the
base case. It also contains one or more recursive cases, which are defined by appealing to the
definition of the function being defined. Observe that there is no circularity in this definition,
because each time the function is invoked, its argument is smaller by one.

IQRA University, Main Campus, Karachi


35

Recursion Programming Example in Java:


In our programming example of recursion in Java, we will calculate Fibonacci number of
giving length using recursion. In the case of Fibonacci number current number is the sum of
previous two number except first and second number which will form the base case for the
recursive solution.

public class RecursionTest {

public static void main(String args[]) {


System.out.println("fibonacci series for length 1 is " + fibonacci(6));
}

public static int fibonacci(int number){


if(number < 1){
throw new IllegalArgumentException("Invalid argument for Fibonacci eries: "
+ number);
}
//base case of recursion
if(number == 0 || number == 1){
return 1;
}
//recursive method call in java
return fibonacci(2) + fibonacci(1);
}

}
0112358,13…

Task 1:

Using Recursion Perform the following Tasks

 Calculate power of a given number in java


 Reverse a String using recursion in Java

IQRA University, Main Campus, Karachi


36

Data Structures

LAB-6

Name ____________________
Roll No ___________________
Date ______________________
Marks Obtained ____________
Signature___________________

IQRA University, Main Campus, Karachi


37

Develop Stack and Queue Using Generic Array in Java


Programming Language

Objective:
Implementation of Stack and Queue data structure in java.

The Stack:
Stack is a collection of objects that are inserted and removed according to the last-in first-out
(LIFO) principle. Objects can be inserted into a stack at any time, but only the most recently
inserted (that is, "last") object can be removed at any time.

Stack support the following methods:

 push(e): Insert element e, to be the top of the stack.


 pop(): Remove from the stack and return the top element on the stack; an error
occurs if the stack is empty.
 size(): Return the number of elements in the stack.
 isEmpty(): Return a Boolean indicating if the stack is empty.
 top(): Return the top element in the stack, without removing it; an error occurs if the
stack is empty.

Task 1: Implement Array-Based Stack.


Below progames shows a complete implementation for the array-based stack class. As with
the array-based list implementation, listArray must be declared of fixed size when the stack
is created. In the stack constructor, size serves to indicate this size. Method top acts
somewhat like a current position value (because the “current” position is always at the top of
the stack), as well as indicating the number of elements currently in the stack.

1. public interface stack<E> {


2. /** Reinitialize the stack. The user is responsible for
3. reclaiming the storage used by the stack elements. */
4. public void clear();
5. /** Push an element onto the top of the stack.
6. @param it The element being pushed onto the stack. */
7. public void push(E it);
8. /** Remove and return the element at the top of the stack.
9. @return The element at the top of the stack. */
10. public E pop();
11. /** @return A copy of the top element. */
12. public E topValue();
13. /** @return The number of elements in the stack. */
14. public int length();

IQRA University, Main Campus, Karachi


38

15. }

1. class AStack<E> implements stack<E>{


2. public E[] listArray;
3. private static final int defaultSize = 10;
4. private int maxSize; // Maximum size of stack
5. private int top; // Index for top Object
6.
7. /** Constructors */
8. AStack() {
9. this(defaultSize);
10. }
11.
12. AStack(int size){
13.
14. maxSize = size;
15. top = 0;
16. listArray =(E[]) new Object[size];
17. }
18. /** Reinitialize stack */
19.
20. public void clear() { top = 0; }
21. /** Push "it" onto stack */
22. public void push(E it) {
23. assert top != maxSize : "Stack is full";
24. listArray[top++] = it;
25. }
26. /** Remove and top element */
27. public E pop() {
28. assert top != 0 : "Stack is empty";
29. return listArray[--top];
30. }
31. /** @return Top element */
32. public E topValue() {
33. assert top != 0 : "Stack is empty";
34. return listArray[top-1];
35. }
36. /** @return Stack size */
37. public int length() { return top; }
38.
39. public static void main(String[] args) {
40. // TODO Auto-generated method stub
41. AStack<Integer> obj= new AStack<Integer>(3);
42. obj.push(3);
43. obj.push(1);
44. obj.push(2);
45.
46. System.out.println(obj.pop());
47. System.out.println(obj.pop());
48.
49. }
50.
51. }

The Queue:
Formally, the queue abstract data type defines a collection that keeps objects in a sequence,
where element access and deletion are restricted to the first element in the sequence, which
is called the front of the queue, and element insertion is restricted to the end of the sequence,

IQRA University, Main Campus, Karachi


39

which is called the rear of the queue. This restriction enforces the rule that items are inserted
and deleted in a queue according to the first-in first-out (FIFO) principle.

The queue abstract data type (ADT) supports the following methods:

 enqueue(e): Insert element e at the rear of the queue.


 dequeue(): Remove and return from the queue the object at the front; an error occurs
if the queue is empty.
 size(): Return the number of objects in the queue.
 isEmpty(): Return a Boolean value that indicates whether the queue is empty.
 front(): Return, but do not remove, the front object in the queue; an error occurs if
the queue is empty.

Task 1: Develop Array-Based Queues.

1. public interface Queue<E> {


2. /** Reinitialize the queue. The user is responsible for
3. reclaiming the storage used by the queue elements. */
4. public void clear();
5. /** Place an element at the rear of the queue.
6. @param it The element being enqueued. */
7. public void enqueue(E it);
8. /** Remove and return element at the front of the queue.
9. @return The element at the front of the queue. */
10. public E dequeue();
11. /** @return The front element. */
12. public E frontValue();
13. /** @return The number of elements in the queue. */
14. public int length();
15. }

1. /** Array-based queue implementation */


2. class AQueue<E> implements Queue<E> {
3. private static final int defaultSize = 10;
4. private int maxSize; // Maximum size of queue
5. private int front; // Index of front element
6. private int rear; // Index of rear element
7. private E[] listArray; // Array holding queue elements
8. /** Constructors */
9. AQueue() { this(defaultSize); }
10. AQueue(int size) {
11. maxSize = size+1; // One extra space is allocated
12. rear = 0; front = 1;
13. listArray = (E[])new Object[maxSize]; // Create listArray
14. }
15. /** Reinitialize */
16. public void clear()
17. { rear = 0; front = 1; }

IQRA University, Main Campus, Karachi


40

18. /** Put "it" in queue */


19. public void enqueue(E it) {
20. assert ((rear+2) % maxSize) != front : "Queue is full";
21. rear = (rear+1) % maxSize; // Circular increment
22. listArray[rear] = it;
23. }
24. /** Remove and return front value */
25. public E dequeue() {
26. assert length() != 0 : "Queue is empty";
27. E it = listArray[front];
28. front = (front+1) % maxSize; // Circular increment
29. return it;
30. }
31. /** @return Front value */
32. public E frontValue() {
33. assert length() != 0 : "Queue is empty";
34. return listArray[front];
35. }
36. /** @return Queue size */
37. public int length()
38. { return ((rear+maxSize) - front + 1) % maxSize; }
39. public static void main(String[] args){
40. AQueue<Integer> obj=new AQueue<Integer>(5);
41. obj.enqueue(2);
42. obj.enqueue(3);
43. obj.enqueue(5);
44. System.out.println(obj.length());
45. System.out.println(obj.dequeue());
46. }
47. }

Lab Tasks:
Implement Stack using Linked List.

IQRA University, Main Campus, Karachi


41

Data Structures

LAB-7

Name ____________________
Roll No ___________________
Date ______________________
Marks Obtained ____________
Signature___________________

IQRA University, Main Campus, Karachi


42

Sorting Part 1

Objective:
Implement insertion sorting, bubble sorting and selection sorting in java.

Insertion sort:
Imagine that you have a stack of phone bills from the past two years and that you wish to organize
them by date. A fairly natural way to do this might be to look at the first two bills and put them in
order. Then take the third bill and put it into the right order with respect to the first two, and so on. As
you take each bill, you would add it to the sorted pile that you have already made. This naturally
intuitive process is the inspiration for our first sorting algorithm, called Insertion Sort. Insertion Sort
iterates through a list of records. Each record is inserted in turn at the correct position within a sorted
list composed of those records already processed.

Advantages of Insertion Sort: 


1. It is very simple.
2. It is very efficient for small data sets.
3. It is stable; i.e., it does not change the relative order of elements with equal keys.
4. In-place; i.e., only requires a constant amount O(1) of additional memory space.

Insertion sort iterates through the list by consuming one input element at each repetition, and
growing a sorted output list

1. public class MyInsertionSort {


2. public static void main(String a[]){
3. int[] arr1 = {10,34,2,56,7,67,88,42};
4. int[] arr2 = doInsertionSort(arr1);
5. for(int i:arr2){
6. System.out.print(i);

IQRA University, Main Campus, Karachi


43

7. System.out.print(", ");
8. }
9. }
10. public static int[] doInsertionSort(int[] input){
11. int temp;
12. for(int i = 1; i < input.length; i++) {
13. for(int j = i ; j > 0; j--){
14. if(input[j] < input[j-1]){
15. temp = input[j];
16. input[j] = input[j-1];
17. input[j-1] = temp;
18. }
19. }
20. }
21. return input;
22. }
23. }

Bubble Sort:
Bubble sort, also referred to as sinking sort, is a simple sorting algorithm that works by
repeatedly stepping through the list to be sorted, comparing each pair of adjacent items and
swapping them if they are in the wrong order. The pass through the list is repeated until no
swaps are needed, which indicates that the list is sorted. The algorithm gets its name from the
way smaller elements "bubble" to the top of the list. Because it only uses comparisons to
operate on elements, it is a comparison sort. Although the algorithm is simple, most of the
other sorting algorithms are more efficient for large lists.
Bubble sort has worst-case and average complexity both О(n2), where n is the number of
items being sorted.

void bubblesort(E[] A) {
for (int i=0; i<A.length-1; i++) // Bubble up i’th record
for (int j=A.length-1; j>i; j--)
if ((A[j].compareTo(A[j-1]) < 0))
DSutil.swap(A, j, j-1);
}

Selection sort:
Consider again the problem of sorting a pile of phone bills for the past year. Another intuitive
approach might be to look through the pile until you find the bill for January, and pull that
out. Then look through the remaining pile until you find the bill for February, and add that
behind January. Proceed through the ever-shrinking pile of bills to select the next one in order
until you are done. This is the inspiration for our last _(n2) sort, called Selection Sort. The ith
pass of Selection Sort “selects” the ith smallest key in the array, placing that record into
position i. In other words, Selection Sort first finds the smallest key in an unsorted list, then

IQRA University, Main Campus, Karachi


44

the second smallest, and so on. Its unique feature is that there are few record swaps. To find
the next smallest key value requires searching through the entire unsorted portion
of the array, but only one swap is required to put the record in place. Thus, the total number
of swaps required will be n-1 (we get the last record in place “for free”).

void selectsort(E[] A) {
for (int i=0; i<A.length-1; i++) { // Select i’th record
int lowindex = i; // Remember its index
for (int j=A.length-1; j>i; j--) // Find the least value
if (A[j].compareTo(A[lowindex]) < 0)
lowindex = j; // Put it in place
DSutil.swap(A, i, lowindex);
}
}

Task 1:

Write a java program to sort the array by using bubble sort and selection sort.

IQRA University, Main Campus, Karachi


45

Data Structures

LAB-8

Name ____________________
Roll No ___________________
Date ______________________
Marks Obtained ____________
Signature___________________

IQRA University, Main Campus, Karachi


46

Sorting Part-2

Objective:
Implement Divide & Conquer approach for sorting an array in java:

Merge-sort and quick sort are based on an algorithmic design pattern called divide-and-
conquer. In terms of sorting, we might consider breaking the list to be sorted into pieces,
process the pieces, and then put them back together somehow.

The divide-and-conquer pattern consists of the following three steps:

1. Divide: If the input size is smaller than a certain threshold (say, one or two elements),
solve the problem directly using a straightforward method and return the solution so
obtained. Otherwise, divide the input data into two or more disjoint subsets.

2. Recur: Recursively solve the subproblems associated with the subsets.


3. Conquer: Take the solutions to the subproblems and "merge" them into a solution to
the original problem.

Merge sort:
Merge sort is a fast, stable sorting routine with guaranteed O(n*log(n)) efficiency. When
sorting arrays, merge sort requires additional scratch space proportional to the size of the
input array. Merge sort is relatively simple to code and offers performance typically only
slightly below that of quicksort.

IQRA University, Main Campus, Karachi


47

public class MyMergeSort {


private int[] array;
private int[] tempMergArr;
private int length;

public static void main(String a[]){

int[] inputArr = {45,23,11,89,77,98,4,28,65,43};


MyMergeSort mms = new MyMergeSort();
mms.sort(inputArr);
for(int i:inputArr){
System.out.print(i);
System.out.print(" ");
}
}
public void sort(int inputArr[]) {
this.array = inputArr;
this.length = inputArr.length;
this.tempMergArr = new int[length];
doMergeSort(0, length - 1);
}
private void doMergeSort(int lowerIndex, int higherIndex) {

if(lowerIndex < higherIndex) {


int middle = lowerIndex + (higherIndex - lowerIndex) / 2;
// Below step sorts the left side of the array
doMergeSort(lowerIndex, middle);
// Below step sorts the right side of the array
doMergeSort(middle + 1, higherIndex);
// Now merge both sides
mergeParts(lowerIndex, middle, higherIndex);
}
}
private void mergeParts(int lowerIndex, int middle, int higherIndex) {
for(int i = lowerIndex; i <= higherIndex; i++) {
tempMergArr[i] = array[i];
}
int i = lowerIndex;
int j = middle + 1;
int k = lowerIndex;
while(i <= middle && j <= higherIndex) {
if(tempMergArr[i] <= tempMergArr[j]) {
array[k] = tempMergArr[i];
i++;
} else{
array[k] = tempMergArr[j];
j++;
}
k++;
}
while(i <= middle) {
array[k] = tempMergArr[i];
k++;
i++;
}

IQRA University, Main Campus, Karachi


48

}
}
Quick sort:

Quicksort or partition-exchange sort, is a fast sorting algorithm, which is using divide and
conquer algorithm. Quicksort first divides a large list into two smaller sub-lists: the low
elements and the high elements. Quicksort can then recursively sort the sub-lists.

Steps to implement Quick sort:

1. Choose an element, called pivot, from the list. Generally pivot can be the middle index
element.
2. Reorder the list so that all elements with values less than the pivot come before the pivot,
while all elements with values greater than the pivot come after it (equal values can go either
way). After this partitioning, the pivot is in its final position. This is called the partition
operation.
3. Recursively apply the above steps to the sub-list of elements with smaller values and
separately the sub-list of elements with greater values.

The Quicksort partition implementation

IQRA University, Main Campus, Karachi


49

public class MyQuickSort {

private int array[];


private int length;

public void sort(int[] inputArr) {

if(inputArr == null|| inputArr.length == 0) {


return;
}
this.array = inputArr;
length = inputArr.length;
quickSort(0, length - 1);
}

private void quickSort(int lowerIndex, int higherIndex) {

int i = lowerIndex;
int j = higherIndex;
// calculate pivot number, I am taking pivot as middle index
number
int pivot = array[lowerIndex+(higherIndex-lowerIndex)/2];
// Divide into two arrays
while(i <= j) {
while(array[i] < pivot) {
i++;
}
while(array[j] > pivot) {
j--;
}
if(i <= j) {
exchangeNumbers(i, j);
//move index to next position on both sides
i++;
j--;
}
}
// call quickSort() method recursively
if(lowerIndex < j)
quickSort(lowerIndex, j);
if(i < higherIndex)
quickSort(i, higherIndex);
}

IQRA University, Main Campus, Karachi


50

private void exchangeNumbers(int i, int j) {


int temp = array[i];
array[i] = array[j];
array[j] = temp;
}

public static void main(String a[]){

MyQuickSort sorter = new MyQuickSort();


int[] input = {24,2,45,20,56,75,2,56,99,53,12};
sorter.sort(input);
for(int i:input){
System.out.print(i);
System.out.print(" ");
}
}
}

IQRA University, Main Campus, Karachi


51

ata Structures

LAB-9

Name ____________________
Roll No ___________________
Date ______________________
Marks Obtained ____________

IQRA University, Main Campus, Karachi


52

Binary search tree

Objective:

Develop Binary Search Tree and implement in-order, post-order, pre-order traversing
techniques

Introduction:
A binary tree is made up of a finite set of elements called nodes. This set either is empty or
consists of a node called the root together with two binary trees, called the left and right
subtrees, which are disjoint from each other and from the root. (Disjoint means that they have
no nodes in common.) The roots of these subtrees are children of the root. There is an edge
from a node to each of its children, and a node is said to be the parent of its children.

A Binary Search Tree (BST) is a tree in which all the nodes follow the below-mentioned
properties –

 The left sub-tree of a node has a key less than or equal to its parent node's key.
 The right sub-tree of a node has a key greater than or equal to its parent node's key.

Search Operation:
The most important consequence of the structural property of a binary search tree is its
namesake search algorithm. We can attempt to locate a particular key in a binary search tree
by viewing it as a decision tree. In this case, the question asked at each internal position p is
whether the desired key k is less than, equal to, or greater than the key stored at position p,
which we denote as key(p). If the answer is “less than,” then the search continues in the left
subtree. If the answer is “equal,” then the search terminates successfully. If the answer is
“greater than,” then the search continues in the right subtree. Finally, if we reach a leaf, then
the search terminates unsuccessfully.

A successful search for key 65 in a binary search tree; (b) an an unsuccessful search for key
68 that terminates at the leaf to the left of the key 76

IQRA University, Main Campus, Karachi


53

Insert Operation:

The insert operation begins with a search for an entry with key . If found, that entry’s existing
value is reassigned. Otherwise, the new entry can be inserted into the underlying tree by
expanding the leaf that was reached at the end of the failed search into an internal node. The
binary search-tree property is sustained by that placement (note that it is placed exactly where
a search would expect it).

public class Binarytree


{
private static Node root;

public Binarytree(int data)


{
root=new Node(data);
}

public void add(Node parent,Node child,String orientation)


{
if(orientation=="left")
{
parent.setLeft(child);
}
else if(orientation=="right")
{
parent.setRight(child);
}

public static void main(String ar[])


{
Node n1=new Node(1);
Node n2=new Node(4);
Node n3=new Node(2);
Node n4=new Node(5);

Binarytree l1=new Binarytree(3);


l1.add(root,n1,"left");
l1.add(root,n2,"right");
l1.add(root,n3,"left");
l1.add(root,n4,"right");

}
}

class Node{
private int key;
private Node left;
private Node right;
Node(int key){

IQRA University, Main Campus, Karachi


54

this.key = key;
right=null;
left=null;
}

public void setKey(int key){


this.key = key;
}

public int getKey(){


return key;
}

public void setLeft(Node left){


this.left = left;
}

public Node getLeft(){


return left;
}

public void setRight(Node right ){


this.right = right;
}

public Node getRight(){


return right;
}

Tree Traversal:
Often we wish to process a binary tree by “visiting” each of its nodes, each time performing a specific
action such as printing the contents of the node. Any process for visiting all of the nodes in some
order is called a traversal. Any traversal that lists every node in the tree exactly once is called an
enumeration of the tree’s nodes. Some applications do not require that the nodes be visited in any
particular order as long as each node is visited precisely once. For other applications, nodes must be
visited in an order that preserves some relationship. For example, we might wish to make sure that we
visit any given node before we visit its children. This is called a preorder traversal

IQRA University, Main Campus, Karachi


55

Figure BST-1

Postorder Traversal:
The postorder enumeration for the tree of Figure BST-1 is
DBGEHIFCA

Another important tree traversal algorithm is the postorder traversal. In some sense, this algorithm
can be viewed as the opposite of the preorder traversal, because it recursively traverses the subtrees
rooted at the children of the root first, and then visits the root (hence, the name “postorder”).

Algorithm postorder(p):
for each child c in children(p) do
postorder(c) { recursively traverse the subtree rooted at c }
perform the “visit” action for position p { this happens after any recursion }

InOrder Traversal:
The inorder enumeration for the tree of BST-1 is
BDAGECHFI

An inorder traversal first visits the left child (including its entire subtree), then visits the node, and
finally visits the right child (including its entire subtree).

Algorithm inorder(T,v):
if v has a left child u in T then
inorder(T,u) {recursively traverse left subtre}
perform the "visit" action for node v
if v has a right child w in T then
inder(t,w) {recursively traverse right subtre}

Preorder traversal:

IQRA University, Main Campus, Karachi


56

The preorder enumeration for the tree of Figure BST-1 is


ABDCEGFHI:

The first node printed is the root. Then all nodes of the left subtree are printed (in preorder) before any
node of the right subtree

Algorithm preorder(T,v):
perform the "visit" action for node v
for each child w of v in T do
Preorder(T,w) {recursively traverse the subtree at w}

Implementation or Inderorder traversal:


//Definition for binary tree
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}

public class Solution {


public ArrayList<Integer> inorderTraversal(TreeNode root) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
ArrayList<Integer> lst = new ArrayList<Integer>();

if(root == null)
return lst;

Stack<TreeNode> stack = new Stack<TreeNode>();


//define a pointer to track nodes
TreeNode p = root;

while(!stack.empty() || p != null){

// if it is not null, push to stack


//and go down the tree to left
if(p != null){
stack.push(p);
p = p.left;

// if no left child
// pop stack, process the node
// then let p point to the right
}else{
TreeNode t = stack.pop();
lst.add(t.val);
p = t.right;
}

IQRA University, Main Campus, Karachi


57

return lst;
}
}

Implementation or Postorder traversal:

public class Node {

private Node right;


private Node left;
private int nodeValue;

public Node ( )
{
// a Java constructor
}

public Node leftNode() {return left;}


public Node rightNode() {return right;}
public int getNodeValue() {return nodeValue;}

Given the Node class above, let’s write a recursive method that will actually do the postorder
traversal for us. In the code below, we also assume that we have a method called
printNodeValue which will print out the Node’s value for us.

void postOrder (Node root)


{

if(root == null) return;

postOrder( root.leftNode() );
postOrder( root.rightNode() );

root.printNodeValue();

Task # 1:
Implement Preorder traversal in java.

IQRA University, Main Campus, Karachi


58

Data Structures

LAB-10

Name ____________________
Roll No ___________________
Date ______________________
Marks Obtained ____________
Signature___________________

IQRA University, Main Campus, Karachi


59

Avl Tree

Objective:
Perform insert operation in AVL Tree .

Description:
The simple correction is to add a rule to the binary search tree definition that will maintain a
logarithmic height for the tree. The rule we consider in this section is the following height-
balance property, which characterizes the structure of a binary search tree T in terms of the
heights of its internal nodes

Height-Balance Property: For every internal node v of T, the heights of the children

of v differ by at most 1.

Update Operations:

The insertion and removal operations for AVL trees are similar to those for binary search
trees, but with AVL trees we must perform additional computations.

Insertion Operaion:

Suppose that tree T satisfies the height-balance property, and hence is an AVL tree, prior to
the insertion of a new entry. An insertion of a new entry in a binary search tree, results in a

IQRA University, Main Campus, Karachi


60

leaf position p being expanded to become internal, with two new external children. This
action may violate the height-balance property.

AVL-Insert

(a) after adding a new node for key 54, the nodes storing keys 78 and 44 become unbalanced;
(b) a trinode restructuring restores the height-balance property. We show the heights of nodes
above them, and we identify the nodes x, y, and z and subtrees T1, T2, T3, and T4
participating in the trinode restructuring

// Java program for insertion in AVL Tree


class Node {
int key, height;
Node left, right;

Node(int d) {
key = d;
height = 1;
}
}

class AVLTree {

Node root;

// A utility function to get the height of the tree


int height(Node N) {
if (N == null)
return 0;

return N.height;
}

// A utility function to get maximum of two integers


int max(int a, int b) {
return (a > b) ? a : b;
}

// A utility function to right rotate subtree rooted with y

IQRA University, Main Campus, Karachi


61

// See the diagram given above.


Node rightRotate(Node y) {
Node x = y.left;
Node T2 = x.right;

// Perform rotation
x.right = y;
y.left = T2;

// Update heights
y.height = max(height(y.left), height(y.right)) + 1;
x.height = max(height(x.left), height(x.right)) + 1;

// Return new root


return x;
}

// A utility function to left rotate subtree rooted with x


// See the diagram given above.
Node leftRotate(Node x) {
Node y = x.right;
Node T2 = y.left;

// Perform rotation
y.left = x;
x.right = T2;

// Update heights
x.height = max(height(x.left), height(x.right)) + 1;
y.height = max(height(y.left), height(y.right)) + 1;

// Return new root


return y;
}

// Get Balance factor of node N


int getBalance(Node N) {
if (N == null)
return 0;

return height(N.left) - height(N.right);


}

Node insert(Node node, int key) {

/* 1. Perform the normal BST insertion */


if (node == null)
return (new Node(key));

if (key < node.key)


node.left = insert(node.left, key);
else if (key > node.key)
node.right = insert(node.right, key);
else // Duplicate keys not allowed
return node;

/* 2. Update height of this ancestor node */


node.height = 1 + max(height(node.left),
height(node.right));

/* 3. Get the balance factor of this ancestor


node to check whether this node became
unbalanced */

IQRA University, Main Campus, Karachi


62

int balance = getBalance(node);

// If this node becomes unbalanced, then there


// are 4 cases Left Left Case
if (balance > 1 && key < node.left.key)
return rightRotate(node);

// Right Right Case


if (balance < -1 && key > node.right.key)
return leftRotate(node);

// Left Right Case


if (balance > 1 && key > node.left.key) {
node.left = leftRotate(node.left);
return rightRotate(node);
}

// Right Left Case


if (balance < -1 && key < node.right.key) {
node.right = rightRotate(node.right);
return leftRotate(node);
}

/* return the (unchanged) node pointer */


return node;
}

// A utility function to print preorder traversal


// of the tree.
// The function also prints height of every node
void preOrder(Node node) {
if (node != null) {
System.out.print(node.key + " ");
preOrder(node.left);
preOrder(node.right);
}
}

public static void main(String[] args) {


AVLTree tree = new AVLTree();

/* Constructing tree given in the above figure */


tree.root = tree.insert(tree.root, 10);
tree.root = tree.insert(tree.root, 20);
tree.root = tree.insert(tree.root, 30);
tree.root = tree.insert(tree.root, 40);
tree.root = tree.insert(tree.root, 50);
tree.root = tree.insert(tree.root, 25);

/* The constructed AVL Tree would be


30
/ \
20 40
/ \ \
10 25 50
*/
System.out.println("Preorder traversal" +
" of constructed tree is : ");
tree.preOrder(tree.root);
}

IQRA University, Main Campus, Karachi


63

// Code reference : https://www.geeksforgeeks.org/avl-tree-set-1-insertion/

Data Structures

LAB-11

Name ____________________
Roll No ___________________
Date ______________________
Marks Obtained ____________

IQRA University, Main Campus, Karachi


64

Signature___________________

Avl Tree (Cont…)

Objective:
Perform delete operation in AVL Tree in Java

Description:

Recall that a deletion from a regular binary search tree results in the structural removal of a
node having either zero or one internal children. Such a change may violate the height-
balance property in an AVL tree. In particular, if position p represents a (possibly external)
child of the removed node in tree T, there may be an unbalanced node on the path from p to
the root of T. (See Figure AVL-Delete(a)). Infact, there can be at most one such unbalanced
node.

AVL-Delete

(a) after removing the node storing key 32, the root becomes unbalanced;
(b) a tri-node restructuring of x, y, and z restores the height-balance property.
Lab task:

Delete operation in AVL Tree.

// Java program for deletion in AVL Tree

IQRA University, Main Campus, Karachi


65

class Node
{
int key, height;
Node left, right;

Node(int d)
{
key = d;
height = 1;
}
}

class AVLTree
{
Node root;

// A utility function to get height of the tree


int height(Node N)
{
if (N == null)
return 0;
return N.height;
}

// A utility function to get maximum of two integers


int max(int a, int b)
{
return (a > b) ? a : b;
}

// A utility function to right rotate subtree rooted with y


// See the diagram given above.
Node rightRotate(Node y)
{
Node x = y.left;
Node T2 = x.right;

// Perform rotation
x.right = y;
y.left = T2;

// Update heights
y.height = max(height(y.left), height(y.right)) + 1;
x.height = max(height(x.left), height(x.right)) + 1;

// Return new root


return x;
}

// A utility function to left rotate subtree rooted with x


// See the diagram given above.
Node leftRotate(Node x)
{
Node y = x.right;
Node T2 = y.left;

// Perform rotation
y.left = x;
x.right = T2;

// Update heights
x.height = max(height(x.left), height(x.right)) + 1;
y.height = max(height(y.left), height(y.right)) + 1;

IQRA University, Main Campus, Karachi


66

// Return new root


return y;
}

// Get Balance factor of node N


int getBalance(Node N)
{
if (N == null)
return 0;
return height(N.left) - height(N.right);
}

Node insert(Node node, int key)


{
/* 1. Perform the normal BST rotation */
if (node == null)
return (new Node(key));

if (key < node.key)


node.left = insert(node.left, key);
else if (key > node.key)
node.right = insert(node.right, key);
else // Equal keys not allowed
return node;

/* 2. Update height of this ancestor node */


node.height = 1 + max(height(node.left),
height(node.right));

/* 3. Get the balance factor of this ancestor


node to check whether this node became
Wunbalanced */
int balance = getBalance(node);

// If this node becomes unbalanced, then


// there are 4 cases Left Left Case
if (balance > 1 && key < node.left.key)
return rightRotate(node);

// Right Right Case


if (balance < -1 && key > node.right.key)
return leftRotate(node);

// Left Right Case


if (balance > 1 && key > node.left.key)
{
node.left = leftRotate(node.left);
return rightRotate(node);
}

// Right Left Case


if (balance < -1 && key < node.right.key)
{
node.right = rightRotate(node.right);
return leftRotate(node);
}

/* return the (unchanged) node pointer */


return node;
}

/* Given a non-empty binary search tree, return the


node with minimum key value found in that tree.

IQRA University, Main Campus, Karachi


67

Note that the entire tree does not need to be


searched. */
Node minValueNode(Node node)
{
Node current = node;

/* loop down to find the leftmost leaf */


while (current.left != null)
current = current.left;

return current;
}

Node deleteNode(Node root, int key)


{
// STEP 1: PERFORM STANDARD BST DELETE
if (root == null)
return root;

// If the key to be deleted is smaller than


// the root's key, then it lies in left subtree
if (key < root.key)
root.left = deleteNode(root.left, key);

// If the key to be deleted is greater than the


// root's key, then it lies in right subtree
else if (key > root.key)
root.right = deleteNode(root.right, key);

// if key is same as root's key, then this is the node


// to be deleted
else
{

// node with only one child or no child


if ((root.left == null) || (root.right == null))
{
Node temp = null;
if (temp == root.left)
temp = root.right;
else
temp = root.left;

// No child case
if (temp == null)
{
temp = root;
root = null;
}
else // One child case
root = temp; // Copy the contents of
// the non-empty child
}
else
{

// node with two children: Get the inorder


// successor (smallest in the right subtree)
Node temp = minValueNode(root.right);

// Copy the inorder successor's data to this node


root.key = temp.key;

// Delete the inorder successor


root.right = deleteNode(root.right, temp.key);

IQRA University, Main Campus, Karachi


68

}
}

// If the tree had only one node then return


if (root == null)
return root;

// STEP 2: UPDATE HEIGHT OF THE CURRENT NODE


root.height = max(height(root.left), height(root.right)) + 1;

// STEP 3: GET THE BALANCE FACTOR OF THIS NODE (to check whether
// this node became unbalanced)
int balance = getBalance(root);

// If this node becomes unbalanced, then there are 4 cases


// Left Left Case
if (balance > 1 && getBalance(root.left) >= 0)
return rightRotate(root);

// Left Right Case


if (balance > 1 && getBalance(root.left) < 0)
{
root.left = leftRotate(root.left);
return rightRotate(root);
}

// Right Right Case


if (balance < -1 && getBalance(root.right) <= 0)
return leftRotate(root);

// Right Left Case


if (balance < -1 && getBalance(root.right) > 0)
{
root.right = rightRotate(root.right);
return leftRotate(root);
}

return root;
}
// A utility function to print preorder traversal of
// the tree. The function also prints height of every
// node
void preOrder(Node node)
{
if (node != null)
{
System.out.print(node.key + " ");
preOrder(node.left);
preOrder(node.right);
}
}

public static void main(String[] args)


{
AVLTree tree = new AVLTree();

/* Constructing tree given in the above figure */


tree.root = tree.insert(tree.root, 9);
tree.root = tree.insert(tree.root, 5);
tree.root = tree.insert(tree.root, 10);
tree.root = tree.insert(tree.root, 0);
tree.root = tree.insert(tree.root, 6);
tree.root = tree.insert(tree.root, 11);
tree.root = tree.insert(tree.root, -1);
tree.root = tree.insert(tree.root, 1);

IQRA University, Main Campus, Karachi


69

tree.root = tree.insert(tree.root, 2);

/* The constructed AVL Tree would be


9
/ \
1 10
/ \ \
0 5 11
/ / \
-1 2 6
*/
System.out.println("Preorder traversal of "+
"constructed tree is : ");
tree.preOrder(tree.root);

tree.root = tree.deleteNode(tree.root, 10);

/* The AVL Tree after deletion of 10


1
/ \
0 9
/ / \
-1 5 11
/ \
2 6
*/
System.out.println("");
System.out.println("Preorder traversal after "+
"deletion of 10 :");
tree.preOrder(tree.root);
}
}

Code Reference : https://www.geeksforgeeks.org/avl-tree-set-2-deletion/

Lab Tasks:
Implement a binary search tree and AVL tree from the following traversals:
{15, 5, 20, 70, 3, 10, 60, 90, 16}
 Write a method that search 15 but your tree should be BST and AVL after deletion
 Write a method to Reverse path of Binary Search Tree.

IQRA University, Main Campus, Karachi


70

Data Structures

LAB-12

IQRA University, Main Campus, Karachi


71

Name ____________________
Roll No ___________________
Date ______________________
Marks Obtained ____________
Signature___________________

Hash Table
Objective:
Implement Basic Hash Table in Java

Description:
In the section we show the very simple hash table example. It uses simple hash function,
collisions are resolved using linear probing (open addressing strategy) and hash table has
constant size. This example clearly shows the basics of hashing technique.

Hash table:

Underlying array has constant size to store 128 elements and each slot contains key-value
pair. Key is stored to distinguish between key-value pairs, which have the same hash.

Hash function

Table allows only integers as values. Hash function to be used is the remainder of division by
128. In the view of implementation, this hash function can be encoded using remainder
operator or using bitwise AND with 127.

IQRA University, Main Campus, Karachi


72

Note. Power of two sized tables are often used in practice (for instance in Java). When used,
there is a special hash function, which is applied in addition to the main one. This measure
prevents collisions occuring for hash codes that do not differ in lower bits.

Collision resolution strategy

Linear probing is applied to resolve collisions. In case the slot, indicated by hash function,
has already been occupied, algorithm tries to find an empty one by probing consequent slots
in the array. 

Note. Linear probing is not the best techique to be used when table is of a constant size.
When load factor exceeds particular value (appr. 0.7), hash table performance will decrease
nonlinearly. Also, the number of stored key-value pairs is limited to the size of the table
(128).

This implementation suffers one bug. When there is no more place in the table, the loop,
searching for empty slot, will run infinitely. It won't happen in real hash table based on open
addressing, because it is most likely dynamic-sized. Also the removal's implementation is
omitted to maintain simplicity.

Code Example:
public class HashEntry {
private int key;
private int value;

HashEntry(int key, int value) {


this.key = key;
this.value = value;
}

public int getKey() {


return key;
}

public int getValue() {


return value;
}
}
 
public class HashMap {
private final static int TABLE_SIZE = 128;

HashEntry[] table;

HashMap() {
table = new HashEntry[TABLE_SIZE];
for (int i = 0; i < TABLE_SIZE; i++)
table[i] = null;
}

IQRA University, Main Campus, Karachi


73

public int get(int key) {


int hash = (key % TABLE_SIZE);
while (table[hash] != null && table[hash].getKey() != key)
hash = (hash + 1) % TABLE_SIZE;
if (table[hash] == null)
return -1;
else
return table[hash].getValue();
}

public void put(int key, int value) {


int hash = (key % TABLE_SIZE);
while (table[hash] != null && table[hash].getKey() != key)
hash = (hash + 1) % TABLE_SIZE;
table[hash] = new HashEntry(key, value);
}
}

Lab Tasks:

 Implement a method contains(s) that returns a boolean value that checks whether the


string s is in the table.
 Implement a method size() that returns the number of strings in the table.

IQRA University, Main Campus, Karachi


74

Data Structures

LAB-13

Name ____________________
Roll No ___________________
Date ______________________
Marks Obtained ____________
Signature___________________

Hash Map

Objective:
Implement Hash Map in Java using linked list and hash table.

Introduction:

IQRA University, Main Campus, Karachi


75

HashMap maintains key and value pairs and often denoted as HashMap<Key, Value> or
HashMap<K, V>. HashMap implements Map interface. HashMap is similar to Hashtable
with two exceptions – HashMap methods are unsynchornized and it allows null key and null
values unlike Hashtable. It is used for maintaining key and value mapping.
It is not an ordered collection which means it does not return the keys and values in the same
order in which they have been inserted into the HashMap. It neither does any kind of sorting
to the stored keys and Values.You must need to import java.util.HashMap or its super class in
order to use the HashMap class and methods.

Hash Map Using Java:

Following steps will help you to develop your own hash map using java. Initially it is
not generic, but after completion of all step make it generic as an assignment.

STEP 1:
o Create a simple data structure with key, value and which can also extend as linked list
o line #2,#3: references to key and value
o line #4: link to itself (used when there is collision in the hashmap)

class Entry {
Employee key;
String value;
Entry next;

Entry(Employee k, String v) {
key = k;
value = v;
}

public String getValue() {


return value;
}

public void setValue(String value) {


this.value = value;
}

public Employee getKey() {


return key;
}
}

IQRA University, Main Campus, Karachi


76

STEP 2:
o  Couple of important utility methods
o getSupplementalHash(): Supplemental hash function used to defend against the poor
quality hash given by the user
o getBucketNumber(): It makes sure the bucket number falls within the size of the
hashmap based on the value of hash

private int getSupplementalHash(int h) {


// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}

private int getBucketNumber(int hash) {


return hash & (SIZE - 1);
}

STEP3: PUT Method:

o line #3: get the user defined hashcode


o line #4: defend against the poor quality hash functions defined by the user (if
Employee.hashcode() is poor, this call will do a better job)
o line #8: get the bucket index
o line #12: If the control reaches into for loop, it means that it should either be a
duplicate or a collision
o line #14-15: Its a duplicate, it will be replaced with old one
o line #20: Its a collision, new pair will be appended to the list
o line #28: Its either a new_pair/collision, add it to the map

public void put(Employee key, String value) {


// get the hashcode and regenerate it to be optimum
int userHash = key.hashCode();
int hash = getSupplementalHash(userHash);

// compute the bucket number (0-15 based on our default size)


// this always results in a number between 0-15
int bucket = getBucketNumber(hash);
Entry existingElement = table[bucket];

for (; existingElement != null; existingElement =


existingElement.next) {

if (existingElement.key.equals(key)) {
System.out
.println("duplicate key value pair,
replacing existing key "
+ key + ", with value " +
value);

IQRA University, Main Campus, Karachi


77

existingElement.value = value;
return;
} else {
System.out.println("Collision detected for key " + key
+ ", adding element to the existing
bucket");

}
}

//
System.out.println("PUT adding key:" + key + ", value:" + value
+ " to the list");
Entry entryInOldBucket = new Entry(key, value);
entryInOldBucket.next = table[bucket];
table[bucket] = entryInOldBucket;
}

STEP4: GET Method:

o line #3: defend against the poor quality hash functions defined by the user (if
Employee.hashcode() is poor, this call will do a better job)
o line #7: get the bucket index
o line #14: This loop is iterated as many times as the number of collisions for every key
o line #23: If nothing is found
public Entry get(Employee key) {
// get the hashcode and regenerate it to be optimum
int hash = getSupplementalHash(key.hashCode());

// compute the bucket number (0-15 based on our default size)


// this always results in a number between 0-15
int bucket = getBucketNumber(hash);

// get the element at the above bucket if it exists


Entry existingElement = table[bucket];

// if bucket is found then traverse through the linked list and


// see if element is present
while (existingElement != null) {
System.out
.println("Traversing the list inside the bucket
for the key "
+ existingElement.getKey());
if (existingElement.key.equals(key)) {
return existingElement;
}
existingElement = existingElement.next;
}

// if nothing is found then return null


return null;
}

IQRA University, Main Campus, Karachi


78

STEP5: 
Employee object as the key to our custom map (TESTING)
hashCode(): Make sure the hash code falls with 0-10 so that we can reproduce collision
easily.
equals(): based on id and name of the person
static class Employee {
private Integer id;
private String name;

Employee(Integer id, String name) {


this.id = id;
this.name = name;
}

@Override
public int hashCode() {
// this ensures all hashcodes are between 0 and 15
return id % 10;
}

@Override
public boolean equals(Object obj) {
Employee otherEmp = (Employee) obj;
return this.name.equals(otherEmp.name);
}

@Override
public String toString() {
return this.id + "-" + name;
}
}

STEP6: 
Test Code
o line #13-14: Demonstrate duplicate key replacement in hashmap
o line #30-42 and #31-35: Demonstrate collision in hashmap
o line #44-49: Demonstrate collision along with duplication in hashmap

TMHashMap tmhm = new TMHashMap();

System.out.println("============== Adding Element


===================");
Employee e1 = new Employee(100, "Niranjan");
tmhm.put(e1, "dept1");

// duplicate
System.out.println("============== Adding Duplicate
=================");
Employee e1_dup = new Employee(100, "Niranjan");
tmhm.put(e1_dup, "dept12");

IQRA University, Main Campus, Karachi


79

// the above value "dept12" should replace the old value "dept1"
Entry e = tmhm.get(e1_dup);
System.out.println("GET element - " + e.getKey() + "::" +
e.getValue());

System.out.println("============== Adding Elements


==================");
Employee e2 = new Employee(102, "Sravan");
tmhm.put(e2, "dept3");

Employee e3 = new Employee(104, "Ananth");


tmhm.put(e3, "dept2");

Employee e4 = new Employee(106, "Rakesh");


tmhm.put(e4, "dept5");

Employee e5 = new Employee(108, "Shashi");


tmhm.put(e5, "dept2");

// collision with e2
System.out.println("============== Adding Collisions
=================");
Employee e2_collision = new Employee(112, "Chandu");
tmhm.put(e2_collision, "dept16");
e = tmhm.get(e2_collision);
System.out.println("GET element - " + e.getKey() + "::" +
e.getValue());

// collision with e3
Employee e3_collision = new Employee(114, "Santhosh");
tmhm.put(e3_collision, "dept9");
e = tmhm.get(e3_collision);
System.out.println("GET element - " + e.getKey() + "::" +
e.getValue());

System.out
.println("============== Adding Duplicate in Collision
===================");
Employee e3_collision_dupe = new Employee(124, "Santhosh");
tmhm.put(e3_collision_dupe, "dept91");
e = tmhm.get(e3_collision_dupe);
System.out.println("GET element - " + e.getKey() + "::" +
e.getValue());

OUTPUT: of this program


============== Adding Element ===================
PUT adding key:100-Niranjan, value:dept1 to the list
============== Adding Duplicate =================
duplicate key value pair, replacing existing key 100-Niranjan, with value dept12
Traversing the list inside the bucket for the key 100-Niranjan
GET element - 100-Niranjan::dept12

IQRA University, Main Campus, Karachi


80

============== Adding Elements ==================


PUT adding key:102-Sravan, value:dept3 to the list
PUT adding key:104-Ananth, value:dept2 to the list
PUT adding key:106-Rakesh, value:dept5 to the list
PUT adding key:108-Shashi, value:dept2 to the list
============== Adding Collisions =================
Collision detected for key 112-Chandu, adding element to the existing bucket
PUT adding key:112-Chandu, value:dept16 to the list
Traversing the list inside the bucket for the key 112-Chandu
GET element - 112-Chandu::dept16
Collision detected for key 114-Santhosh, adding element to the existing bucket
PUT adding key:114-Santhosh, value:dept9 to the list
Traversing the list inside the bucket for the key 114-Santhosh
GET element - 114-Santhosh::dept9
============== Adding Duplicate in Collision ===================
duplicate key value pair, replacing existing key 124-Santhosh, with value dept91
Traversing the list inside the bucket for the key 114-Santhosh
GET element - 114-Santhosh::dept91

Lab Tasks:

 Implement a method remove(s) that removes a value from hashmap.


 Implement a method isempty() that returns a boolean value a that checks whether the
hash map is empty or not.
 Implement a method clear() that removes all values from the hashmap.

IQRA University, Main Campus, Karachi


81

Data Structures

LAB-14

Name ____________________
Roll No ___________________
Date ______________________
Marks Obtained ____________
Signature___________________

Graph

Objective:
Implementation of graph in Java.

Introduction:

IQRA University, Main Campus, Karachi


82

Graphs provide the ultimate in data structure flexibility. Graphs can model both real-world
systems and abstract problems, so they are used in hundreds of applications. Here is a small
sampling of the range of problems that graphs are routinely applied to.

1. Modeling connectivity in computer and communications networks.


2. Representing a map as a set of locations with distances between locations;
used to compute shortest routes between locations.
3. Modeling flow capacities in transportation networks.
4. Finding a path from a starting condition to a goal condition; for example, in
artificial intelligence problem solving.
5. Modeling computer algorithms, showing transitions from one program state
to another.
6. Finding an acceptable order for finishing subtasks in a complex activity, such
as constructing large buildings.
7. Modeling relationships such as family trees, business or military organizations,
and scientific taxonomies.

Implementation of Graph:

import java.util.LinkedList;

public class Graph {

int V;
LinkedList<Integer> adjListArray[];

// constructor
Graph(int V)
{
this.V = V;

// define the size of array as


// number of vertices
adjListArray = new LinkedList[V];

// Create a new list for each vertex


// such that adjacent nodes can be stored
for(int i = 0; i < V ; i++){
adjListArray[i] = new LinkedList<>();
}
}

// Adds an edge to an undirected graph


static void addEdge(Graph graph, int src, int dest)
{
// Add an edge from src to dest.
graph.adjListArray[src].add(dest);

// Since graph is undirected, add an edge from dest


// to src also

IQRA University, Main Campus, Karachi


83

graph.adjListArray[dest].add(src);
}

// A utility function to print the adjacency list


// representation of graph
static void printGraph(Graph graph)
{
for(int v = 0; v < graph.V; v++)
{
System.out.println("Adjacency list of vertex "+ v);
System.out.print("head");
for(Integer pCrawl: graph.adjListArray[v]){
System.out.print(" -> "+pCrawl);
}
System.out.println("\n");
}
}

// Driver program to test above functions


public static void main(String args[])
{
// create the graph given in above figure
int V = 5;
Graph graph = new Graph(V);
addEdge(graph, 0, 1);
addEdge(graph, 0, 4);
addEdge(graph, 1, 2);
addEdge(graph, 1, 3);
addEdge(graph, 1, 4);
addEdge(graph, 2, 3);
addEdge(graph, 3, 4);

// print the adjacency list representation of


// the above graph
printGraph(graph);
}
}

IQRA University, Main Campus, Karachi

You might also like