0% found this document useful (0 votes)
14 views109 pages

Data Structures and Algorithms Overview

Uploaded by

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

Data Structures and Algorithms Overview

Uploaded by

benti
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd

Data Structures &

Algorithms

Week1
Contents

 Textbook
 Grade
 Software
Textbook

C & Data Structures


– P. S. Deshpande, O. G. Kakde
– CHARLES RIVER MEDIA, INC.
Hingham, Massachusetts
Grade

 Midterm test (Lab)


 Final test (Lab)
 Project (working on group)
 Multiple choice test
 How to Grade
Grade
Software: C/C++ edittor

 BC++, TC++
 C-Free is a professional C/C++ integrated
development environment (IDE) that support multi-
compilers. Use of this software, user can edit, build,
run and debug programs freely.

With C/C++ source parser included


 Lightweight C/C++ development tool.
 [Link]
C/C++ edittor: demo

 Find max of 3 numbers: a,b,c


– Using scanf, prinf (C standard)
– Using cin, cout (Cpp)
CHAPTER 0: INTRODUTION

 What is Data Structures?


– A data structure is defined by
 (1) the logical arrangement of data elements,
combined with
 (2) the set of operations we need to access the
elements.
Atomic Variables

 Atomic variables can only store one value at


a time.
int num;
float s;
A value stored in an atomic variable cannot
be subdivided.
What is Data Structures?

 Example:library
– is composed of elements
(books)
– Accessing a particular
book requires knowledge
of the arrangement of the
books
– Users access books only
through the librarian
the logical arrangement of data elements,
combined with
the set of operations we need to access the
elements.
Basic Data Structures

 Structures include
– linked lists
– Stack, Queue
– binary trees
– …and others
What is Algorithm?

 Algorithm:
– A computable set of steps to achieve a desired
result
– Ralationship to Data Structure
 Example: Find an element

2 4 6

1 3 5 7

1 2 3 4 5 6 7
Sumary
Chapter 0: C LANGUAGE

1. ADDRESS
2. POINTERS
3. ARRAYS
4. ADDRESS OF EACH ELEMENT IN AN ARRAY
5. ACCESSING & MANIPULATING AN ARRAY USING
POINTERS
6. ANOTHER CASE OF MANIPULATING AN ARRAY USING
POINTERS
7. TWO-DIMENSIONAL ARRAY
8. POINTER ARRAYS
9. STRUCTURES
10. STRUCTURE POINTERS
Chapter 0: C LANGUAGE

1. ADDRESS
For every variable there are two attributes:
address and value

In memory with address 3: value: 45.


In memory with address 2: value "Dave"

cout << "Value of 'y' is: " << y << "\n";


cout << "Address of 'y' is: " << &y << "\n\n";
Chapter 0: C LANGUAGE

2. POINTERS
1. is a variable whose value is also an address.
2. A pointer to an integer is a variable that can
store the address of that integer
ia: value of variable
&ia: address of ia
*ia means you are printing the value at the
location specified by ia
Chapter 0: C LANGUAGE

int i; //A
int * ia; //B
cout<<"The address of i "<< &i << " value="<<i <<endl;
cout<<"The address of ia " << &ia << " value = " << ia<< endl;

i = 10; //C
ia = &i; //D

cout<<"after assigning value:"<<endl;


cout<<"The address of i "<< &i << " value="<<i <<endl;
cout<<"The address of ia " << &ia << " value = " << ia<< " point to: "<< *ia;
Chapter 0: C LANGUAGE

Points to Remember

• Pointers give a facility to access the value of


a variable indirectly.
• You can define a pointer by including a *
before the name of the variable.
• You can get the address where a variable is
stored by using &.
Chapter 0: C LANGUAGE

3. ARRAYS
1. An array is a data structure
2. used to process multiple elements with the same data
type when a number of such elements are known.
3. An array is a composite data structure; that means it
had to be constructed from basic data types such as
array integers.

1. int a[5];
2. for(int i = 0;i<5;i++)
1. {a[i]=i; }
Chapter 0: C LANGUAGE

4. ADDRESS OF EACH ELEMENT IN AN


ARRAY
Each element of the array has a memory
address.
void printdetail(int a[])
{
for(int i = 0;i<5;i++)
{
cout<< "value in array “<< a[i] <<“ at address: “ << &a[i]);
}
Chapter 0: C LANGUAGE

5. ACCESSING & MANIPULATING AN


ARRAY USING POINTERS
– You can access an array element by using a pointer.
– If an array stores integers->use a pointer to integer to
access array elements.
Chapter 0: C LANGUAGE

6. ANOTHER CASE OF MANIPULATING AN


ARRAY USING POINTERS
The array limit is a pointer constant : cannot
change its value in the program.

It works correctly even using


int a[5]; int *b; a++ ???

a=b; //error
b=a; //OK
Chapter 0: C LANGUAGE

7. TWO-DIMENSIONAL ARRAY
int a[3][2];
Chapter 0: C LANGUAGE

8. POINTER ARRAYS
 You can define a pointer array (similarly to an array of
integers).
 In the pointer array, the array elements store the
pointer that points to integer values.
Chapter 0: C LANGUAGE

9. STRUCTURES
 Structures are used when
you want to process data of
multiple data types
 But you still want to refer to
the data as a single entity
 Access data:
[Link]
e
Chapter 1: C LANGUAGE

10. STRUCTURE POINTERS


Process the structure using a structure pointer
CHAPTER 2: FUNCTION & RECURSION

 1. FUNCTION
 2. THE CONCEPT OF STACK
 3. THE SEQUENCE OF EXECUTION DURING A
FUNCTION CALL
 4. PARAMETER PASSING
 5. CALL BY REFERENCE
 6. RESOLVING VARIABLE REFERENCES
 7. RECURSION
 8. STACK OVERHEADS IN RECURSION
 9. WRITING A RECURSIVE FUNCTION
 10. TYPES OF RECURSION
CHAPTER 2: FUNCTION & RECURSION

 1. FUNCTION
– provide modularity to the software
– divide complex tasks into small manageable tasks
– avoid duplication of work
CHAPTER 2: FUNCTION & RECURSION

 2. THE CONCEPT OF STACK


– A stack is memory in which values are stored and
retrieved in "last in first out" manner by using
operations called push and pop.
CHAPTER 2: FUNCTION & RECURSION

 3. THE SEQUENCE OF EXECUTION DURING


A FUNCTION CALL
– When the function is called, the current execution is
temporarily stopped and the control goes to the called
function. After the call, the execution resumes from the
point at which the execution is stopped.
– To get the exact point at which execution is resumed, the
address of the next instruction is stored in the stack. When
the function call completes, the address at the top of the
stack is taken.
CHAPTER 2: FUNCTION & RECURSION

 3. THE SEQUENCE OF EXECUTION


DURING A FUNCTION CALL
– Functions or sub-programs are implemented
using a stack.
– When a function is called, the address of the next
instruction is pushed into the stack.
– When the function is finished, the address for
execution is taken by using the pop operation.
CHAPTER 2: FUNCTION & RECURSION

 3. THE SEQUENCE OF
EXECUTION DURING A
FUNCTION CALL
 Result:?
CHAPTER 2: FUNCTION & RECURSION

 4. PARAMETER * REFERENCE
PASSING
– passing by value
 the value before and after the call remains the same
– passing by reference
 changed value after the function completes
CHAPTER 2: FUNCTION & RECURSION

 6. RESOLVING VARIABLE
REFERENCES
When a variable can
be resolved by using
multiple references,
the local definition is
given more preference
CHAPTER 2: FUNCTION & RECURSION

 7. RECURSION
– A method of
programming
whereby a function
directly or indirectly
calls itself
– Problems: stop
recursion?
CHAPTER 2: FUNCTION & RECURSION

 7. RECURSION
CHAPTER 2: FUNCTION & RECURSION

 7.
RECURSION:
Hanoi tower
CHAPTER 2: FUNCTION & RECURSION

 7. RECURSION
CHAPTER 2: FUNCTION & RECURSION

 8. STACK OVERHEADS IN RECURSION


– two important results: the depth of recursion and
the stack overheads in recursion
CHAPTER 2: FUNCTION & RECURSION

 9. WRITING A RECURSIVE FUNCTION


– Recursion enables us to write a program in a
natural way. The speed of a recursive program
is slower because of stack overheads.
– In a recursive program you have to specify
recursive conditions, terminating conditions, and
recursive expressions.
CHAPTER 2: FUNCTION & RECURSION

 10. TYPES OF RECURSION


– LINEAR RECURSION (tuyến tính)
– TAIL RECURSION (đuôi)
– BINARY RECURSION (nhị phân)
– EXPONENTIAL RECURSION (đa tuyến)
– NESTED RECURSION (lồng)
– MUTUAL RECURSION (tương hỗ)
CHAPTER 2: FUNCTION & RECURSION

 10. TYPES OF RECURSION


– LINEAR RECURSION
 only makes a single call to itself each time the
function runs

CHAPTER 2: FUNCTION & RECURSION

 10. TYPES OF RECURSION


– TAIL RECURSION
 Tail recursion is a form of linear recursion.
 In tail recursion, the recursive call is the last thing
the function does. Often, the value of the recursive
call is returned.
CHAPTER 2: FUNCTION & RECURSION

 10. TYPES OF RECURSION


– BINARY RECURSION
 Somerecursive functions don't just have one call to
themself, they have two (or more).
CHAPTER 2: FUNCTION & RECURSION

 10. TYPES OF RECURSION


– EXPONENTIAL RECURSION
 An exponential recursive function is one that, if you
were to draw out a representation of all the function
calls, would have an exponential number of calls in
relation to the size of the data set
 (exponential meaning if there were n elements, there
would be O(an) function calls where a is a positive
number)
CHAPTER 2: FUNCTION & RECURSION

 10. TYPES OF RECURSION


– EXPONENTIAL RECURSION
CHAPTER 2: FUNCTION & RECURSION

 10. TYPES OF RECURSION


– NESTED RECURSION
 Innested recursion, one of the arguments to the
recursive function is the recursive function itself
 These functions tend to grow extremely fast.
CHAPTER 2: FUNCTION & RECURSION

 10. TYPES OF RECURSION


– MUTUAL RECURSION
A recursive function doesn't necessarily need to call
itself.
 Some recursive functions work in pairs or even larger
groups. For example, function A calls function B which
calls function C which in turn calls function A.
CHAPTER 2: FUNCTION & RECURSION

 10. TYPES OF RECURSION


– MUTUAL RECURSION
Exercises 1: Recursion
Exercises 2: Recursion

 Convert number from H10->H2

7 2

1 3 2

1 1 2
1 0
Week3: Recursion Excercises (1)

 E1.(44/174) Write a program to compute: S


= 1 + 2 + 3 + …n using recursion.
Week3: Recursion Excercises (2-3)

 E3(a).Write a program to print a revert


number Example: input n=12345. Print
out: 54321.

 E3(b).Write a program to print this number


Example: input n=12345. Print out:
12345.
Week3: Recursion Excercises (4)

 [Link] a recursion function to find the sum


of every number in a int number. Example:
n=1980 => Sum=1+9+8+0=18.
Week3: Recursion Excercises (5)

 E4. Write a recursion function to calculate:


– S=a[0]+a[1]+…a[n-1]
 A: array of integer numbers
Week3: Recursion Excercises (6)

 [Link] a recursion function to find an


element in an array (using linear algorithm)
Week3: Recursion Excercises (7)

 Print triangle

c d

a b
Week3: Recursion Excercises (8)

 Convert number from H10->H2

7 2

1 3 2

1 1 2
1 0
Week3: Recursion Excercises (9)

 Minesweeper
Week 4

CHAPTER 3: SEARCHING TECHNIQUES


1. LINEAR (SEQUENTIAL) SEARCH
2. BINARY SEARCH
3. COMPLEXITY OF ALGORITHMS
SEARCHING TECHNIQUES

 To finding out whether a particular element is


present in the list.
 2 methods: linear search, binary search
 The method we use depends on how the
elements of the list are organized
– unordered list:
 linear search: simple, slow
– an ordered list
 binary search or linear search: complex, faster
1. LINEAR (SEQUENTIAL) SEARCH

 How?
– Proceeds by sequentially comparing the key with
elements in the list
– Continues until either we find a match or the end
of the list is encountered.
– If we find a match, the search terminates
successfully by returning the index of the element
– If the end of the list is encountered without a
match, the search terminates unsuccessfully.
1. LINEAR (SEQUENTIAL) SEARCH

void lsearch(int list[],int n,int element)


{ int i, flag = 0;
for(i=0;i<n;i++)
if( list[i] == element)
{ cout<<“found at position”<<i;
flag =1;
break; } flag: what for???

if( flag == 0)
cout<<“ not found”;
}
1. LINEAR (SEQUENTIAL) SEARCH

int lsearch(int list[],int n,int element)


{ int i, find= -1;
for(i=0;i<n;i++)
if( list[i] == element) Another way using flag

{find =i;
break;}
return find;
} average time: O(n)
2. BINARY SEARCH

 List must be a sorted one


 We compare the element with the element
placed approximately in the middle of the list
 If a match is found, the search terminates
successfully.
 Otherwise, we continue the search for the
key in a similar manner either in the upper
half or the lower half.
Baba? Eat?
void bsearch(int list[],int n,int element)
{
int l,u,m, flag = 0;
l = 0; u = n-1;
while(l <= u)
{ m = (l+u)/2;
if( list[m] == element)
{cout<<"found:"<<m;
flag =1;
break;}
else
if(list[m] < element)
l = m+1;
else
u = m-1;
} average time: O(log2n)
if( flag == 0)
cout<<"not found";
}
BINARY SEARCH: Recursion

int Search (int list[], int key, int left, int right)
{
if (left <= right) {
int middle = (left + right)/2;
if (key == list[middle])
return middle;
else if (key < list[middle])
return Search(list,key,left,middle-1);
else return Search(list,key,middle+1,right);
}
return -1;
}
3. COMPLEXITY OF ALGORITHMS

 In Computer Science, it is important to measure the


quality of algorithms, especially the specific amount
of a certain resource an algorithm needs
 Resources: time or memory storage (PDA?)
 Different algorithms do same task with a different set
of instructions in less or more time, space or effort
than other.
 The analysis has a strong mathematical background.
 The most common way of qualifying an algorithm is
the Asymptotic Notation, also called Big O.
3. COMPLEXITY OF ALGORITHMS
 It is generally written as

 Polynomial time algorithms,


– O(1) --- Constant time --- the time does not change in response to
the size of the problem.
– O(n) --- Linear time --- the time grows linearly with the size (n) of
the problem.
– O(n2) --- Quadratic time --- the time grows quadratically with the
size (n) of the problem. In big O notation, all polynomials with the
same degree are equivalent, so O(3n2 + 3n + 7) = O(n2)
 Sub-linear time algorithms
– O(logn) -- Logarithmic time
 Super-polynomial time algorithms
– O(n!)
– O(2n)
3. COMPLEXITY OF ALGORITHMS

 Example1: complexity of an algorithm


void f ( int a[], int n )
{
int i; 2 * O(1)? + O(N)
cout<< "N = “<< n;
for ( i = 0; i < n; i++ )
cout<<a[i];
printf ( "n" );
} O(N)
?
3. COMPLEXITY OF ALGORITHMS

 Example2: complexity of an algorithm


void f ( int a[], int n )
{ int i;
cout<< "N = “<< n;
2 * O(1) + O(N)+O(N
? 2
)
for ( i = 0; i < n; i++ )
for (int j=0;j<n;j++)
cout<<a[i]<<a[j];

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


cout<<a[i]; O(N2)
?
printf ( "n" );
}
3. COMPLEXITY OF ALGORITHMS

 Linear Search
– O(n).
 Binary Search
– O(log2 N)
Week 4

CHAPTER 4: SORTING TECHNIQUES


1. BUBBLE SORT
2. INSERTION SORT
3. SELECTION SORT
4. QUICK SORT
SORTING TECHNIQUES
SORTING TECHNIQUES

We need to do sorting for the following reasons :


a) By keeping a data file sorted, we can do binary
search on it.
b) Doing certain operations, like matching data in
two different files, become much faster.
There are various methods for sorting: Bubble sort,
Insertion sort, Selection sort, Quick sort, Heap sort,
Merge sort…. They having different average and
worst case behaviours:
1. BUBBLE SORT

Introduction:
Bubble sorting is a simple sorting technique in
which we arrange the elements of the list by
forming pairs of adjacent elements. That
means we form the pair of the ith and (i+1)th
element. If the order is ascending, we
interchange the elements of the pair if the
first element of the pair is greater than the
second element.
1. BUBBLE SORT

Bubble sort: beginning of first pass


1. BUBBLE SORT
1. BUBBLE SORT

Bubble sort: end of First pass


1. BUBBLE SORT

void bsort(int list[], int n)


{
int i,j;
for(i=0;i<(n-1);i++)
for(j=0;j<(n-(i+1));j++)
if(list[j] > list[j+1])
swap(&list[j],&list[j+1]);
}
2. INSERTION SORT

Introduction:
Basic Idea: Insert a record R into a
sequence of ordered records: R1,R2,.., Ri
with keys K1 <= K2 <= ... <= Ki , such that,
the resulting sequence of size i+1 is also
ordered with respect to key values.
2. INSERTION SORT
2. INSERTION SORT
2. INSERTION SORT
Algorithm Insertion_Sort; (* Assume Ro has Ko = -maxint *)
void InsertionSort( Item &list[])
{ // Insertion_Sort
Item r;
int i,j;
list[0].key = -maxint;
for (j=2; j<=n; j++)
{ r=list[j];
i=j-1;
while ( [Link] < list[i].key )
{// move greater entries to the right
list[i+1]:=list[i];
i:=i-1;
};
list[i+1] = r // insert into it's place
}
}
3. SELECTION SORT

Selection sort is a simplicity sorting algorithm. It


works as its name as it is. Here are basic
steps of selection sort algorithm:
1. Find the minimum element in the list
2. Swap it with the element in the first position
of the list
3. Repeat the steps above for all remainder
elements of the list starting at the second
position.
3. SELECTION SORT
3. SELECTION SORT
3. SELECTION SORT

void selection_sort(int list[], int n){


int i, j, min; for (i = 0; i < n - 1; i++) {
min = i;
for (j = i+1; j < n; j++) {
if (list[j] < list[min]) {
min = j;
}
}
swap(&list[i], &list[min]);
}
4. QUICK SORT
4. QUICK SORT
4. QUICK SORT
4. QUICK SORT
4. QUICK SORT

Chọn ngẫu nhiên một phần tử X của dãy (chẳng


hạn phần tử đầu tiên) và cố gắng phân chia dãy
này thành 3 dãy con liên tiếp nhau:
+ Dãy 1: Gồm những phần tử nhỏ hơn X.
+ Dãy 2: Gồm những phần tử bằng X.
+ Dãy 3: Gồm những phần tử lớn hơn X.
Sau đó áp dụng lại giải thuật này cho dãy con thứ
nhất và dãy con thứ ba (dãy con này có số phần
tử lớn hơn 1).
4. QUICK SORT
4. QUICK SORT
4. QUICK SORT
4. QUICK SORT
Week 6

CHAPTER 6: LINKED LISTS


Introduction

When dealing with many problems we need a dynamic


list, dynamic in the sense that the size requirement
need not be known at compile time. Thus, the list
may grow or shrink during runtime. A linked list is a
data structure that is used to model such a dynamic
list of data items, so the study of the linked lists as
one of the data structures is important.
Concept
Data Structures

struct node
{
int data;
struct node *link;
};
struct node *insert(struct node *p, int n) {
struct node *temp;
if(p==NULL){
p=new node;
if(p==NULL){
Data Structures printf("Error\n");
exit(0);
}
p-> data = n;
p-> link = p;
}
else{
temp = p;
while (temp-> link != p)
temp = temp-> link;
temp-> link = new node;
if(temp -> link == NULL){
printf("Error\n");
exit(0);
}
temp = temp-> link;
temp-> data = n;
temp-> link = p;
}
return (p);
Data Structures
INSERTING A NODE BY USING
RECURSIVE PROGRAMS
INSERTING A NODE BY USING
RECURSIVE PROGRAMS

Common questions

Powered by AI

Functions in programming provide key advantages, including improving modularity and task management. Modularity allows a program to be broken down into smaller, manageable tasks, making the code easier to understand, maintain, and debug. It also enables code reuse across different parts of an application or even in different programs. Moreover, functions help avoid duplication by encapsulating repetitive operations into callable subroutines, thereby reducing errors and improving code efficiency .

In C, arrays and pointers are intimately related. An array name represents the address of the first element, and a pointer to an array element can be used to traverse and manipulate elements of the array. You can access array elements by using a pointer and incrementing it to navigate through the elements. This is because the array elements are stored in contiguous memory locations. Using integer pointers, a programmer can iterate over an array and modify its elements without directly using array indexing .

Linked lists use several primary operations: insertion, deletion, and traversal. Insertion adds a new node to the list, which can be done at the beginning, end, or between nodes, facilitating dynamic growth at runtime without a predefined size. Deletion removes a node, freeing memory for other data, which is important for maintaining efficiency. Traversal involves moving sequentially through the list from one node to another, allowing access to data. These operations make linked lists highly flexible and efficient for lists that need frequent updating, unlike static arrays .

Tail recursion optimizes recursive functions by allowing certain compilers or interpreters to optimize away the stack frame of the current function call. This optimization is possible because the recursive call is the last operation in the function, meaning no further computation follows after returning from the recursive call. This can reduce stack overhead and prevent stack overflow in deep recursions. Unlike other recursion types, such as non-tail linear or binary recursion, tail recursion can often be transformed into an iterative loop by using accumulation to carry forward computation results, further enhancing performance and efficiency .

The stack plays a crucial role in function calls by managing execution control and variable references. When a function is called, the current execution context, including the address of the next instruction, is pushed onto the stack. This ensures that once a function completes its execution, control can return to the correct location in the calling function. Additionally, the stack maintains local variables and function parameters, handling different variable scopes by prioritizing local definitions over global ones due to its Last In, First Out (LIFO) structure. This mechanism allows programs to resolve variable references accurately throughout nested or recursive function calls .

The complexity of algorithms is crucial for evaluating their efficiency, particularly concerning time and space resources. Measuring complexity helps determine how an algorithm scales with input size, which is vital for predicting performance in real-world applications. In computer science, complexity is typically measured using Big O notation, which provides an upper bound on the time or space requirements in terms of the size of the input. These notations help in analyzing and comparing different algorithms or choosing the most suitable one for particular problems, based on expected performance for large input sizes .

Selection sort is characterized by its simplicity and method of operation, which involves repeatedly finding the minimum element from the unsorted portion and swapping it with the first unsorted element. Unlike other algorithms, it performs well on small lists and requires minimal swaps. However, it is comparatively inefficient on larger lists due to its theoretical time complexity of O(n^2), where n is the number of elements. This quadratic complexity arises from the two nested loops required to select the minimum element and perform the swapping for each pass .

Pointers in C provide a way to access variable values indirectly by storing the address of the variable rather than the value itself. In C, a pointer is defined by placing an asterisk (*) before the name of the variable, indicating that it is a pointer to a certain data type. To access or manipulate the value of the variable the pointer points to, the asterisk (*) is used as the dereference operator. The address of a variable can be obtained using the address-of operator (&). This allows for powerful operations like dynamic memory allocation and efficient array manipulation .

Recursion is a programming technique where a function calls itself either directly or indirectly to solve a problem. The document outlines several types of recursion: Linear recursion involves a single recursive call at each step. Tail recursion is a form of linear recursion where the recursive call is the final operation in the function. Binary recursion involves a function making two (or more) calls to itself. Exponential recursion, characterized by an exponential number of calls with respect to the data set size, can lead to rapid growth of function calls. Nested recursion involves a function using itself as an argument. Mutual recursion involves sets of functions calling each other in a cyclic manner .

Binary search improves upon linear search by significantly reducing the number of comparisons needed to find an element in a list. While linear search has a time complexity of O(n), binary search reduces this to O(log2n) by repeatedly dividing the array into halves and effectively ruling out one half of the elements in each step. However, for binary search to be applicable, the list must be sorted. It requires that the middle element of a list is compared to the target element, and based on the result, the search continues in the left or right sublist until the element is found or the sublist is empty .

You might also like