You are on page 1of 12

CS 101 DATA STRUCTURES AND ALGORITHMS CONCEPTS REVIEWER

Complexity Analysis
Recursion

Sorting Algorithms
Abstract Data Type

Complexity Analysis

ALGORITHM

the step by step procedure on how to solve a


problem.
may be described using a pseudocode, can
be a combination of natural language or
familiar programming language structures

PROPERTIES OF AN ALGORITHM
It must be correct.
-

It must be composed of a series of concrete steps.

There has to be no ambiguity.

It must be composed of a finite number of steps.

It must terminate.

EFFICIENCY OF AN ALGORITHM:
Space
o the amount of memory used
o directly calculated based on the declaration
of variables (sizeof or bytes used)
Speed
o the approximated time needed for a
program to finish its execution
o depends on the CPU, Memory, Input size,
software, algorithm
o algorithms running time (programs
running time)
Ease in implementation (algorithms basic
operation count)
CASES: Hold the size of the program fixed
Best case: input that requires the fewest basic
operations to obtain results

Worst case: input that requires the most basic


operations to obtain result
Average case: expected number of steps for
an arbitrary input

NOTES TO PONDER ON:


The running time of an algorithm is usually a
function of the input size.
It will always depend on the size of the input.

Fastest running time = Most Efficient

ALGORITHM ANALYSIS
Frequency Count
this refers to the no. of times a statement or
group of statements are executed within the
entire duration of the program.
Running Time Big O Notation
one method of describing the running time of
an alogrithm.
The notation that describes the lower bound
is called the Omega Notation
The Big-Oh describes the upper bound for
the running time of an algorithm
provides a way to simplify analysis by getting
rid of irrelevant information
RULES IN DETERMINING:
1. An I/O statement, assignment start will take
one unit of time O(1)
2. In a conditional statement, the running time is
equal to the maximum running time between
executing the statements when the condition
is satisfied and when it is not. depends

Pointers and Addresses


ADT Letter String and ADT Linked Lists
3.

In a loop, the running time is computed


based on the product of
a. the running times of the statements in the
body of the loop; - O(n)
b. the no. of times the body of the loop will
be executed. iterations, see next rule
4. declaration takes no time - O(0)
5. operations, one unit each O(1)
6. Sequence of statements find maximum
2
2
Max(O(1), O(n), O(n ), O(log n)) = On
RULES IN ITERATIONS:
Let the iteration variable be i. if the iteration is:
a. i++, then retain the running time
b. i--, then retain the running time
c. i+=num or i-=num, then divide the
running time to the number of constant
Example: i+=2 O(?/2)
Example: i-=3 O(?/3)
d. i*=num or i/=num, then set the running
time to a logarithmic constant
Example: i*=10 O(log * ?)
Example: i/=3 O(log * ?)
ALGORITHMS - COMMON CLASSIFICATIONS
Typical functions that classify algorithms
constant
O (1)
logarithmic
O (log n)
linear
O (n)
quadratic
O (n2)
exponential
O (an), n > 1

Reviewer Compiled by Donald

Recursion
-

a programming technique in which functions


call themselves (kasi may sayad)
process of solving a problem by reducing it to
smaller versions of itself.

ADVANTAGES/VALUES OF RECURSION:
Recursion can be used to replace loops.
Recursively defined data structures, like lists,
are very well-suited to processing by recursive
procedures and functions.
A recursive procedure is mathematically more
elegant than one using loops.
Sometimes procedures that would be tricky to
write using a loop are straightforward using
recursion.
On the book:
TYPES OF RECURSIVE CALL:
Directly Recursive a function that calls itself
Indirectly Recursive a function that calls
another function and eventually results in the
original function call
Tail recursive function recursive function in
which the last statement executed is the
recursive call
Infinite recursion the case where every
recursive call results in another recursive call.
STEPS IN DESIGNING A RECURSIVE FUNCTION:
1. Understanding problem requirements
2. Determine limiting condition
3. Identify base cases
4. Provide direct solution to each base case
5. Identify general case(s)
6. Provide solution to general cases in terms of
smaller versions of itself (recursion)

On the discussion of the other classes:


TYPES OF RECURSIVE CALL:
Linear Recursion
o Recursion with base cases and recursive
calls the traditional
Tail Recursion
o First in, First Out.
o Tail recursion occurs when a linearly
recursive method makes its recursive call as
its last step.
o Such methods can be easily converted to
non-recursive methods (which saves on
some resources).
Non-tail Recursion
First in, Last Out. (Stack-like)
Alam mo na yan.
o

CONTENT OF A RECURSIVE METHOD


Base case(s).
Values of the input variables for which we
perform no recursive calls are called base
cases (there should be at least one base case).
Every possible chain of recursive calls must
eventually reach a base case.
The so-called stopping condition
The value of the function is specified for one
or more values of the parameter (?)
Recursive calls.
Calls to the current method.
Each recursive call should be defined so that it
makes progress towards a base case.
Nandito ang recursive function/method with
edited parameters.
The functions value for the current value of
the parameter(s) defined in terms of
previously defined function values and/or
parameter values. (?)

Sorting Algorithms
Sorting is the process of arranging data in a certain
order, either in ascending or descending.
THINGS TO MEASURE IN SORT ALGO:
Passes / Runs
Number of Comparisons done
-

The measure of these things usually approximate


fairly, accurately the running time of the algorithm
(and if one of which has changed, it greatly affects
the running time)

SORTING TECHNIQUES
BIN/BUCKET SORT
requires the amount of nos. to be w/in a
predetermined range
RADIX SORT
arranges by the place values of the elements,
arranging from the smallest to largest and
vice versa (by a revised bucket system).
BUBBLE SORT
the most common in terms of implementation
Procedure:
test only two numbers at a time , starting with
the first two numbers
if the top is smaller, leave as is. If top is larger,
switch the 2 nos. go down one no. and
compare that no. with the no. that follows it.
Continue this process until no switch has been
made in an entire pass through the list.
SELECTION SORT
Locates / selects the smallest / largest
element first, then. place that element in its
most appropriate position
INSERTION SORT
inserts the elements in its proper position
in the array

Reviewer Compiled by Donald

SHELL SORT
Named after Donald Shell
Also known as the diminishing increment sort
MERGE SORT
can work with nos. of unlimited duplication
and unspecified size
determine the middle of the initial array
each sub-array is split into two until each subarrays have two and one elements each.
A single comparison is performed on the twoelement array
Merge by comparing elements in each array,
one at a time.
QUICK SORT
most efficient
choose a partitioning element called the pivot
one part contains elements that are less than
or equal to the pivot, the other part contains
elements that are greater than the pivot
new pivots are chosen until arrays contain
only 1 or 2 elements perform necessary
comparisons
TIME COMPLEXITY OF SORTING ALGOS:
BUCKET
RADIX
BUBBLE
SELECTION
INSERTION
SHELL
MERGE
QUICK

WORST
2
O(n )
O(n)
2
O(n )
2
O(n )
2
O(n )
2
O(n )
O(nlog2n)
2
O(n )

AVE
O(n)
O(n)
2
O(n )
2
O(n )
2
O(n )
2
O(n )
O(nlog2n)
O(nlog2n)

**Just take note of the Average Cases.

BEST
O(n)
O(n)
O(n)
2
O(n )
O(n)
O(n)
O(nlog2n)
O(nlog2n)

Abstract Data Types


TERMS
Type a collection of values
Data Type a type together with a collection
of operations to manipulate the type
Abstract Data Type (ADT) defines a data
type solely in terms of a type and a set of
operations on that type
Data Structure the physical implementation
of the ADT; a particular organization of data
implementing on ADT
Abstract considered apart from the detailed
specifications or implementation
ADT consists of a collection of data items
(variables of the class / struct) and basic
operations on the data items that must be
performed on them (functions, constructor)
With his, we are considering WHAT can be
done with the data rather than how it is done
DATA STRUCTURES AND OOP PRINCIPLES
Data Structures are Objects
Abstraction: ability to distill a software system
into its most basic parts
Encapsulation: implementing the abstraction
without revealing how is implemented
Abstractions and Encapsulation applies to
Data Structures.
Inheritance and Polymorphism
o Data Structures are often containers and
share similar operations
DEFINING AN ADT
1. Specifications
structure; operations/functions; definition of
the ADT
2. Representation (variable/constant declaration)
Choosing the appropriate data structure fitted
for the given specs used in no. 1.

3.

Implementation

Choosing the appropriate


commands/programming statements given a
chosen programming language to implement
the necessary operations of each of the defined
functions.

Pointers
STATIC AND DYNAMIC ALLOCATION
Static Allocation
o Binds memory space to variables at
compile time (stack)
o Static variables

The values may change but the locations


may not be created nor destroyed

Dynamic Allocation
Binds memory space to variable during
runtime (heap)
o Dynamic Variables
o

Created and disposed during execution

POINTER
a variable that is the address of another
variable. They are used to access dynamic
variables
Two operators are used to work with pointers:
the ampersand (&) means the address of
and the asterisk (*) the indirection operator
means contents of address.
A pointer is declared using the data type of
the variable it points to plus an asterisk (*)
before its name.
BASIC POINTER OPERATIONS
Dereferencing and Indirection
Assignment: Pointer variables can be assigned
the values of other pointer variables that are
bound to the same type.
Comparison: We can compare pointer
variables that are bound to the same type
using relational operators like == and !=.
Reviewer Compiled by Donald

JAVA AND POINTERS


Java does not use explicit pointers and does
not allow the programmer to use them,
object access is implemented in terms of
pointers
An object occupies some memory space
starting from a certain memory location
A pointer to this object is a variable that holds
the address of this object, and this address is
the starting position of the object in memory
The term reference is used instead
NOTES TO PONDER ON:
-

Pass pointers to that value to any function which


wants to see or change the value
Functions can dereference their pointer to see or
change the value of interest
No value is passed to the function; instead the
function workds directly with the calling programs
actual parameters through the pointer variables
Within the function, changes made to the formal
parameter (prefixed with *) immediately affect the
calling programs actual parameter.
Usually supplies answers to the calling program or
updates a variable of the calling program

ADT LETTER STRING


SPECIFICATIONS:
Definition: A letter string is a sequence of n
characters. The length is referred to as length.
Operations:
1. Append- to add a character at the tail of the
sequence.
2. Remove- to delete a character at any position
in the given sequence.
3. Print- display the elements of the letter string.
4. Makenull- make the letter string empty.
5. Empty- returns true if the letter string is empty
otherwise it returns false.

6.

Full- returns true if the letter string is full


otherwise it returns false.

REPRESENTATION:
int n=100;
class LS
{
char letter_string [n];
int length;
void append(char c);
void remove(int n);
void print(int i);
void makenull()
int empty();
int full(); };
1. APPEND
Pre: LS is not full
Post: a new char is added at the tail end of the LS
& likewise the gap is closed
2. REMOVE
Pre: not empty
Post: one character should have been removed
from the LS
3. PRINT
Pre: LS is not empty/none
Post: LS is printed
4. MAKENULL
Pre: 0 length ls. Length/none
Post: All elements were deleted
5. EMPTY
Pre: 0length ls /none
Post: returned TRUE if LS is empty, otherwise
returned false
6. FULL
Pre: LS must be full/none
Post: returned true if LS is full, otherwise returned
false

IMPLEMENTATION:
void LS :: append (char c){
if (LS.length != n-1){
LS.length = LS.length + 1;
LS.letter_string[LS.length]= c;

}
else if (LS.length == n-1)
cout<<the letterstring is full;

}
void LS :: print (int i) {
if (LS.length<= -1)
cout<<empty;

else
for( i=0; i<=LS.length; i++)
cout<<LS.letter_string[i];

void LS :: remove (int n){


if (LS.length<0)
cout<<string is empty;

else if (LS.length<n)
cout<<position is beyond the length;

else{
for (int i=n;i<LS.length; i++)
LS.letter_string[i] = LS.letter_string [i+1];
LS.length = LS.length-1;}

}
void LS::makenull (){
if (LS.length> -1)
LS.length= -1;

else
cout<<theres no character in LS;

}
int LS ::empty (){
if (LS.length<0)
else

return 1;
return 0; }

int LS:: full (){


if (LS.length>99)
else

return 1;
return 0;}

Reviewer Compiled by Donald

ADT LINKED LIST


STATIC VS DYNAMIC DATA STRUCTURE
Static Data Structure (arrays)
Fast access to elements
Costly to remove insert elements
Have a fixed, maximum size of elements
Dynamic data structure (pointer list)
Fast insertion / deletion of elements
Slower access to elements
Have flexible size

Definition: A list is a sequence of dynamic variables


or nodes that are linked together.
Note: The linked list terminates with a node whose
link field value is NULL.
NULL is a predefined constant pointer which
means point to nothing.
Operations:
1. Add insert an item into the list
2. Delete remove an item into the list
3. Print prints the list
4. Makenull emptied the list
5. Empty check if the list is empty
SINGLY LINKED LIST
Linked list is a set of items organized
segmentially, just like any array, the
segmented organization is provided implicitly
in the link list, we use an explicit arrangement
in which items is a part of the node that also
contains a link to the next node.
IMPLEMENTATION:
struct node
{ int data;
struct node *link;};
typedef struct node list;

void addtail(list *head, int num){


list newnode, ptr;
ptr=*head;
newnode =(list)malloc(sizeof(struct node));
while(ptr->link!=NULL)
ptr=ptr->link;
ptr->link=newnode;
newnode->value=num;
newnode->link=NULL;

void deltail(list *head){


list ptr,ptr2;
ptr=*head;
if (*head!=NULL){
while (ptr->link!=NULL)
ptr2=ptr; ptr=ptr->link;
free(ptr);
ptr2->link = NULL;
}

else

void addhead(list *head, int num)


{

void display(list *head)


{list ptr=NULL;
if (*head!=NULL){

list newnode;
newnode = (list)malloc(sizeof(struct node));
newnode->value = num;
newnode->link = *head;
*head = newnode;

}
void delhead(list *head){
list ptr;
if(*head!=NULL){
ptr=*head;
*head=ptr->link;
free(ptr);

}
else
cout<<"Nothing to delete!!!";

cout<<"Nothing to delete!!!";}

for (ptr=*head; ptr->link!=NULL; ptr=ptr->link)


{cout<< ptr->value <<" ";}

cout<<ptr->value;
}
void makenull(list *head)
{ *head = NULL; }
int empty (list *head)
{ if (*head !=NULL)
return 0;
else
return 1;
}
DOUBLY LINKED LIST
Each node has 2 reference field, one to the
successor and the one to the predecessor.
CIRCULAR LINKED LIST
Lists where nodes form a ring

Reviewer Compiled by Donald

CS 101 DATA STRUCTURES AND ALGORITHMS IMPLEMENTATION REVIEWER


FREQUENCY COUNT
Example:
Find the Frequency Count of printf()
a.
int main(){
printf(Hello World!);
} // Count: 1
b.
int main(){
if(something()){
printf(Hello World!);
}
else {
print(Goodbye!);
} //Count: 1 (max)
c.
int main(){
for(int i = 0; i < p.Last; i++)
printf(Hello World!);
} //Count: p.Last
d.
int main(){
for(int i = 0; i <= p.Last; i++)
printf(Hello World!);
} //Count: p.Last + 1
e.
int main(){
for(int i = 1; i < p.Last; i++)
printf(Hello World!);
} //Count: p.Last 1
f.
int main(){
for(int i = 1; i <= p.Last; i++)
printf(Hello World!);
} //Count: p.Last

g.
int main(){
for(int i = n; i < p.Last; i++)
printf(Hello World!);
} //Count: p.Last - n
h.
int main(){
for(int i = n; i <= p.Last; i++)
printf(Hello World!);
} //Count: p.Last - n + 1

for(int i = 0; i < n*n; i+=2){


for(int j = 0; j < n; j++)
cout << yeah;
for(int y = 0; y < n*n*n; i+=4)
cout << no;
5
} // O(n /8)
while(x < n){
cout << sparks;
x /= 2;
}//O(log n)

i.
int main(){
for(int i = 1; i <= p.Last-n; i++)
for(int k = 2; k < p.Last-1; k++)
printf(Hello po);
} //Count: (p.Last n 1)(p.Last 3)

int func(int x){


if(x == 1)
return 1;
else
return x * funct(x-1);
} //O(n)

BIG-OH NOTATION
for(int i = 0; i <= n; i++)
cout << sigaw;
//O(n)

int cabin (int x){


if(x == 0)
return x;
else
return x + cabin(x/2);
} //O(log n)

for(int i = n; i < 1; i--)


cout << yehey;
//O(n)
for(int i = 0; i < n; i++)
for(int j = 0; j < n-1; j++)
cout << awoo;
2
//O(n )

int y = 4; //O(1)
int x;

//O(0)

X = X + 1 //O(1)

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


cout << batingaw;
2
// O(n )
Reviewer Compiled by Donald

RECURSION SIMULATION
A. Linear
int rose(int x){
if(x == 0)
return x;
else
return x%10 + rose(x/10);
}
let x be 12345
1
rose(12345)
2
rose(1234)
3
rose(123)
4
rose(12)
5
rose(1)
6
rose(0)

= 5 + rose(1234)
= 4 + rose(123)
= 3 + rose(12)
= 2 + rose(1)
= 1 +rose(0)
=0

Then,
Since rose(0) = 0,
substitute to the equation of rose(1)
5
rose(1)
= 1 + rose(0) //substitute
1+0
5
rose(1) = 1
Then,
4
rose(12)
4

rose(12)

Then,
3
rose(123)
3

rose(123)

Then,
2
rose(1234)
2

rose(1234)

2 + rose(1) //substitute
2+1
3

Then,
1
rose(12345)
1

int rose(12345) returns 15


final answer: 15
int rose(int x, int y)
{
if(y == 1)
return x;
else
return x * rose(x, y-1);
}
Let x be 4 and y be 5
1
rose(4, 5)
= 4 * rose(4, 4)
2
rose(4, 4)
= 4 * rose(4, 3)
3
rose(4, 3)
= 4 * rose(4, 2)
4
rose(4, 2)
= 4 * rose(4, 1)
5
rose(4, 1)
=4
4
rose(4, 2)
= 16
3
rose(4, 3)
= 64
2
rose(4, 4)
= 256
1
rose(4, 5)
= 1024
B.

=
=

3 + rose(12) //substitute
3+3
6

= 4 + rose(123) //substitute
4+6
= 10

rose(12345)

Let i be 5
= 5 + rose(1234) //substitute
5 + 10
= 15

Tail

void frog(int i){


if(i > 0){
cout << i;
tail(i 1);
}
}

Output
frog(5) 5
frog(4) 4
frog(3) 3
frog(2) 2
frog(1) 1
frog(0) //none
Output: 54321
C.

frog(4)
frog(3)
frog(2)
frog(1)
frog(0)
Because 0 > 0 is false

Nontail

void frog(int i){


if(i > 0){
tail(i 1);
cout << i;
}
else
cout << endl;
}

frog(5)
frog(4)
frog(3)
frog(2)
frog(1)
frog(0)

Stack
5
4
3
2
1
----------

Stack
frog(5)
5
frog(4)
4
frog(3)
3
frog(2)
2
frog(1)
1
frog(0) ---------Output: 12345

Output
frog(4)
frog(3)
frog(2)
frog(1)
frog(0)
----------

endl
Output
5
4
3
2
1
endl

frog(4)
frog(3)
frog(2)
frog(1)
frog(0)
----------

Reviewer Compiled by Donald

SORTING SIMULATION
BUBBLE SORT (ASCENDING)
1ST PASS:

.
3RD PASS:

TOTAL COMPARISON: 3 + 3 + 3 + 3 = 12

COMPARISON: 3

COMPARISON: 3

2ND PASS:

4TH PASS:

COMPARISON: 3

PASSES

: 4=n

COMPARISON: 3
Reviewer Compiled by Donald

SELECTION SORT (ASCENDING)


1ST PASS

MIN

MIN = 8

MIN

4
4

MIN

MIN

1 < 3 THEN, MIN = 1

COMPARISONS: 2

COMPARISONS: 3

MIN

NO SWAP!, NUMBER IS IN PLACE

MIN

SWAP!

MIN

MIN

COMPARISONS: 1

SWAP!

MIN

MIN

MIN

8 < 4 IS NOT TRUE, MIN IS STILL 4

8 < 3 IS NOT TRUE, MIN IS STILL 3

3RD PASS:

MIN = 4

3 < 4 THEN, MIN = 3

3 < 4 THEN, MIN = 3

MIN

MIN = 4

4 < 8 THEN, MIN = 4

2ND PASS

MIN

4TH PASS:

MIN = 8
NO SWAP! NUMBER IS IN PLACE.

MIN

MIN

MIN

COMPARISON: 0
.

COMPARISON: 3 + 2 + 1 + 0 = 6
PASSES:
4=n

Reviewer Compiled by Donald

INSERTION SORT (ASCENDING)


3RD PASS

1ST PASS

COMPARISON = 0

2ND PASS

4TH PASS

COMPARISON = 1
4 > 5 IS FALSE, THEREFORE, THERES NO SWAP
NO SWAP = NO COMPARISON (FOR INSERTION)

COMPARISON = 3
TOTAL COMP: 0 + 1 + 1 + 3 = 5
PASSES = 4 = n

COMPARISON = 1

Reviewer Compiled by Donald

10

MERGE SORT (ASCENDING)

QUICK SORT (ASCENDING)

LET THE PIVOT BE THE FIRST ELEMENT OF THE SEGMENTS

4 3

7 9

8 1

8 1

PIVOT = PARENT; THE REST = CHILD


ALL LEFT CHILDS ARE SMALLER THAN THE PIVOT
ALL RIGHT CHILDS ARE BIGGER THAN THE PIVOT

COMPARISON CHECK!

4 3

7 9

COMPARISON = 2

3 4

COMPARISON CHECK!

7 9

3 4 7 9

1 8

1 8

1 3 4 7 9 8
1 2 3 4 7 9 8

2
2

COMPARISION = 1

3
3

4
4

//TALASAN ANG MATA!


//BAKA MAY MAISIP KANG FORMULA!

Reviewer Compiled by Donald

11

POINTERS SIMULATION

Line 2: x = &a; y = &b; z = c;

void N(int *x, int *y, int z)


{
int t;
z += *x;
*x = *y + z;
t = z; z = *y; *y = *x;
*x = t;
}
main(){
int a=1, b=2, c=3;
N(&a, &b, c);
cout << Line 1: <<a << b<<c<<endl;
N(&a, &b, c);
cout << Line 2: <<a<<b<<c<<endl;
N(&c, &b, a);
cout<< Line 3: << a << b << c << endl;
}
NOTE: GRAYED OUT ARE NEWLY EDITED FIELDS
Line 1: x = &a; y = &b; z = c;

passed value

z += *x;

*x = *y + z;

13

t=z

13

z = *y

13

*y = *x

13

13

*x = t

13

NEW VALUE:
a = 7; b = 13; c = 3
Line 3: x = &c; y = &b; z = a;
X

passed value

13

z += *x;

13

10

*x = *y + z;

23

13

10

t=z

23

13

10

10

z = *y

23

13

13

10

passed value

*y = *x

23

23

13

10

z += *x;

*x = t

10

23

13

10

*x = *y + z;

t=z

z = *y

*y = *x

*x = t

NEW VALUE:
a = 4; b = 6; c = 3

NEW VALUE:
a = 7; b = 23; c = 10
Output:
VALUE OF VV: 20
Line 1: 4 6 3
Line 2: 7 13 3
Line 3: 7 23 10
EXERCISE: Determine the output
void CC(int *a, int b)

int t;
t = *a;
*a = *a + b / 2;
b = ++(*a);
*a = t + 1;
}
int VV(int *x, int z, int *y)
{
*x += *y;
(*x)++;
*y = z;
return (*x + *y + z);
}
main(){
int a = 4, b = 5, c = 6;
cout << VALUE OF VV: <<VV(&b, a, &c);
cout << endl;
cout << Line 1: << a << << b << << c;
CC(&a, c);
cout << endl;
cout << Line 2: << a << << b << << c;
CC(&a, VV(&b, a, &c)); //note: evaluate VV first
cout << endl;
cout << Line 3: << a << << b << << c;
}
Output:
VALUE OF VV: 20
Line 1: 4 12 4
Line 2: 5 12 4
Line 3: 6 17 5

//Reference: Data Structures and Algorithms


//
Maam Cha and Sir Verg
Reviewer Compiled by Donald

12