ICT-2103
Introduction to Data Structures:
Data Structure is a way of collecting and organising data in such a way that we can perform operations on these data in an effective way.
Data:
2K apple @ $25.6 3K banana @ $16.5
struct product { int weight; double price; };
product apple, banana;
apple.weight = 2; apple.price = 25.6; banana.weight = 3; banana.price = 16.5;
General types of Data Structures:
✔ Primitive Data Structures: Built-in support
✔ Abstract Data Structures: Derived, implementation independent (User defined)
Basic Operations:
The data in the data structures are processed by certain operations. The particular data structure chosen largely depends on the frequency of the operation that needs to be performed on the data structure.
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 can be expressed either as an informal high level description as pseudocode or using a flowchart.
The performance of an algorithm is said to be efficient and fast, if it takes less time to execute and consumes less memory space.
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.
Calculating Time Complexity: Now the most common metric for calculating time complexity is Big O notation. This removes all constant factors so that the running time can be estimated in relation to N, as N approaches infinity. In general you can think of it like this :
statement;
Above we have a single statement. Its Time Complexity will be Constant. The running time of the statement will not change in relation to N.
for(i=0; i < N; i++) {
statement; }
The time complexity for the above algorithm will be Linear. The running time of the loop is directly proportional to N. When N doubles, so does the running time.
for(i=0; i < N; i++) {
for(j=0; j < N;j++) {
statement; }
This time, the time complexity for the above code will be Quadratic. The running time of the two loops is proportional to the square of N. When N doubles, the running time increases by N * N.
while(low <= high) {
mid = (low + high) / 2; if (target < list[mid]) high = mid - 1;
else if (target > list[mid]) low = mid + 1;
else break; }
This is an algorithm to break a set of numbers into halves, to search a particular field. Now, this algorithm will have a Logarithmic Time Complexity. The running time of the algorithm is proportional to the number of times N can be divided by 2 (N is high-low here). This is because the algorithm divides the working area in half with each iteration.
void quicksort(int list[], int left, int right) {
int pivot = partition(list, left, right); quicksort(list, left, pivot - 1); quicksort(list, pivot + 1, right); }
Taking the previous algorithm forward, above we have a small logic of Quick Sort (we will study this in detail later). Now in Quick Sort, we divide the list into halves every time, but we repeat the iteration N times(where N is the size of list). Hence time complexity will be N*log( N ). The running time consists of N loops (iterative or recursive) that are logarithmic, thus the algorithm is a combination of linear and logarithmic.
Note: In general, doing something with every item in one dimension is linear, doing something with every item in two dimensions is quadratic, and dividing the working area in half is logarithmic
Types of Notations for Time Complexity
Now we will discuss and understand the various notations used for Time Complexity.
1)Big Oh denotes "fewer than or the same as" <expression> iterations (worst-case). 2)Big Omega denotes "more than or the same as" <expression> iterations.
3)Big Theta denotes "the same as" <expression> iterations. 4)Little Oh denotes "fewer than" <expression> iterations. 5)Little Omega denotes "more than" <expression> iterations.
Understanding Notations of Time Complexity with Example:
O(expression) is the set of functions that grow slower than or at the same rate as expression. Omega(expression) is the set of functions that grow faster than or at the same rate as expression. Theta(expression) consist of all the functions that lie in both O(expression) and Omega(expression).
Suppose you've calculated that an algorithm takes f(n) operations, where, f(n) = 3*n^2 + 2*n + 4. // n^2 means square of n
Since this polynomial grows at the same rate as n^2, then you could say that the function f lies in the set Theta(n^2). (It also lies in the sets O(n^2) and Omega(n^2) for the same reason.)
Array and string
Array is a very basic data structure representing a group of similar elements, accessed by index. Array data structure can be effectively stored inside the computer and provides fast access to the all its elements.
Advantages
✔ No overhead per element.
✔ Any element of an array can be accessed at O(1) time by its index.
Drawbacks
allocated and old data is copied to it.
✔ Insertion and deletion of an element in the array requires to shift O(n) elements on average, where n is size of the array.
Static and dynamically-allocated arrays
There are two types of arrays, which differ in the method of allocation. Static array has constant size and exists all the time, application being executed. Dynamically allocated array is created during program run and may be deleted when it is not more needed. Dynamically allocated arrays can be quite large, even bigger, than amount of physical memory. Yet, dynamically allocated array can not be resized. But you can expand an array as noted below:
1) Create new array of bigger size;
2) Copy data from old array to the new one; 3) Free memory, occupied by the old array.
Fixed-size and dynamic arrays
As it mentioned above, arrays can't be resized. In this case array is called fixed-size array. But we can use a simple trick to construct a dynamic array, which can be resized.
The idea is simple. Let us allocate some space for the dynamic array and imaginary divide it into two parts. One part contains the data and the other one is free space. When new element is added, free space is reduced and vice versa. This approach results in overhead for free space, but we have all advantages of arrays and capability of changing size dynamically. We present some definitions about this kind of arrays below.
Dynamic array has its capacity, which shows the maximum number of elements, it can contain. Also, such an array has the logical size, which indicates, how much elements it actually contains. For instance, we would like to find minimum of the values user entering. We allocate space to store 15 elements, but user has entered only 5 numbers. In the example, capacity of an array is 15 elements, but logical size is 5 elements. When dynamic array becomes full, it must be expanded by creating new larger array and copying elements from the old array to the new one. Notice, that copying arrays is supported by the hardware and can be done very efficiently.
Example. Dynamic array with capacity 10, logical size 5.
1 5 7 -8 4 0 -49 15 86 46
http://www.tutorialspoint.com/data_structures_algorithms/array_data_structure.htm Copyright © tutorialspoint.com
DATA STRUCTURE - ARRAYS
DATA STRUCTURE - ARRAYS
Array is a container which can hold fix number of items and these items should be of same type. Most of the datastructure make use of array to implement their algorithms. Following are
important terms to understand the concepts of Array.
Element − Each item stored in an array is called an element.
Index − Each location of an element in an array has a numerical index which is used to identify the element.
Array Representation
Arrays can be declared in various ways in different languages. For illustration, let's take C array declaration.
Arrays can be declared in various ways in different languages. For illustration, let's take C array declaration.
As per above shown illustration, following are the important points to be considered.
Index starts with 0.
Array length is 8 which means it can store 8 elements.
Each element can be accessed via its index. For example, we can fetch element at index 6 as 9.
Basic Operations
Following are the basic operations supported by an array.
Traverse − print all the array elements one by one.
Insertion − add an element at given index.
Deletion − delete an element at given index.
Search − search an element using given index or by value.
Update − update an element at given index.
In C, when an array is initialized with size, then it assigns defaults values to its elements in following order.
bool false
char 0
int 0
float 0.0
double 0.0f
void
wchar_t 0
Insertion Operation
Insert operation is to insert one or more data elements into an array. Based on the requirement, new element can be added at the beginning, end or any given index of array.
Here, we see a practical implementation of insertion operation, where we add data at the end of the array −
Algorithm
Let Array is a linear unordered array of MAX elements.
Example
Result
Let LA is a Linear Array unordered with N elements and K is a positive integer such that K<=N. Below is the algorithm where ITEM is inserted into the Kth position of LA −
1. Start 2. Set J=N 3. Set N = N+1
4. Repeat steps 5 and 6 while J >= K 5. Set LA[J+1] = LA[J]
6. Set J = J-1 7. Set LA[K] = ITEM 8. Stop
Example
Below is the implementation of the above algorithm −
#include <stdio.h>
main() {
int LA[] = {1,3,5,7,8};
int item = 10, k = 3, n = 5;
int i = 0, j = n;
printf("The original array elements are :\n");
for(i = 0; i<n; i++) {
printf("LA[%d] = %d \n", i, LA[i]);
}
n = n + 1;
while( j >= k){
LA[j+1] = LA[j];
j = j - 1;
LA[k] = item;
printf("The array elements after insertion :\n");
for(i = 0; i<n; i++) {
printf("LA[%d] = %d \n", i, LA[i]);
} }
When compile and execute, above program produces the following result −
The original array elements are : LA[0]=1
LA[1]=3 LA[2]=5 LA[3]=7 LA[4]=8
The array elements after insertion : LA[0]=1
LA[1]=3 LA[2]=5 LA[3]=10 LA[4]=7 LA[5]=8
For other variations of array insertion operation click here
Deletion Operation
Deletion refers to removing an existing element from the array and re-organizing all elements of an array.
Algorithm
Consider LA is a linear array with N elements and K is a positive integer such that K<=N. Below is the algorithm to delete an element available at the Kth position of LA.
1. Start 2. Set J=K
3. Repeat steps 4 and 5 while J < N 4. Set LA[J-1] = LA[J]
5. Set J = J+1 6. Set N = N-1 7. Stop
Example
Below is the implementation of the above algorithm −
#include <stdio.h>
main() {
int LA[] = {1,3,5,7,8};
int k = 3, n = 5;
int i, j;
printf("The original array elements are :\n");
for(i = 0; i<n; i++) {
printf("LA[%d] = %d \n", i, LA[i]);
}
j = k;
while( j < n){
j = j + 1;
}
n = n -1;
printf("The array elements after deletion :\n");
for(i = 0; i<n; i++) {
printf("LA[%d] = %d \n", i, LA[i]);
} }
When compile and execute, above program produces the following result −
The original array elements are : LA[0]=1
LA[1]=3 LA[2]=5 LA[3]=7 LA[4]=8
The array elements after deletion : LA[0]=1
LA[1]=3 LA[2]=7 LA[3]=8
Search Operation
You can perform a search for array element based on its value or its index.
Algorithm
Consider LA is a linear array with N elements and K is a positive integer such that K<=N. Below is the algorithm to find an element with a value of ITEM using sequential search.
1. Start 2. Set J=0
3. Repeat steps 4 and 5 while J < N
4. IF LA[J] is equal ITEM THEN GOTO STEP 6 5. Set J = J +1
6. PRINT J, ITEM 7. Stop
Example
Below is the implementation of the above algorithm −
#include <stdio.h>
main() {
int LA[] = {1,3,5,7,8};
int item = 5, n = 5;
int i = 0, j = 0;
printf("The original array elements are :\n");
for(i = 0; i<n; i++) {
printf("LA[%d] = %d \n", i, LA[i]);
}
while( j < n){
if( LA[j] == item ){
break;
}
}
printf("Found element %d at position %d\n", item, j+1); }
When compile and execute, above program produces the following result −
The original array elements are : LA[0]=1
LA[1]=3 LA[2]=5 LA[3]=7 LA[4]=8
Found element 5 at position 3
Update Operation
Update operation refers to updating an existing element from the array at a given index.
Algorithm
Consider LA is a linear array with N elements and K is a positive integer such that K<=N. Below is the algorithm to update an element available at the Kth position of LA.
1. Start
2. Set LA[K-1] = ITEM 3. Stop
Example
Below is the implementation of the above algorithm −
#include <stdio.h>
main() {
int LA[] = {1,3,5,7,8};
int k = 3, n = 5, item = 10;
int i, j;
printf("The original array elements are :\n");
for(i = 0; i<n; i++) {
printf("LA[%d] = %d \n", i, LA[i]);
}
LA[k-1] = item;
printf("The array elements after updation :\n");
for(i = 0; i<n; i++) {
printf("LA[%d] = %d \n", i, LA[i]);
} }
When compile and execute, above program produces the following result −
The original array elements are : LA[0]=1
LA[1]=3 LA[2]=5 LA[3]=7 LA[4]=8
The array elements after updation : LA[0]=1
LA[3]=7 LA[4]=8