Introduction To Data Structures - BCA
Introduction To Data Structures - BCA
Data Structure is a way of collecting and organizing data in such a way that we can perform
operations on these data in an effective way. Data Structures is about rendering data elements
in terms of some relationship, for better organization and storage. For example, we have data
player's name "Virat" and age 26. Here "Virat" is of String data type and 26 is of integer data
type.
We can organize this data as a record like Player record. Now we can collect and store
player's records in a file or database as a data structure. For example: "Dhoni" 30, "Gambhir"
31, "Sehwag" 33
In simple language, Data Structures are structures programmed to store ordered data, so that
various operations can be performed on it easily.
As we discussed above, anything that can store data can be called as a data structure, hence
Integer, Float, Boolean, Char etc, all are data structures. They are known as Primitive Data
Structures.
Then we also have some complex Data Structures, which are used to store large and
connected data. Some examples of Abstract Data Structure are:
Linked List
Tree
Graph
All these data structures allow us to perform different operations on data. We select these data
structures based on which type of operation is required. We will look into these data
structures in more details in our later lessons.
What is Algorithm ?
An algorithm is a finite set of instructions or logic, written in order, to accomplish a certain
predefined task. Algorithm is not the complete code or program, it is just the core logic
(solution) of a problem, which can be expressed either as an informal high level description
as pseudo code or using a flowchart.
An algorithm is said to be efficient and fast, if it takes less time to execute and consumes less
memory space. The performance of an algorithm is measured on the basis of following
properties:
1.
Time Complexity
2.
Space Complexity
Space Complexity
Its the amount of memory space required by the algorithm, during the course of its execution.
Space complexity must be taken seriously for multi-user systems and in situations where
limited memory is available.
An algorithm generally requires space for following components :
Instruction Space : Its the space required to store the executable version of the
program. This space is fixed, but varies depending upon the number of lines of code in the
program.
Data Space : Its the space required to store all the constants and variables value.
Environment Space : Its the space required to store the environment information
needed to resume the suspended function.
Time Complexity
Time Complexity is a way to represent the amount of time needed by the program to run to
completion. We will study this in details in our section.
2.
Big Omega denotes "more than or the same as" <expression> iterations.
3.
4.
5.
Introduction to Sorting
Sorting is nothing but storage of data in sorted order, it can be in ascending or descending
order. The term Sorting comes into picture with the term Searching. There are so many things
in our real life that we need to search, like a particular record in database, roll numbers in
merit list, a particular telephone number, any particular page in a book etc.
Sorting arranges data in a sequence which makes searching easier. Every record which is
going to be sorted will contain one key. Based on the key the record will be sorted. For
example, suppose we have a record of students, every such record will have the following
data:
Roll No.
Name
Age
Class
Here Student roll no. can be taken as key for sorting the records in ascending or descending
order. Now suppose we have to search a Student with roll no. 15, we don't need to search the
complete record we will simply search between the Students with roll no. 10 to 20.
Sorting Efficiency
There are many techniques for sorting. Implementation of particular sorting technique
depends upon situation. Sorting techniques mainly depends on two parameters. First
parameter is the execution time of program, which means time taken for execution of
program. Second is the space, which means space taken by the program.
Bubble Sort
2.
Insertion Sort
3.
Selection Sort
4.
Quick Sort
5.
Merge Sort
6.
Heap Sort
Bubble Sorting
Bubble Sort is an algorithm which is used to sort N elements that are given in a memory for
eg: an Array with N number of elements. Bubble Sort compares all the element one by one
and sort them based on their values.
It is called Bubble sort, because with each iteration the smaller element in the list bubbles up
towards the first place, just like a water bubble rises up to the water surface.
Sorting takes place by stepping through all the data items one-by-one in pairs and comparing
adjacent data items and swapping each pair that is out of order.
int i, j, temp;
for(i=0; i<6, i++)
{
for(j=0; j<6-i-1; j++)
{
int flag = 0;
}
}
if(!flag)
{
break;
}
}
In the above code, if in a complete single cycle of j iteration(inner for loop), no swapping
takes place, and flag remains 0, then we will break out of the for loops, because the array has
already been sorted.
Insertion Sorting
It is a simple Sorting algorithm which sorts the array by shifting elements one by one.
Following are some of the important characteristics of Insertion Sort.
1.
2.
It is efficient for smaller data sets, but very inefficient for larger lists.
3.
4.
5.
6.
Insertion Sort is adaptive, that means it reduces its total number of steps if given a
partially sorted list, hence it increases its efficiency.
It is better than Selection Sort and Bubble Sort algorithms.
Its space complexity is less, like Bubble Sorting, inerstion sort also requires a single
additional memory space.
It is Stable, as it does not change the relative order of elements with equal keys
10
In the above array, first we pick 1 as key, we compare it with 5(element before 1), 1 is smaller
than 5, we shift 1 before 5. Then we pick 6, and compare it with 5 and 1, no shifting this time.
Then 2 becomes the key and is compared with, 6 and 5, and then 2 is placed after 1. And this
goes on, until complete array gets sorted.
Selection Sorting
Selection sorting is conceptually the most simplest sorting algorithm. This algorithm first
finds the smallest element in the array and exchanges it with the element in the first position,
then find the second smallest element and exchange it with the element in the second
position, and continues in this way until the entire array is sorted.
In the first pass, the smallest element found is 1, so it is placed at the first position, then
leaving first element, smallest element is searched from the rest of the elements, 3 is the
11
smallest, so it is then placed at the second position. Then we leave 1 nad 3, from the rest of
the elements, we search for the smallest and put it at third position and keep doing this, until
array is sorted.
2.
Pivot element
3.
In the list of elements, mentioned in below example, we have taken 25 as pivot. So after the
first pass, the list will be changed like this.
6 8 17 14 25 63 37 52
12
Hence after the first pass, pivot will be set at its position, with all the elements smaller to it on
its left and all the elements larger than it on the right. Now 6 8 17 14 and 63 37 52 are
considered as two separate lists, and same logic is applied on them, and we keep doing this
until the complete list is sorted.
14
Like we can see in the above example, merge sort first breaks the unsorted list into sorted
sublists, and then keep merging these sublists, to finally get the complete sorted list.
k = 0;
i = p;
j = q+1;
while(i <= q && j <= r)
{
if(a[i] < a[j])
{
b[k++] = a[i++];
}
else
{
b[k++] = a[j++];
}
}
while(i <= q)
{
b[k++] = a[i++];
}
while(j <= r)
{
b[k++] = a[j++];
}
for(i=r; i >= p; i--)
{
a[i] = b[--k];
}
}
16
What is a Heap?
Heap is a special tree-based data structure that satisfies the following special heap properties:
1.
Shape Property: Heap data structure is always a Complete Binary Tree, which means
all levels of the tree are fully filled.
2. Heap Property : All nodes are either [greater than or equal to] or [less than or equal
to] each of its children. If the parent nodes are greater than their children, heap is called
a Max-Heap, and if the parent nodes are smaller than their child nodes, heap is
called Min-Heap.
heapsize--;
satisfyheap(a, 0, heapsize);
}
for( i=0; i < length; i++)
{
cout << "\t" << a[i];
}
}
void buildheap(int a[], int length)
{
int i, heapsize;
heapsize = length - 1;
for( i=(length/2); i >= 0; i--)
{
satisfyheap(a, i, heapsize);
}
}
void satisfyheap(int a[], int i, int heapsize)
{
int l, r, largest, temp;
l = 2*i;
r = 2*i + 1;
if(l <= heapsize && a[l] > a[i])
{
largest = l;
}
else
{
largest = i;
}
if( r <= heapsize && a[r] > a[largest])
{
largest = r;
}
19
if(largest != i)
{
temp = a[i];
a[i] = a[largest];
a[largest] = temp;
satisfyheap(a, largest, heapsize);
}
}
Stacks
Stack is an abstract data type with abounded(predefined) capacity. It is a simple data structure
that allows adding and removing elements in a particular order. Every time an element is
added, it goes on the top of the stack, the only element that can be removed is the element
that was at the top of the stack, just like a pile of objects.
2.
3.
push() function is used to insert new elements into the Stack and pop() is used to
delete an element from the stack. Both insertion and deletion are allowed at only one end
of Stack called Top.
4.
20
Applications of Stack
The simplest application of a stack is to reverse a word. You push a given word to stack letter by letter - and then pop letters from the stack.
There are other uses also like : Parsing, Expression Conversion(Infix to Postfix, Postfix to
Prefix etc) and many more.
Implementation of Stack
Stack can be easily implemented using an Array or a Linked List. Arrays are quick, but are
limited in size and Linked List requires overhead to allocate, link, unlink, and deallocate, but
is not limited in size. Here we will implement Stack using array.
Stack()
{
top = -1;
}
};
void Stack::push(int x)
{
21
Status of Stack
-1
Stack is Empty
22
N-1
Stack is Full
Like Stack, Queue is also an ordered list of elements of similar data types.
2.
3.
Once a new element is inserted into the Queue, all the elements inserted before the
new element in the queue must be removed, to remove the new element.
4.
Peek ( ) function is often used to return the value of first element without dequeuing
it.
23
Applications of Queue
Queue, as the name suggests is used whenever we need to have any group of objects in an
order in which the first one coming in also gets out first while the others wait for their turn,
like in the following scenarios:
1.
Serving requests on a single shared resource, like a printer, CPU task scheduling etc.
2.
In real life, Call Center phone systems will use Queues, to hold people calling them in
an order, until a service representative is free.
3.
Handling of interrupts in real-time systems. The interrupts are handled in the same
order as they arrive, First come first served.
Implementation of Queue
Queue can be implemented using an Array, Stack or Linked List. The easiest way of
implementing a queue is by using an Array. Initially the head(FRONT) and the tail(REAR)
of the queue points at the first index of the array (starting the index of array from 0). As we
add elements to the queue, the tail keeps on moving ahead, always pointing to the position
where the next element will be inserted, while the head remains at the first index.
24
When we remove element from Queue, we can follow two possible approaches (mentioned
[A] and [B] in above diagram). In [A] approach, we remove the element at head position, and
then one by one move all the other elements on position forward. In approach [B] we remove
the element from head position and then move head to the next position.
In approach [A] there is an overhead of shifting the elements one position forward every time
we remove the first element. In approach [B] there is no such overhead, but whenever we
move head one position ahead, after removal of first element, the size on Queue is reduced by
one space each time.
/* Below program is wtitten in C++ language */
#define SIZE 100
class Queue
{
int a[100];
int rear;
//same as tail
int front;
//same as head
public:
Queue()
{
rear = front = -1;
}
void enqueue(int x);
int dequeue();
void display();
}
void Queue :: enqueue(int x)
{
if( rear = SIZE-1)
{
cout << "Queue is full";
}
else
{
a[++rear] = x;
}
25
}
int queue :: dequeue()
{
return a[++front];
}
void queue :: display()
{
int i;
for( i = front; i <= rear; i++)
{
cout << a[i];
}
}
To implement approach [A], you simply need to change the dequeue method, and include a
for loop which will shift all the remaining elements one position.
return a[0];
26
27