Estructuras de Datos

Download as pdf or txt
Download as pdf or txt
You are on page 1of 107

ESTRUCTURAS

DE DATOS
Yoan Pinzón

by Dilan A. Correa

© 2020
Estructuras de Datos

The C Language

© 2020

In This Session

● The C Language
⊳ The Origins of C
⊳ Program Structure
⊳ Data Types
⊳ Operators
⊳ Control Structures
⊳ Iteration Statements
⊳ Break and Continue
⊳ Arrays
⊳ Pointers
⊳ Functions
⊳ Argument Passing Methods
⊳ Dynamic Memory Allocation
⊳ Structures
⊳ Files

yoan Estru turas de Datos 1


The Origins of C

C was originally developed by Dennis Ritchie between 1969 and 1973 at


Bell Labs, and used to re-implement the Unix operating system. It is one
of the most widely used programming languages of all time.

ANSI C: The American National Standards Institution (ANSI) provides


“official” and generally accepted standard definitions of many program-
ming languages, including C. Such standards are important. A program
written only in ANSI C is guaranteed to run on any computer whose
supporting software conforms to the ANSI standard. In other words, the
standard guarantees that ANSI C programs are portable.

yoan Estru turas de Datos 2

Program Structure

#include <stdio.h>
// other preprocessor directives

function-definition 1; function-definition 2; . . .

int main(){
declaration 1;
declaration 2;
. . .

execution-statement 1;
execution-statement 2;
. . .

return 0;
}

yoan Estru turas de Datos 3


1. Comments: In C the comments (/* .... */) are used to comment
multiple lines.

2. The header file: The header file included in the basic C program
is stdio.h which would be used in a basic C program. The file stdio.h
provides the fundamental input and output definitions and functions for
C. We will be using other header files later on.

3. The main() funtion: This marks the start of the main part of
the program. All programs will contain one and only one definition of a
function called main.

4. The braces: The opening brace ({) and the closing brace (}) mark
the beginning and the end of the program body. Any code enclosed by
the two braces is referred to as a block. Any variable, or function, defined
in a block only has scope (i.e. is only available) within that block.

yoan Estru turas de Datos 4

5. Identifiers: C programs can be written using many English words


which are not reserved words as:

auto double int struct


break else long switch
case enum register typedef
char extern return union
const float short unsigned
continue for signed void
default goto sizeof volatile
do if static while

yoan Estru turas de Datos 5


Here is an example of a complete C program:

/*
This program prompts the user for two integers.
It then calculates the sum
*/

#include <stdio.h>

int main( ){
int x, y;

printf( "Enter two numbers\n" );


scanf( "%d%d", &x, &y );

printf( "The sum of %d and %d is %d\n", x, y, x+y );

return 0;
}

yoan Estru turas de Datos 6

Data Types

There are just three fundamental data types in C: int, char and float.
These basic data types together with a small number of modifiers (e.g.
short, long, unsigned) are used to build more complex data types.

Integral data types

Data type∗ Bytes Values


[signed] char 1 [-128, 127]
unsigned char 1 [0, 255]
short int 2 [-32768, 32767]
unsigned short 2 [0, 65535]
int 4 [−231, 231-1]
unsigned int 4 [0, 4294967295]
long 4 [-231, 231-1]
unsigned long 4 [0, 4294967295]
long long int 8 [-263, 263-1]
unsigned long long int 8 [0, 264-1]
∗ These values depend on the particular system and are described in the header file limits.h

yoan Estru turas de Datos 7


Real numeric types

Data type∗ Bytes Values


float 4 1.17549435×10−38
3.40282347×1038
double 8 2.2250738585072014×10−308
1.79769313448623157×10308
long double 16 ≈ 10−4931
≈ 104932
∗ These values depend on the particular system and are described in the header file float.h

yoan Estru turas de Datos 8

Strings

string is not a fundamental data type such as int, float or char. Instead,
strings are represented as arrays of characters, so we will return to subject
of strings later, when we discuss arrays in general.

yoan Estru turas de Datos 9


Operators

Arithmetic Operators
Operator Function Use Association
( ) parentheses (expr list) L-to-R
* multiply expr1 * expr2 L-to-R
/ divide expr1 / expr2 L-to-R
% modulo expr1 % expr2 L-to-R
+ plus expr1 + expr2 L-to-R
- minus expr1 - expr2 L-to-R

Example:
int main(){
int i=4, j=7, k=5, val1, val2;

val1 = i * j / 2 + k % 2 -3 ;
val2 = (i * j / ( 2 + k )) % 2 - 3;
printf( "val1=%d\n", val1 ); // outputs 12
printf( "val1=%d\n", val2 ); // outputs -3

return 0;
}

yoan Estru turas de Datos 10

Equality, Relational and Logical Operators

Operator Function Use Association


! logical NOT !expr R-to-L
< less than expr1 < expr2 L-to-R
<= less than or equal expr1 <= expr2 L-to-R
> greater than expr1 > expr2 L-to-R
>= greater than or equal expr1 >= expr2 L-to-R
== equal expr1 == expr2 L-to-R
!= not equal expr1 != expr2 L-to-R
&& logic AND expr1 && expr2 L-to-R
|| logic OR expr1 || expr2 L-to-R

Examples:
Expression true/false
(6 <= 6) && (5 < 3) false
(6 <= 6) || (5 < 3) true
(5 != 6) true
(5 < 3) && (6 <= 6) || (5 != 6) true
(5 < 3) && ((6 <= 6) || (5 != 6)) false
!((5 < 3) && ((6 <= 6) || (5 != 6))) true

yoan Estru turas de Datos 11


Bitwise Operators
Operator Function Use Association
∼ bitwise NOT ∼expr R-to-L
<< shift left expr1 << expr2 L-to-R
>> shift right expr1 >> expr2 L-to-R
& bitwise AND expr1 & expr2 L-to-R
ˆ bitwise XOR expr1 ˆ expr2 L-to-R
| bitwise OR expr1 | expr2 L-to-R

Example:
// Assumes int are 4 bits
unsigned int a = 11; // 1011
unsigned int b = ~a; // 0100
unsigned int c = a << 1; // 0110
unsigned int d = a >> 2; // 0010
unsigned int e = a & c; // 0010
unsigned int f = a ^ c; // 1101
unsigned int g = a | c; // 1111

yoan Estru turas de Datos 12

Assignment Operators
Operator Function Use Association
= conventional assignment lvalue = expr R-to-L
*= multiply and assign lvalue *= expr R-to-L
/= divide and assign lvalue /= expr R-to-L
%= modulo and assign lvalue %= expr R-to-L
+= add and assign lvalue += expr R-to-L
-= subtract and assign lvalue -= expr R-to-L
<<= shift left and assign lvalue <<= expr R-to-L
>>= shift right and assign lvalue >>= expr R-to-L
&= AND and assign lvalue &= expr R-to-L
|= OR and assign lvalue |= expr R-to-L
ˆ= XOR and assign lvalue ˆ= expr R-to-L

generally a op= b is equivalent to a = a op b.

Examples:
Expression Equivalent to
number += 1; number = number + 1;
total -= discount; total = total - discount;
bonus *= 2; bonus = bonus * 2;
time /= rush factor; time = time / rush factor;
change %= 100; change = change % 100;
amount *= count1 + count2; amount = amount * (count1 + count2);

yoan Estru turas de Datos 13


Unary Operators
Operator Function Use Association
++ post increment lvalue++ L-to-R
-- post decrement lvalue-- L-to-R
sizeof size of object sizeof(expr) R-to-L
sizeof size of type sizeof(type) R-to-L
++ pre increment ++lvalue R-to-L
-- pre decrement --lvalue R-to-L
+ unary plus +lvalue R-to-L
- unary minus -lvalue R-to-L

Example:
int main(){
int x=5;

printf( "%d\n", x ); // outputs 5


printf( "%d\n", x++ ); // outputs 5
printf( "%d\n", x ); // outputs 6
x=5;
printf( "%d\n", x ); // outputs 5
printf( "%d\n", ++x ); // outputs 6
printf( "%d\n", x ); // outputs 6

return 0;
}

yoan Estru turas de Datos 14

Operators
– in decreasing precedence order –

Oper. Function Use Association


( ) parentheses (expr list) L-to-R
++ post increment lvalue++ L-to-R
-- post decrement lvalue-- L-to-R
sizeof size of object sizeof(expr) R-to-L
sizeof size of type sizeof(type) R-to-L
++ pre increment ++lvalue R-to-L
-- pre decrement --lvalue R-to-L
∼ bitwise NOT ∼expr R-to-L
! logical NOT !expr R-to-L
- unary minus -lvalue R-to-L
+ unary plus +lvalue R-to-L
& address of &expr R-to-L
* dereference *expr R-to-L
* multiply expr1 * expr2 L-to-R
/ divide expr1 / expr2 L-to-R
% modulo expr1 % expr2 L-to-R
+ plus expr1 + expr2 L-to-R
- minus expr1 - expr2 L-to-R
<< shift left expr1 << expr2 L-to-R
>> shift right expr1 >> expr2 L-to-R
< less than expr1 < expr2 L-to-R
<= less than or equal expr1 <= expr2 L-to-R
> greater than expr1 > expr2 L-to-R
>= greater than or equal expr1 >= expr2 L-to-R

yoan Estru turas de Datos 15


Operators (Cont.)
– in decreasing precedence order –

Oper. Function Use Association


== equal expr1 == expr2 L-to-R
!= not equal expr1 != expr2 L-to-R
& bitwise AND expr1 & expr2 L-to-R
ˆ bitwise XOR expr1 ˆ expr2 L-to-R
| bitwise OR expr1 | expr2 L-to-R
&& logic AND expr1 && expr2 L-to-R
|| logic OR expr1 || expr2 L-to-R
?: alternative if expr1 ? expr2 : expr3 L-to-R
<< stream insertion expr1 << expr2 L-to-R
>> stream extraction expr1 >> expr2 L-to-R
= conventional assignment lvalue = expr R-to-L
*= multiply and assign lvalue *= expr R-to-L
/= divide and assign lvalue /= expr R-to-L
%= modulo and assign lvalue %= expr R-to-L
+= add and assign lvalue += expr R-to-L
-= subtract and assign lvalue -= expr R-to-L
<<= shift left and assign lvalue <<= expr R-to-L
>>= shift right and assign lvalue >>= expr R-to-L
&= AND and assign lvalue &= expr R-to-L
|= OR and assign lvalue |= expr R-to-L
ˆ= XOR and assign lvalue ˆ= expr R-to-L

yoan Estru turas de Datos 16

Type Conversion

There is the need to convert one type to another. This is done using
the syntax:

(type) variable or type(variable)

The following program is a complete example.


int main(){
float a=9.23, b;
int c=3, d;

b=(float)c;
d=(int)a;
printf( "a=%f\n", a);
printf( "b=%f\n", b);
printf( "c=%d\n", c);
printf( "d=%d\n", d);

return 0;
}

yoan Estru turas de Datos 17


Constant Variables

we can specify that a variable’s value cannot be altered during the exe-
cution of a program with the reserved word const.

Example:
const double Pi = 3.14159;

int main(){
double radius, area, circumference;

printf( "Circle radius:" );


scanf( "%lf", &radius );
area = Pi * radius * radius;
circumference = Pi * 2 * radius;
printf( "Area of circle with radius %lf is %lf\n", radius, area );
printf( "Circumference is %lf\n", circumference );

return 0;
}

Generally speaking, it is considered good practice to put constant


declarations before the main program heading, and variable
declarations afterwards, in the body of main.
yoan Estru turas de Datos 18

Control Structures

If and If/Else selection structure

if(Boolean-expression){
i-statement-1;
i-statement-2;
if(Boolean-expression){
. . .
statement-1;
}
statement-2;
else
. . .
{
}
e-statement-1;
e-statement-2;
. . .
}

yoan Estru turas de Datos 19


Example 1. Get a candidate’s grade and reports whether the candidate
has passed the test or not. The pass mark is 50%.

int main(){
int grade;

printf( "Enter the grade: " );


scanf( "%d", &grade );

if( grade >= 50 ){


printf( "Passed\n" );
}
else {
printf( "Failed\n" );
printf( "You must take this course again\n" );
}

return 0;
}

yoan Estru turas de Datos 20

Example 2. Get a candidate’s age and test score, and reports whether
the candidate has passed the test. It uses the following criteria: candi-
dates between 0 and 14 years old have a pass mark of 50%, 15 and 16
year olds have a pass mark of 55%, over 16’s have a pass mark of 60%:
int main(){
int candidate_age, candidate_score;

printf( "Enter the candidate’s age: " );


scanf( "%d", &candidate_age );
printf( "Enter the candidate’s score: " );
scanf( "%d", &candidate_score );

if (candidate_age <= 14 && candidate_score >= 50)


printf( "This candidate passed the test.\n" );
else if (candidate_age <= 16 && candidate_score >= 55)
printf( "This candidate passed the test.\n" );
else if (candidate_score >= 60)
printf( "This candidate passed the test.\n" );
else
printf( "This candidate failed the test.\n" );

return 0;
}

yoan Estru turas de Datos 21


The switch multiple-selection structure

switch(selector){
case label-1: statement-1;
break;
. . .
. . .
. . .

case label-N: statement-N;


break;
default: d-statement;
}

Example. Get a candidate’s test score. If score has value 0, 1, 2, 3 or


4, print “You have fail”, if score has value 5, print “You can do better”,
if score has value 6 or 7, print “You have done quite well”, and finally, if
score has value 8, 9 or 10, print “Well done!!!”.

yoan Estru turas de Datos 22

int main(){
int score;

printf( "Enter the score: " );


scanf( "%d", &score );
switch(score){
case 0:
case 1:
case 2:
case 3:
case 4: printf( "You have fail.\n" ); break;
case 5: printf( "You can do better.\n" ); break;
case 6:
case 7: printf( "You have done quite well.\n" ); break;
case 8:
case 9:
case 10: printf( "Well done!!!.\n" ); break;
default: printf( "Wrong score.\n" );
}

return 0;
}

yoan Estru turas de Datos 23


Iteration Statements
There are three types of iteration statements, which are informally known
as loops:

● The for-loop statement: ● The while-loop statement:


for(init-statement; condition; expression) while(condition)
{ {
loop-statement-1; loop-statement-1;
loop-statement-2; loop-statement-2;
. . . . . .
} }

● The do-while-loop statement:


do
{
loop-statement-1;
loop-statement-2;
. . .
} while(condition);

To see how they work, let us use all three of then for the same purpose,
namely to compute s = Σni=1i (s = 1 + 2 + 3 + . . . + n).

yoan Estru turas de Datos 24

With a for-loop statement: With a for-loop statement:

#include <stdio.h> #include <stdio.h>

int main(){ int main(){


int s = 0, i, n; int s = 0, i, n;

printf( "Enter n: " ); printf( "Enter n: " );


scanf( "%d", &n ); scanf( "%d", &n );
for(i = 1; i <= n; i++) s += i; i = 1;
printf( "suma=%d\n", s ); while( i <= n ){
s += i;
return 0; i++;
} }
printf( "suma=%d\n", s );

return 0;
}

yoan Estru turas de Datos 25


With a do-while-loop statement:
#include <stdio.h>

int main(){
int s = 0, i, n;

printf( "Enter n: " );


scanf( "%d", &n );
i = 1;
do {
s += i;
i++;
} while( i<= n);
printf( "suma=%d\n", s );

return 0;
}

As you see there are not major differences among them. However, the for-loop
statement should be used when we know what the range of the loop is going to be.
Otherwise we should use a while-loop or do-while-loop statement. The do-while-
loop statement is desirable when we need to execute the loop-statement before
checking for the condition.

yoan Estru turas de Datos 26

Break and Continue


● break: causes an immediate exit from a loop.

Example:
#include <stdio.h>

int main(){
double s = 0.0, x;

printf( "Enter numbers, separated by blanks.\n" );


printf( "They are added up as long as they are positive.\n" );
for (;;){ // Example of a forever-loop
scanf( "%lf", &x );
if (x <= 0) break;
s += x;
}
printf( "Sum of the positive numbers that have been read: %lf", s );

return 0;
}

yoan Estru turas de Datos 27


● continue: causes an immediate jump to the test for the continuation
of the loop.

Example:
#include <stdio.h>

int main(){
int i;

for( i = 1; i <= 10; i++){


if( i == 5) continue;
printf( "%d\n", i );
}
printf( "Used continue to skip the printing of value 5\n" );

return 0;
}

yoan Estru turas de Datos 28

Arrays
The use of arrays permits us to manipulate a group of memory locations
as a single entity, but at the same time gives us direct access to any
individual component. Arrays are simple examples of structured data
types.
Declaring an array: The general syntax for an array declaration is: type
array-name[size-d1][size-d2] ...;

Example:
#include <stdio.h>

int main(){
int i, a[10];

for( i = 0; i < 10; i++ ){


printf( "a[%d]= ", i + 1 );
scanf( "%d", &a[ i ] );
}
printf( "The same integers, in reverse order: " );
for( i = 9; i >= 0; i--)
printf( "%d ", a[ i ] );

return 0;
}

yoan Estru turas de Datos 29


Initializing an array:

Examples:
int a[2][3] = { { 1,2,3 }, { 4,5,6 } };
int b[2][3] = { 1,2,3,4,5 };
int c[2][3] = { { 1,2 }, { 4 } };

Values of a by row: 1 2 3
4 5 6

Values of b by row: 1 2 3
4 5 0

Values of c by row: 1 2 0
4 0 0

yoan Estru turas de Datos 30

#include <stdio.h>

int main(){
int i, j;
int a[2][3] = { { 1,2,3 }, { 4,5,6 } };
int b[2][3] = { 1,2,3,4,5 };
int c[2][3] = { { 1,2 }, { 4 } };

printf( "Array a:\n" );


for( i = 0; i < 2; i++ ){
for( j = 0; j < 3; j++ )
printf( "%4d ", a[ i ][ j ] );
printf( "\n" );
}
printf( "Array b:\n" );
for( i = 0; i < 2; i++ ){
for( j = 0; j < 3; j++ )
printf( "%4d ", b[ i ][ j ] );
printf( "\n" );
}
printf( "Array c:\n" );
for( i = 0; i < 2; i++ ){
for( j = 0; j < 3; j++ )
printf( "%4d ", c[ i ][ j ] );
printf( "\n" );
}
return 0;
}

yoan Estru turas de Datos 31


Pointers
Variables that contains a memory address as its value. There are two
important pointer operators namely:

Operator Function Meaning


& address of returns the address of the object
given by the operand
* dereference returns the object that has the address
given by the operand

Example:
#include <stdio.h>

int main(){
int i = 16;
int * pi;

pi = &i;

printf( "%d\n", *pi );

return 0;
}

yoan Estru turas de Datos 32

Functions

User-defined operation to facilitate the reuse of code within programs. a


function basically consists of:
● return type
● function name
● list of parameters
● body

return-type function-name(para1, para2, . . .)


{
. . .

body-of-the-funtion;

. . .
}

yoan Estru turas de Datos 33


Argument Passing Methods
Passing by Value
This is the default method, a copy of the arguments is made and passed
to the corresponding parameters. The values of the arguments do not
change.
Example:
#include <stdio.h>

void swap( int x, int y ){


int temp;

temp = x; x = y; y = temp;

return;
}

int main(){
int a = 4, b = 5;

swap( a, b );
printf( "a=%d\nb=%d\n", a, b );

return 0;
}

yoan Estru turas de Datos 34

Passing by Reference

The parameters receive the address of the arguments rather that a copy
of its value. The values of the arguments do change.

Example:
#include <stdio.h>

void swap( int* x, int* y ){


int temp;

temp = *x; *x = *y; *y = temp;

return;
}

int main(){
int a = 4, b = 5;

swap( &a, &b );


printf( "a=%d\nb=%d\n", a, b );

return 0;
}

yoan Estru turas de Datos 35


Dynamic Memory Allocation
When the allocation is done by a run-time library invoked during program
execution.
Allocation of dynamic objects: Using the keyword malloc

Example 1:
int * p = malloc( sizeof(int) );
malloc will allocate unnamed memory of type int and will return the
address where the allocation was done.

Example 2:
int * q = malloc( 128 * sizeof(int) );
This line will allocate memory for an array of 128 elements of type int.

Deallocation of dynamic objects: Using the keyword free.

Example:

free( p );
free( q );

yoan Estru turas de Datos 36

Structures
A structure is a collection of one or more variables

Example 1:
#include <stdio.h>

int main( ){

struct point {
int x;
int y;
};

struct point p1 ={-1, 4}, p2 = {1, 5}, p3;


p3.x = 3;
p3.y = 6;
printf( "point 1 = (%d, %d)\n", p1.x, p1.y ); // point 1 = (-1, 4)
printf( "point 2 = (%d, %d)\n", p2.x, p2.y ); // point 2 = (1, 5)
printf( "point 3 = (%d, %d)\n", p3.x, p3.y ); // point 3 = (3, 6)

return 0;
}

yoan Estru turas de Datos 37


Example 2:
1 #include <stdio.h>

3 struct cat
4 {
5 int age;
6 int height;
7 char name[20];
8 char father[20];
9 char mother[20];
10 };

12 int main()
13 {
14 struct cat myCat;
15 printf("Enter the name of the cat: " ); scanf("%s", myCat.name );
16 printf("How old is %s? ", myCat.name ); scanf("%d", &myCat.age );
17 printf("How high is %s ( in hands )? ", myCat.name );
18 scanf("%d", &myCat.height );
19 printf("Who is %s’s father? ", myCat.name ); scanf("%s", myCat.father );
20 printf("Who is %s’s mother? ", myCat.name ); scanf("%s", myCat.mother );
21 printf("\n%s is %d years old, %d hands high,", myCat.name, myCat.age, ⤦
Ç myCat.height);
22 printf(" and has %s and %s as parents.\n", myCat.father,myCat.mother );

24 return 0;
25 }

yoan Estru turas de Datos 38

Files
In C we can make use of the function fopen to open a file, and fprintf
to write in it.

Example:
1 #include <stdio.h>

3 int main(){
4 FILE *f;
5 int i;

7 srand( time( NULL ) );


8 f=fopen( "data.txt", "w" );
9 for( i = 0; i < 100; i++ )
10 fprintf( f, "%10d\n", rand()%10000 );
11 fclose( f );

13 return 0;
14 }

yoan Estru turas de Datos 39


Other modes in which fopen can operate:

”r” reading (file must exits)

”w” writing (create new and overwrite if already exist)

”a” appends (created if does not exist)

”r+” reading/writing (file must exist)

”w+” reading/writing (create file)

”a+” reading/appending

fopen returns NULL if the file can not be opened

yoan Estru turas de Datos 40

Files
We can use fscanf to read from a file.

Example:
1 #include <stdio.h>

3 int main(){
4 FILE *f;
5 int x;

7 f=fopen( "data.txt", "r" );


8 while( !feof( f ) ){
9 fscanf( f, "%10d", &x );
10 printf( "%10d\n", x );
11 }
12 fclose( f );

14 return 0;
15 }

yoan Estru turas de Datos 41


Estructuras de Datos

List Data Structure

© 2020

In This Session

● List Data Structure


⊳ Array-based Representation
⊳ Linked Representation

yoan Estru turas de Datos 43


Data Structures
– in general –

A data structure is a data object along with the relationship that exist
among the instances and elements, and which are provided by specifying
the functions of interest.

Our main concern will be:


● The representation of data objects (actually of their instances)

● The representation should facilitate an efficient implementation of func-


tions

yoan Estru turas de Datos 44

List Data Structure

A list is a data object whose instances are of the form (e1, e2, . . . , en)
where n is a finite natural number.

The ei terms are the elements of the list and n is the length.

There exist different methods for representing a List, namely:


● Array-based Representation
● Linked Representation
● Indirect Addressing Representation
● Simulating Pointers Representation

In this course we will only focus our attention on the first two
representations

yoan Estru turas de Datos 45


Methods of Representing a List
Array-based Representation: Uses a mathematical formula to deter-
mine where (i.e., the memory address) to store each element of a data
object.

[0] [1] [2] [3] [4] ... [MaxSize-1]

FE300 5 2 4 8 9 ...
element length
FE300 5

yoan Estru turas de Datos 46

Linked Representation: The elements may be stored in any arbitrary


set of memory locations. Each element keeps explicit information about
the location of the next element called pointer (or link).

first

link
data 5 2 4 8 9

yoan Estru turas de Datos 47


Indirect Addressing Representation: Is a combination of formula-
based and linked representation where the addresses of the elements
are collected into a table.

elements 5 2 4 8 9

table [0] [1] [2] [3] [4]

yoan Estru turas de Datos 48

Simulating Pointers Representation: Similar to the linked list repre-


sentation. However, pointers are replaced by integers.

firstNode 2

node [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]

next 6 7 1 -1 5
element 8 5 4 9 2
first=2

5 2 4 8 9 -1

node[2] node[7] node[5] node[1] node[6]

yoan Estru turas de Datos 49


LinearList Data Structure
– Array-Based Representation –

A formula-based representation uses an array to represent the instances


of a linearlist. A simple formula is used to determine the location of each
element:

i= i − 1
locationˆ

This means that the ith element of the list (if it exists) is at position
i − 1 of the array.

yoan Estru turas de Datos 50

Example
An array list with 5 elements and max size 10 will look like this:

[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]

FE300 5 2 4 8 9

element MaxSize length


FE300 10 5

yoan Estru turas de Datos 51


arraylist.h

#ifndef ARRAYLIST
#define ARRAYLIST

#include <stdio.h>
#include <stdlib.h>
#define CAP 100

typedef struct List List;

struct List{
int a[ CAP ], n;
void (*add) ( List *, int, int );
void (*delete) ( List *, int );
int (*get) ( List *, int );
int (*search) ( List *, int );
void (*display) ( List * );
int (*size) ( List * );
int (*empty) ( List * );
};

void add( List * x, int index, int e ){ ... }


void delete( List * x, int index ){ ... }

yoan Estru turas de Datos 52

int get( List * x, int index ){ ... }


int search( List * x, int e ){ ... }
void display( List * x ){ ... }
int size( List * x ){ ... }
int empty( List * x ){ ... }
List createList( ){ ... }

#endif

yoan Estru turas de Datos 53


createList

List createList( ){
List l;
l.n = 0;
l.add = &add;
l.delete = &delete;
l.get = &get;
l.search = &search;
l.display = &display;
l.size = &size;
l.empty = &empty;
return l;
}

yoan Estru turas de Datos 54

add

void add( List * x, int index, int e ){


int i;
if( index < 0 || index > x->n ){
fprintf( stderr, "Error : invalid index\n" );
return;
}
if( x->n == CAP ){
fprintf( stderr, "Error : list is full\n" );
return;
}
for( i = x->n - 1; i >= index; i-- )
x->a[ i + 1 ] = x->a[ i ];
x->a[ index ] = e;
x->n++;
return;
}

yoan Estru turas de Datos 55


delete
void delete( List * x, int index ){
int i;
if( index < 0 || index >= x->n ){
fprintf( stderr, "Error : invalid index\n" );
return;
}
for( i = index; i < x->n - 1; i++ )
x->a[ i ] = x->a[ i + 1 ];
x->n--;
return;
}

yoan Estru turas de Datos 56

get, search

int get( List * x, int index ){


if( index < 0 || index >= x->n ){
fprintf( stderr, "Error : invalid index\n" );
return;
}
return x->a[ index ];
}

int search( List * x, int e ){


int i;
for( i = 0; i < x->n; i++ )
if( x->a[ i ] == e )
return i;
return -1;
}

yoan Estru turas de Datos 57


display, size, empty

void display( List * x ){


int i;
printf( "List: " );
for( i = 0; i < x->n; i++ )
printf( "%d ", x->a[ i ] );
printf( "\n" );
return;
}

int size( List * x ){


return x->n;
}

int empty( List * x ){


return x->n == 0;
}

yoan Estru turas de Datos 58

testlist.c
#include <stdio.h>
#include "arraylist.h"

int main(){
List maria = createList( );
maria.add( &maria, 0, 100 );
maria.add( &maria, 1, 80 );
maria.add( &maria, 2, 15 );
maria.add( &maria, 3, 24 );
maria.add( &maria, 4, 135 );
maria.display( &maria );
maria.delete( &maria, 2 );
maria.display( &maria );
printf( "La lista tiene %d elementos\n", maria.size( &maria ) );
printf( "El segundo elemento es %d\n", maria.get( &maria, 1 ) );
printf( "El numero 24 tiene posicion %d\n", maria.search( &maria, 24 ) );
return 0;
}

yoan Estru turas de Datos 59


Compilation and Running

C:\Users\Yoan\Desktop\code\progs>gcc testlist.c

C:\Users\Yoan\Desktop\code\progs>a
List: 100 80 15 24 135
List: 100 80 24 135
La lista tiene 4 elementos
El segundo elemento es 80
El numero 24 tiene posicion 2

C:\Users\Yoan\Desktop\code\progs>

yoan Estru turas de Datos 60

Complexity of Operations

add : Oˆn
delete : Oˆ
n
get : Ȉ1
search : Oˆn
display : Ȉn
size : Ȉ1
empty : Ȉ1
createList : Ȉ1

yoan Estru turas de Datos 61


LinearList Data Structure
– Linked Representation –

● Each element of an instance of a data object is represented as a group


of memory locations called cell or node.
● The elements may be stored in any arbitrary set of memory locations.

● Each element keeps explicit information about the location of the next
element through a pointer (or link)
● Also called Chain

first

Link Field
Data Field 5 2 4 8 9
Singly linked list or chain

yoan Estru turas de Datos 62

Example
A linked list with 5 elements will look like this:
first

L
Link Field
Data Field 5 2 4 8 9 first
FE30
FF10
link
FF26
FE45 link
FE30 0
data
link
FF10 2 data
data 9
5

FE45
link FA10
FA10 link
data FF26
4 data
8

yoan Estru turas de Datos 63


linkedlist.h

#ifndef LINKEDLIST
#define LINKEDLIST

#include <stdio.h>
#include <stdlib.h>

typedef struct List List;


typedef struct Node Node;

struct Node{
int item;
Node * next;
};

struct List{
Node * firstNode;
int n;
void (*add) ( List *, int, int );
void (*delete) ( List *, int );
int (*get) ( List *, int );
int (*search) ( List *, int );
void (*display) ( List * );
int (*size) ( List * );
int (*empty) ( List * );
};

yoan Estru turas de Datos 64

void add( List * x, int index, int e ){ ... }


void delete( List * x, int index ){ ... }
int get( List * x, int index ){ ... }
int search( List * x, int e ){ ... }
void display( List * x ){ ... }
int size( List * x ){ ... }
int empty( List * x ){ ... }
List createList( ){ ... }

#endif

Important: this representation does not specify any capacity

yoan Estru turas de Datos 65


createList

List createList( ){
List l;
l.firstNode = NULL;
l.n = 0;
l.add = &add;
l.delete = &delete;
l.get = &get;
l.search = &search;
l.display = &display;
l.size = &size;
l.empty = &empty;
return l;
}

yoan Estru turas de Datos 66

Adding after the kth element


If k=0
first

... link
1 2 3 n data

New Node

(a) Before
first
... link
2 3 4 n+1 data

1
(b) After

yoan Estru turas de Datos 67


If kx0

first ... ... link


1 k k+1 n data

New Node

(a) Before

first ... ... link


1 k k+2 n+1 data

k+1

(b) After

yoan Estru turas de Datos 68

add

void add( List * x, int index, int e ){


int i;
if( index < 0 || index > x->n ){
fprintf( stderr, "Error : invalid index\n" );
return;
}
Node * y = malloc( sizeof( Node ) );
y->item = e;
if( index == 0 ){
y->next = x->firstNode;
x->firstNode = y;
}
else{
Node * p = x->firstNode;
for( i = 0; i < index - 1; i++ )
p = p->next;
y->next = p->next;
p->next = y;
}
x->n++;
return;
}

yoan Estru turas de Datos 69


Deleting the kth element

first

link ... ...


data 1 k-1 k k+1 n

(a) Before
first

link ... ...


data 1 k-1 k n+1

(b) After

yoan Estru turas de Datos 70

delete
void delete( List * x, int index ){
int i;
if( index < 0 || index >= x->n ){
fprintf( stderr, "Error : invalid index\n" );
return;
}
if( empty( x ) ){
fprintf( stderr, "Error : list is empty\n" );
return;
}
Node * y;
if( index == 0 ){
y = x->firstNode;
x->firstNode = x->firstNode->next;
}
else{
Node * p = x->firstNode;
for( i = 0; i < index - 1; i++ )
p = p->next;
y = p->next;
p->next = p->next->next;
}
free( y );
x->n--;
return;
}

yoan Estru turas de Datos 71


get, search

int get( List * x, int index ){


int i;
if( index < 0 || index >= x->n ){
fprintf( stderr, "Error : invalid index\n" );
return;
}
Node * p = x->firstNode;
for( i = 0; i < index; i++ )
p = p->next;
return p->item;
}

int search( List * x, int e ){


int i;
Node * p = x->firstNode;
for( i = 0; i < x->n; i++ ){
if( p->item == e )
return i;
p = p->next;
}
return -1;
}

yoan Estru turas de Datos 72

display, size, empty

void display( List * x ){


int i;
printf( "List: " );
Node * y = x->firstNode;
for( i = 0; i < x->n; i++ ){
printf( "%d ", y->item );
y = y->next;
}
printf( "\n" );
return;
}

int size( List * x ){


return x->n;
}

int empty( List * x ){


return x->n == 0;
}

yoan Estru turas de Datos 73


testlist.c
#include <stdio.h>
#include "linkedlist.h"

int main(){
List maria = createList( );
maria.add( &maria, 0, 100 );
maria.add( &maria, 1, 80 );
maria.add( &maria, 2, 15 );
maria.add( &maria, 3, 24 );
maria.add( &maria, 4, 135 );
maria.display( &maria );
maria.delete( &maria, 2 );
maria.display( &maria );
printf( "La lista tiene %d elementos\n", maria.size( &maria ) );
printf( "El segundo elemento es %d\n", maria.get( &maria, 1 ) );
printf( "El numero 24 tiene posicion %d\n", maria.search( &maria, 24 ) );
return 0;
}

yoan Estru turas de Datos 74

Compilation and Running

C:\Users\Yoan\Desktop\code\progs>gcc testlist.c

C:\Users\Yoan\Desktop\code\progs>a
List: 100 80 15 24 135
List: 100 80 24 135
La lista tiene 4 elementos
El segundo elemento es 80
El numero 24 tiene posicion 2

C:\Users\Yoan\Desktop\code\progs>

yoan Estru turas de Datos 75


Complexity of Operations

add : Oˆn
delete : Oˆ
n
get : Oˆn
search : Oˆn
display : Ȉn
size : Ȉ1
empty : Ȉ1
createList : Ȉ1

yoan Estru turas de Datos 76

Array-based List Vs Linked List

● Arrays are easy to use, but they have a fixed length

● Can you predict the maximum number of element in the list?

● Will an array waste storage?

● Linked lists do not have a fixed length

● An array-based implementation does not waste space storing pointers


to the next item

● You can access any array item directly with equal access time, whereas
you must traverse a linked list to access the ith element

yoan Estru turas de Datos 77


● Inserting/Deleting elements in an array based implementation re-
quires the movement of other elements in the array

● Inseting/Deleting elements in a linked implementation does not re-


quire the movement of other elements in the array, however the ap-
propriate position has to be found

If most of the activity is on inserting/deleting elements, there is little


difference in performance (theoretically)

If most of the activity is on querying the list by their position, then


the array-based implementation will have better performance

yoan Estru turas de Datos 78


Estructuras de Datos

Stack Data Structure

© 2020

In This Session

● Stack Data Structure


⊳ Array-based Representation
⊳ Linked Representation
⊳ Applications
lParentheses Matching
lSwitchbox Routing

yoan Estru turas de Datos 80


Stacks Data Structure
A stack is a linear list in which insertions (also called additions) and
deletions take place at the same end. This end is called the top. The
other end is called the bottom.
top bottom
e e e
1 2 3
... ei ... en- en
1

insertions
deletions

bottom top
e e e
1 2 3
... ei ... en- en
1

insertions
deletions

In other words, a stack is a LIFO (last-in-first out) list

yoan Estru turas de Datos 81

Stack Data Structure


– Array-based Representation –

Basic design decision:

designate the left end of the array as the bottom and the
right end as the top

yoan Estru turas de Datos 82


arraystack.h
#ifndef ARRAYSTACK
#define ARRAYSTACK

#include <stdio.h>
#include <stdlib.h>
#define CAP 100

typedef struct Stack Stack;

struct Stack{
int a[ CAP ];
int top;
void (*push) ( Stack *, int );
void (*pop) ( Stack * );
int (*peek) ( Stack * );
void (*display) ( Stack * );
int (*empty) ( Stack * );
};

void push( Stack * x, int e ){ ... }


void pop( Stack * x ){ ... }
int peek( Stack * x ){ ... }
void display( Stack * x ){ ... }
int empty( Stack * x ){ ... }
Stack createStack( ){ ... }

#endif

yoan Estru turas de Datos 83

createStack

Stack createStack( ){
Stack s;
s.top = -1;
s.push = &push;
s.pop = &pop;
s.peek = &peek;
s.display = &display;
s.empty = &empty;
return s;
}

yoan Estru turas de Datos 84


push, pop

void push( Stack * x, int e ){


if( x->top == CAP - 1 ){
fprintf( stderr, "Error: stack is full\n" );
return;
}
x->a[ ++x->top ] = e;
return;
}

void pop( Stack * x ){


if( x->top == -1 ){
fprintf( stderr, "Error: stack is empty\n" );
return;
}
x->top--;
return;
}

yoan Estru turas de Datos 85

peek, display, empty

int peek( Stack * x ){


if( x->top == -1 ){
fprintf( stderr, "Error: stack is empty\n" );
return;
}
return x->a[ x->top ];
}

void display( Stack * x ){


int i;
printf( "Stack: [top] " );
for( i = x->top; i >= 0; i-- )
printf( "%d ", x->a[ i ] );
printf( "[bottom]\n" );
return;
}

int empty( Stack * x ){


return x->top == -1;
}

yoan Estru turas de Datos 86


teststack.c

#include <stdio.h>
#include "arraystack.h"

int main(){
Stack maria = createStack( );
maria.push( &maria, 100 );
maria.push( &maria, 80 );
maria.push( &maria, 15 );
maria.push( &maria, 24 );
maria.push( &maria, 135 );
maria.display( &maria );
maria.pop( &maria );
maria.display( &maria );
while( !maria.empty( &maria ) ){
printf( "Deleting top element %d\n", maria.peek( &maria ) );
maria.pop( &maria );
}
return 0;
}

yoan Estru turas de Datos 87

Compilation and Running

C:\Users\Yoan\Desktop\code\progs>gcc teststack.c

C:\Users\Yoan\Desktop\code\progs>a
Stack: [top] 135 24 15 80 100 [bottom]
Stack: [top] 24 15 80 100 [bottom]
Deleting top element 24
Deleting top element 15
Deleting top element 80
Deleting top element 100

C:\Users\Yoan\Desktop\code\progs>

yoan Estru turas de Datos 88


Complexity of Operations

push : Ȉ

pop : Ȉ

peek : Ȉ

display : Ȉ

empty : Ȉ

createStack : Ȉ

yoan Estru turas de Datos 89

Stack Data Structure


– Linked Representation –

Basic design decision:

designate the left end of the list as the top and the other
end as the bottom

yoan Estru turas de Datos 90


linkedstack.h

#ifndef LINKEDSTACK
#define LINKEDSTACK

#include <stdio.h>
#include <stdlib.h>

typedef struct Stack Stack;


typedef struct Node Node;

struct Node{
int item;
Node * next;
};

struct Stack{
Node * top;
void (*push) ( Stack *, int );
void (*pop) ( Stack * );
int (*peek) ( Stack * );
void (*display) ( Stack * );
int (*empty) ( Stack * );
};

yoan Estru turas de Datos 91

void push( Stack * x, int e ){ ... }


void pop( Stack * x ){ ... }
int peek( Stack * x ){ ... }
void display( Stack * x ){ ... }
int empty( Stack * x ){ ... }
Stack createStack( ){ ... }

#endif

yoan Estru turas de Datos 92


createStack

Stack createStack( ){
Stack s;
s.top = NULL;
s.push = &push;
s.pop = &pop;
s.peek = &peek;
s.display = &display;
s.empty = &empty;
return s;
}

yoan Estru turas de Datos 93

push, pop

void push( Stack * x, int e ){


Node * y = malloc( sizeof( Node ) );
y->item = e;
y->next = x->top;
x->top = y;
return;
}

void pop( Stack * x ){


if( x->top == NULL ){
fprintf( stderr, "Error: stack is empty\n" );
return;
}
Node * y = x->top;
x->top = x->top->next;
free( y );
return;
}

yoan Estru turas de Datos 94


peek, display, empty

int peek( Stack * x ){


if( x->top == NULL ){
fprintf( stderr, "Error: stack is empty\n" );
return;
}
return x->top->item;
}

void display( Stack * x ){


Node * y = x->top;
printf( "Stack: [top] " );
while( y ){
printf( "%d ", y->item );
y = y->next;
}
printf( "[bottom]\n" );
return;
}

int empty( Stack * x ){


return x->top == NULL;
}

yoan Estru turas de Datos 95

teststack.c

#include <stdio.h>
#include "linkedstack.h"

int main(){
Stack maria = createStack( );
maria.push( &maria, 100 );
maria.push( &maria, 80 );
maria.push( &maria, 15 );
maria.push( &maria, 24 );
maria.push( &maria, 135 );
maria.display( &maria );
maria.pop( &maria );
maria.display( &maria );
while( !maria.empty( &maria ) ){
printf( "Deleting top element %d\n", maria.peek( &maria ) );
maria.pop( &maria );
}
return 0;
}

yoan Estru turas de Datos 96


Compilation and Running

C:\Users\Yoan\Desktop\code\progs>gcc teststack.c

C:\Users\Yoan\Desktop\code\progs>a
Stack: [top] 135 24 15 80 100 [bottom]
Stack: [top] 24 15 80 100 [bottom]
Deleting top element 24
Deleting top element 15
Deleting top element 80
Deleting top element 100

C:\Users\Yoan\Desktop\code\progs>

yoan Estru turas de Datos 97

Complexity of Operations

push : Ȉ

pop : Ȉ

peek : Ȉ

display : Ȉ

empty : Ȉ

createStack : Ȉ

yoan Estru turas de Datos 98


Stack Application
– Parentheses Matching –

How do we match parentheses in an expression?

● (((a+b)*c+d*e)/((f+g)-h+i))

● (a*(a+b))/(b+d)

yoan Estru turas de Datos 99

Parentheses Matching
– Strategy –

● Scan expression from left to right

● When a left parenthesis is encountered, add its position to the stack

● When a right parenthesis is encountered, remove matching position


from stack

yoan Estru turas de Datos 100


Parentheses Matching
– Example –


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
( ( ( a + b ) * c + d * e ) / ( ( f + g ) - h ) )

3
2
1

                      
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
( ( ( a + b ) * c + d * e ) / ( ( f + g ) - h ) )

(3 7) (2 14) (17 21) (16 24) (1 25)

yoan Estru turas de Datos 101

Parentheses Matching
– Implementation –

parenthesismatching.c

#include <stdio.h>
#include <string.h>
#include "arraystack.h"

void printMatchedPairs( char* expr ){ ... }

int main( ){
char x[256];
printf( "Type an expression \n" );
gets( x );
printf( "The pairs of matching parentheses in %s are:\n", x );
printMatchedPairs( x );
return 0;
}

yoan Estru turas de Datos 102


printMatchedPairs

void printMatchedPairs( char* expr ){


int i;
Stack s = createStack( );
int n = strlen( expr );
for( i = 0; i < n; i++ )
if( expr[ i ] == ’(’ )
s.push( &s, i );
else if( expr[ i ] == ’)’ )
if( !s.empty( &s ) ){
printf( "%d %d\n", s.peek( &s ), i );
s.pop( &s );
}
else{
printf( "No match for right parenthesis at %d\n", i );
}
while( !s.empty( &s ) ){
printf( "No match for left parenthesis at %d\n", s.peek( &s ) );
s.pop( &s );
}
}

yoan Estru turas de Datos 103

Compilation and Running

C:\Users\Yoan\Desktop\code\progs>gcc parenthesismatching.c

C:\Users\Yoan\Desktop\code\progs>a
Type an expression
(((a+b)*c+d*e)/((f+g)-h+i))
The pairs of matching parentheses in (((a+b)*c+d*e)/((f+g)-h+i)) are:
2 6
1 13
16 20
15 25
0 26

yoan Estru turas de Datos 104


Stack Application
– Switchbox Routing –

The switchbox routing problem arises in the fabrication of computer


chips, where certain components need to be connected to other compo-
nents.
1 2 3 4 5 6 7 8 9 10
40 11
39 12
38 13
37 14
36 15
Routing region
35 16
34 17
33 18
32 19
31 20
30 29 28 27 26 25 24 23 22 21

yoan Estru turas de Datos 105

Switchbox Routing
– Example –

1 2 3 4 5 6 7 8 9 10
Net={ 1, 2, 3, 4, 4, 3, 2, 5, 5, 1 }

1 2 3
10 4
Routable !
9 5
8 7 6

1 2 3 4 5 6 7 8 9 10
Net={ 1, 2, 3, 4, 4, 2, 3, 5, 5, 1 }

1 2 3
10 4
NOT
Routable!
9 5
8 7 6

yoan Estru turas de Datos 106


Switchbox Routing
– Implementation –

switchbox.c

#include <stdio.h>
#include "arraystack.h"

void checkBox( int * net, int n ){ ... }

int main( ){
int i, n, * net;
printf( "Type number of pins in switch box\n" );
scanf( "%d", &n );
net = ( int * ) malloc( sizeof( int ) * n );
printf( "Type net numbers for pins 1 through %d\n", n );
for( i = 0; i < n; i++ )
scanf( "%d", &net[ i ] );
checkBox( net, n );
return 0;
}

yoan Estru turas de Datos 107

checkBox
void checkBox( int * net, int n ){
int i;
Stack s = createStack( );
for( i = 0; i < n; i++ )
if( !s.empty( &s ) )
if( net[ i ] == net[ s.peek( &s ) ] )
s.pop( &s );
else s.push( &s, i );
else s.push( &s, i );
if( s.empty( &s ) ){
printf( "Switch box is routable\n" );
return;
}
printf( "Switch box is not routable\n" );
return;
}

yoan Estru turas de Datos 108


Compilation and Running

C:\Users\Yoan\Desktop\code\progs>gcc switchbox.c

C:\Users\Yoan\Desktop\code\progs>a
Type number of pins in switch box
10
Type net numbers for pins 1 through 10
1 2 3 4 4 3 2 5 5 1
Switch box is routable

C:\Users\Yoan\Desktop\code\progs>a
Type number of pins in switch box
10
Type net numbers for pins 1 through 10
1 2 3 4 4 2 3 5 5 1
Switch box is not routable

C:\Users\Yoan\Desktop\code\progs>

yoan Estru turas de Datos 109


Estructuras de Datos

Time Complexity

© 2020

In This Session

● Time Complexity
⊳ Growth of Functions
⊳ Growth Rates
⊳ Asymptotic Notation: O, Ω, Θ

yoan Estru turas de Datos 152


Growth of Functions

● Asymptotic efficiency of algorithms

– How does the running time of an algorithm increase with the size
of the input in the limit as the input increases in size without
bound?

● Asymptotic notation (the order of)

– Define sets of functions that satisfy certain criteria and use these
to characterize time and space complexity of algorithms

yoan Estru turas de Datos 153

time
2n-7
n

0.5n+3

n
(a) Growth of Functions (Linear)

yoan Estru turas de Datos 154


time
2n
n2
n

log n

n
(b) Growth Rates

yoan Estru turas de Datos 155

Growth Rates

Let f ˆnand gˆnbe functions

¢
¨0, f ˆngrows slower than gˆn
¨
¨
f ˆn ¨
¨
¨ª, f ˆngrows faster than gˆn
lim ¦
n ª gˆn ¨¨
¨
¨
¨otherwise f ˆnand gˆn
¤have the same growth rate
¨

f ˆnhgˆn

lim f ˆn~gˆn= 0
n ª

f ˆnhgˆn: f ˆngrows slower than gˆn

0.5n h1 hlog n hlog6 n hn0.5 hn3 h2n hn!

yoan Estru turas de Datos 156


Asymptotic Notations

● Helps in simplifying the analysis of running time

● Deal with the behavior of functions in the limit (for sufficiently large
value of its parameters)

● Permit substantial simplification (napkin mathematic, rough order


of magnitude). Simple Rule: Drop lower order terms and constant
factors

– 7n − 3 is Oˆn

– 8n2 log n + 5n2 + n is Oˆn2 log n

● Classify functions by their growth rates

yoan Estru turas de Datos 157

The Big-Oh Notation


f ˆn= Oˆgˆn if there exist positive constants c and 0n such that for
every n Cn0,
f ˆnBcgˆn
time
cg(n)

f(n)

n0 n
f(n)=O(g(n))
yoan Estru turas de Datos 158
The Ω Notation
f ˆn= Ωˆgˆn if there exist positive constants c and 0n such that for
every n Cn0,
f ˆnCcgˆn
time

f(n)

cg(n)

n0 n
f(n)= (g(n))
yoan Estru turas de Datos 159

The Θ Notation
f ˆn= Ȉgˆnif f ˆn= Oˆgˆnand f ˆn= Ωˆn, or equivalently, if there
are positive constants c1, c2 and n0 such that for every n Cn0,
c1gˆnBf ˆnB2cgˆn
time
c2 g(n)

f(n)

c1 g(n)

n0 n
f(n)=£(g(n))
yoan Estru turas de Datos 160
Danger of Asymptotic Notation

● We typically try to get algorithms with the best running time.

● Then we might prefer an algorithm requiring 1, 000, 000n operations


to an algorithm requiring 1.000n log n operations for inputs of length
n.

● Even though the former algorithm is better for all but finitely many
instances, the latter is better for all the instances that can exist in
the known universe.

yoan Estru turas de Datos 161

Special Orders of Growth

● constant Oˆ1
● logarithmic Oˆlog n
● polylogarithmic Oˆlogc n, c C1
● n log n Oˆn log n
● sublinear Oˆna, 0 < a < 1
● linear Oˆn
● quadratic Oˆn2
● polynomial Oˆnc, c C1
● exponential Oˆcn, c > 1
● factorial Oˆn!

yoan Estru turas de Datos 162


Estructuras de Datos

Queue Data Structure

© 2020

In This Session

● Queue Data Structure


⊳ Array-based Representation
⊳ Linked Representation
⊳ Applications
lImage-Component Labeling
lLee’s Wire Router

yoan Estru turas de Datos 111


Queue Data Structure
A queue is a special case of linear list where insertions and deletions take
place at different ends

rear: end at which a new element is added.

front: end at which an element is deleted.

front rear
e e e
1 2 3
... ei ... en- en
1

deletions insertions

In other words, a queue is a FIFO (first-in-first-out) list

yoan Estru turas de Datos 112

Queue Data Structure


– Array-based Representation –

We can use three different approaches:

1) Using the formula locationˆ


i= i − 1

front rear front rear front rear

F A T ... A T ... A T E ...


[0] [1] [2] [0] [1] [0] [1] [2]

L Empty queue: rear = -1 L Deletion:


Shift all elements one position
L Addition: to the left.
rear = rear + 1 Ȉ ntime
queue[rear] = new element
Oˆ 1time

yoan Estru turas de Datos 113


2) Using the formula locationˆ 1+ i − 1
i= locationˆ

front rear front rear front rear

F A T ... A T ... A T E ...


[0] [1] [2] [0] [1] [2] [0] [1] [2] [3]

L Empty queue: rear < front

L front = locationˆ
1; rear = locationˆ

L Deletions & Insertions: Oˆ


1time

What happens if rear = MaxSize - 1 and front > 0 ?

yoan Estru turas de Datos 114

3) Using the formula locationˆ


i= ˆ 1+ i − 1
locationˆ %M axSize
rear rear rear

T T T E
A A A
F
front front

front

Lfront points one position before the position of the first element in the
queue.
L Empty queue: front = rear
(initially front=rear=0)
L Full queue: (rear+1)%MaxSize = front

This approach is also called Circular Queue

yoan Estru turas de Datos 115


arrayqueue.h
#ifndef ARRAYQUEUE
#define ARRAYQUEUE

#include <stdio.h>
#include <stdlib.h>
#define CAP 100

typedef struct Queue Queue;

struct Queue{
int a[ CAP ];
int front, rear, n;
void (*put) ( Queue *, int );
void (*delete) ( Queue * );
int (*getFront) ( Queue * );
int (*getRear) ( Queue * );
void (*display) ( Queue * );
int (*empty) ( Queue * );
};

void put( Queue * x, int e ){ ... }


void delete( Queue * x ){ ... }
int getFront( Queue * x ){ ... }
int getRear( Queue * x ){ ... }
void display( Queue * x ){ ... }
int empty( Queue * x ){ ... }
Queue createQueue( ){ ... }

#endif

yoan Estru turas de Datos 116

createQueue

Queue createQueue( ){
Queue q;
q.front = q.rear = q.n = 0;
q.put = &put;
q.delete = &delete;
q.getFront = &getFront;
q.getRear = &getRear;
q.display = &display;
q.empty = &empty;
return q;
}

yoan Estru turas de Datos 117


put, delete

void put( Queue * x, int e ){


if( x->n == CAP ){
fprintf( stderr, "Error: Queue is full\n" );
return;
}
x->rear = ( x->rear + 1 ) % CAP;
x->a[ x->rear ] = e;
x->n++;
return;
}

void delete( Queue * x ){


if( empty( x ) ){
fprintf( stderr, "Error: Queue is empty\n" );
return;
}
x->front = ( x->front + 1 ) % CAP;
x->n--;
return;
}

yoan Estru turas de Datos 118

getFront, getRear

int getFront( Queue * x ){


if( empty( x ) ){
fprintf( stderr, "Error: Queue is empty\n" );
exit( 1 );
}
return x->a[ ( x->front + 1 ) % CAP ];
}

int getRear( Queue * x ){


if( empty( x ) ){
fprintf( stderr, "Error: Queue is empty\n" );
exit( 1 );
}
return x->a[ x->rear ];
}

yoan Estru turas de Datos 119


display, empty

void display( Queue * x ){


int i;
printf( "Queue: [front] " );
for( i = 1; i <= x->n; i++ )
printf( "\%d ", x->a[ ( x->front + i ) % CAP ] );
printf( "[rear]\n" );
return;
}

int empty( Queue * x ){


return !x->n;
}

yoan Estru turas de Datos 120

testqueue.c

#include <stdio.h>
#include "arrayqueue.h"

int main(){
Queue maria = createQueue( );
maria.put( &maria, 100 );
maria.put( &maria, 80 );
maria.put( &maria, 15 );
maria.put( &maria, 24 );
maria.put( &maria, 135 );
maria.display( &maria );
maria.delete( &maria );
maria.display( &maria );
printf( "Front element is %d\n", maria.getFront( &maria ) );
printf( "Rear element is %d\n", maria.getRear( &maria ) );
while( !maria.empty( &maria ) ){
printf( "Deleting front element %d\n", maria.getFront( &maria ) );
maria.delete( &maria );
}
return 0;
}

yoan Estru turas de Datos 121


Compilation and Running

C:\Users\Yoan\Desktop\code\progs>gcc testqueue.c

C:\Users\Yoan\Desktop\code\progs>a
Queue: [front] 100 80 15 24 135 [rear]
Queue: [front] 80 15 24 135 [rear]
Front element is 80
Rear element is 135
Deleting front element 80
Deleting front element 15
Deleting front element 24
Deleting front element 135

C:\Users\Yoan\Desktop\code\progs>

yoan Estru turas de Datos 122

Complexity of Operations

put : Ȉ

delete : Ȉ

getFront : Ȉ

getRear : Ȉ

display : Ȉ

empty : Ȉ

createQueue : Ȉ

yoan Estru turas de Datos 123


Queue Data Structure
Linked Representation

...

front rear

...

front rear

(a) Addition

yoan Estru turas de Datos 124

...

front rear

(b) Deletion

L Empty queue: front = null

L Deletions & Insertions: Ȉ


1time

yoan Estru turas de Datos 125


linkedqueue.h

#ifndef LINKEDQUEUE
#define LINKEDQUEUE

#include <stdio.h>
#include <stdlib.h>

typedef struct Queue Queue;


typedef struct Node Node;

struct Node{
int item;
Node * next;
};

struct Queue{
Node *front, *rear;
void (*put) ( Queue *, int );
void (*delete) ( Queue * );
int (*getFront) ( Queue * );
int (*getRear) ( Queue * );
void (*display) ( Queue * );
int (*empty) ( Queue * );
};

yoan Estru turas de Datos 126

void put( Queue * x, int e ){ ... }


void delete( Queue * x ){ ... }
int getFront( Queue * x ){ ... }
int getRear( Queue * x ){ ... }
void display( Queue * x ){ ... }
int empty( Queue * x ){ ... }
Queue createQueue( ){ ... }

#endif

yoan Estru turas de Datos 127


createQueue

Queue createQueue( ){
Queue q;
q.front = q.rear = NULL;
q.put = &put;
q.delete = &delete;
q.getFront = &getFront;
q.getRear = &getRear;
q.display = &display;
q.empty = &empty;
return q;
}

yoan Estru turas de Datos 128

put, delete
void put( Queue * x, int e ){
Node * y = malloc( sizeof( Node ) );
y->item = e;
y->next = NULL;
if( empty( x ) )
x->front = y;
else
x->rear->next = y;
x->rear = y;
return;
}

void delete( Queue * x ){


if( empty( x ) ){
fprintf( stderr, "Error: Queue is empty\n" );
return;
}
Node * y = x->front;
x->front = x->front->next;
free( y );
return;
}

yoan Estru turas de Datos 129


getFront, getRear

int getFront( Queue * x ){


if( empty( x ) ){
fprintf( stderr, "Error: Queue is empty\n" );
exit( 1 );
}
return x->front->item;
}

int getRear( Queue * x ){


if( empty( x ) ){
fprintf( stderr, "Error: Queue is empty\n" );
exit( 1 );
}
return x->rear->item;
}

yoan Estru turas de Datos 130

display, empty

void display( Queue * x ){


Node * y = x->front;
printf( "Queue: [front] " );
while( y ){
printf( "%d ", y->item );
y = y->next;
}
printf( "[rear]\n" );
return;
}

int empty( Queue * x ){


return x->front == NULL;
}

yoan Estru turas de Datos 131


testqueue.c

#include <stdio.h>
#include "linkedqueue.h"

int main(){
Queue maria = createQueue( );
maria.put( &maria, 100 );
maria.put( &maria, 80 );
maria.put( &maria, 15 );
maria.put( &maria, 24 );
maria.put( &maria, 135 );
maria.display( &maria );
maria.delete( &maria );
maria.display( &maria );
printf( "Front element is %d\n", maria.getFront( &maria ) );
printf( "Rear element is %d\n", maria.getRear( &maria ) );
while( !maria.empty( &maria ) ){
printf( "Deleting front element %d\n", maria.getFront( &maria ) );
maria.delete( &maria );
}
return 0;
}

yoan Estru turas de Datos 132

Compilation and Running

C:\Users\Yoan\Desktop\code\progs>gcc testqueue.c

C:\Users\Yoan\Desktop\code\progs>a
Queue: [front] 100 80 15 24 135 [rear]
Queue: [front] 80 15 24 135 [rear]
Front element is 80
Rear element is 135
Deleting front element 80
Deleting front element 15
Deleting front element 24
Deleting front element 135

C:\Users\Yoan\Desktop\code\progs>

yoan Estru turas de Datos 133


Complexity of Operations

put : Ȉ

delete : Ȉ

getFront : Ȉ

getRear : Ȉ

display : Ȉ

empty : Ȉ

createQueue : Ȉ

yoan Estru turas de Datos 134

Queue Application
– Image-Component Labelling –

1 2
1 1 2 2
1 3
(a) Input 1 1 (b) Output 3 3
1 1 1 4 3 5
1 1 1 1 4 4 4 5
1 1 1 1 1 4 4 4 5 5

● Digitised image: m × m matrix of pixels (0,1). 0-pixel represents image


background; 1-pixel represents a point on an image component.
● Two pixels are adjacent if one is to the left, above, right, or below the
other.
● Two 1-pixels (component pixels) that are adjacent belong to the same
image component.
● Objective: label the components pixels such that two pixels get the
same label if and only if they are pixels of the same image component.

yoan Estru turas de Datos 135


Image-Component Labelling
– Implementation –

imagecomponets.c

#include <stdio.h>
#include "arrayqueue.h"

int **pixel, size, i, j;

typedef struct Position Position;

struct Position{
int row, col;
};

void inputImage( ){ ... }


void labelComponents( ){ ... }
void outputImage( ){ ... }

int main( ){
inputImage( );
labelComponents( );
outputImage( );
return 0;
}

yoan Estru turas de Datos 136

inputImage

void inputImage( ){
printf( "Enter image size: " );
scanf( "%d", &size );
pixel = malloc( ( size + 2 ) * sizeof( int * ) );
for( i = 0; i < size + 2; i++ )
pixel[i] = malloc( ( size + 2 ) * sizeof( int ) );
printf( "Enter the pixel array in row-major order\n" );
for( i = 1; i <= size; i++ )
for( j = 1; j <= size; j++ )
scanf( "%d", &pixel[ i ][ j ] );
return;
}

yoan Estru turas de Datos 137


labelComponents

void labelComponents( ){
int numOfNbrs = 4, id = 1, r, c;
Position nbr, here, offset[ 4 ] = {
{ 0, 1 }, // right
{ 1, 0 }, // down
{ 0, -1 }, // left
{ -1, 0 } // up
};
for( i = 0; i <= size + 1; i++ ){
pixel[ 0 ][ i ] = pixel[ size + 1 ][ i ] = 0;
pixel[ i ][ 0 ] = pixel[ i ][ size + 1 ] = 0;
}
Queue qx = createQueue();
Queue qy = createQueue();
for( r = 1; r <= size; r++ )
for( c = 1; c <= size; c++ )
if( pixel[ r ][ c ] == 1 ){
pixel[ r ][ c ] = ++id;
here = (Position) { r, c };
while( 1 ){
for( i = 0; i < numOfNbrs; i++ ){
nbr.row = here.row + offset[ i ].row;
nbr.col = here.col + offset[ i ].col;

yoan Estru turas de Datos 138

if( pixel[ nbr.row ][ nbr.col ] == 1 ){


pixel[ nbr.row ][ nbr.col ] = id;
qx.put( &qx, nbr.row );
qy.put( &qy, nbr.col );
}
}
if( qx.empty( &qx ) ) break;
here.row = qx.getFront( &qx );
here.col = qy.getFront( &qy );
qx.delete( &qx );
qy.delete( &qy );
}
}
return;
}

yoan Estru turas de Datos 139


outputImage

void outputImage( ){
printf( "\nThe labeled image is\n\n" );
for( i = 1; i <= size; i++ ){
for( j = 1; j <= size; j++ )
printf( "%d ", pixel[ i ][ j ] );
printf( "\n" );
}
}

yoan Estru turas de Datos 140

imagecomponents.input

7
0 0 1 0 0 0 0
0 0 1 1 0 0 0
0 0 0 0 1 0 0
0 0 0 1 1 0 0
1 0 0 0 1 0 0
1 1 1 0 0 0 0
1 1 1 0 0 0 0

yoan Estru turas de Datos 141


Compilation and Running

C:\Users\Yoan\Desktop\code\progs>gcc imagecomponents.c

C:\Users\Yoan\Desktop\code\progs>a < imagecomponents.input


Enter image size: Enter the pixel array in row-major order

The labeled image is

0 0 2 0 0 0 0
0 0 2 2 0 0 0
0 0 0 0 3 0 0
0 0 0 3 3 0 0
4 0 0 0 3 0 0
4 4 4 0 0 0 0
4 4 4 0 0 0 0

yoan Estru turas de Datos 142

Queue Application
– Lee’s Wire Router –

Find a path from S to T by wave propagation.

T
6 6
5 6 2 3 4 5 6 5 6 2 3 4 5 6
4 1 2 4 1 2
3 2 1 S 1 3 2 1 S 1
3 2 1 2 3 3 2 1 2 3
3 T 3 T
6 5 4 5 6 6 5 4 5 6

(a) Filing (b) Retrace

yoan Estru turas de Datos 143


Lee’s Wire Router
– Implementation –

wirerouter.c
#include <stdio.h>
#include "arrayqueue.h"

int **grid, size, pathLength, i, j;

typedef struct Position Position;

struct Position{
int row, col;
};

Position start, finish, path[100];

void inputData( ){ ... }


void findPath( ){ ... }
void outputPath( ){ ... }

int main( ){
inputData( );
if( findPath( ) ) outputPath( );
else printf( "There is no wire path" );
return 0;
}

yoan Estru turas de Datos 144

inputData

void inputData( ){
printf( "Enter grid size: " );
scanf( "%d", &size );
printf( "Enter the start position\n" );
scanf( "%d %d", &start.row, &start.col );
printf( "Enter the finish position\n" );
scanf( "%d %d", &finish.row, &finish.col );
grid = malloc( ( size + 2 ) * sizeof( int * ) );
for( i = 0; i < size + 2; i++ )
grid[i] = malloc( ( size + 2 ) * sizeof( int ) );
printf( "Enter the grid array in row-major order\n" );
for( i = 1; i <= size; i++ )
for( j = 1; j <= size; j++ )
scanf( "%d", &grid[ i ][ j ] );
return;
}

yoan Estru turas de Datos 145


findPath

void findPath( ){
int numOfNbrs = 4;
Position here, nbr, offset[ 4 ] = {
{ 0, 1 }, // right
{ 1, 0 }, // down
{ 0, -1 }, // left
{ -1, 0 } // up
};
for( i = 0; i <= size + 1; i++ ){
grid[ 0 ][ i ] = grid[ size + 1 ][ i ] = 1;
grid[ i ][ 0 ] = grid[ i ][ size + 1 ] = 1;
}
if( ( start.row == finish.row ) && ( start.col == finish.col ) )
return 1;
here = (Position) { start.row, start.col };
grid[ start.row ][ start.col ] = 2;
Queue qx = createQueue();
Queue qy = createQueue();
while( 1 ){
for( i = 0; i < numOfNbrs; i++ ){
nbr.row = here.row + offset[ i ].row;
nbr.col = here.col + offset[ i ].col;
if( grid[ nbr.row ][ nbr.col ] == 0 ){
grid[ nbr.row ][ nbr.col ] = grid[ here.row ][ here.col ] + 1;
if( ( nbr.row == finish.row ) && ( nbr.col == finish.col ) )

yoan Estru turas de Datos 146

break;
qx.put( &qx, nbr.row );
qy.put( &qy, nbr.col );
}
}
if( ( nbr.row == finish.row ) && ( nbr.col == finish.col ) )
break;
if( qx.empty( &qx ) ) return 0;
here.row = qx.getFront( &qx );
here.col = qy.getFront( &qy );
qx.delete( &qx );
qy.delete( &qy );
}
pathLength = grid[ finish.row ][ finish.col ] - 2;
here = finish;
for( j = pathLength - 1; j >= 0; j-- ){
path[ j ] = here;
for( i = 0; i < numOfNbrs; i++ ){
nbr.row = here.row + offset[ i ].row;
nbr.col = here.col + offset[ i ].col;
if( grid[ nbr.row ][ nbr.col ] == j + 2 ) break;
}
here = (Position) { nbr.row, nbr.col };
}
return 1;
}

yoan Estru turas de Datos 147


outputPath

void outputPath( ){
printf( "The wire path is\n" );
for( i = 0; i < pathLength; i++ )
printf( "%d %d\n", path[ i ].row, path[ i ].col );
return;
}

yoan Estru turas de Datos 148

wirerouter.input

7
3 2
4 6
0 0 1 0 0 0 0
0 0 1 1 0 0 0
0 0 0 0 1 0 0
0 0 0 1 1 0 0
1 0 0 0 1 0 0
1 1 1 0 0 0 0
1 1 1 0 0 0 0

yoan Estru turas de Datos 149


Compilation and Running

C:\Users\Yoan\Desktop\code\progs>gcc wirerouter.c

C:\Users\Yoan\Desktop\code\progs>a < wirerouter.input


Enter grid size: Enter the start position
Enter the finish position
Enter the grid array in row-major order
The wire path is
4 2
5 2
5 3
5 4
6 4
6 5
6 6
5 6
4 6

yoan Estru turas de Datos 150


Estructuras de Datos

Tree Data Structure

© 2020

In This Session

● Tree Data Structure


⊳ Terminology
⊳ Binary Trees
lProperties
lArray-based Representation
lLinked Representation
lTraversals
lAn Application

yoan Estru turas de Datos 164


Tree Data Structure

● Until now: linear and tabular data

● How can we represent hierarchical data?

– somebody’s descendants

– governmental/company subdivisions

– modular decomposition of programs

● Answer: using a Tree Data Structure

A tree is a data structure that organizes information like an


upsidedown tree

yoan Estru turas de Datos 165

Terminology
A tree is a finite nonempty set of elements

root ● x, y are children of v; v is a parent of x, y


level 1

● x, y are siblings
2
v
● Elements with no children are called
leaves
3
x y
● Level: root=level 1; children=level 2,3,
...
4

● Degree of an element: number of chil-


dren
5 subtree
● Height or Depth: number of levels
subtree

yoan Estru turas de Datos 166


Binary Trees
A binary tree is a tree (possible empty) in which every element has
degree B2

yoan Estru turas de Datos 167

Properties of Binary Trees

P1: Every binary tree with n elements, n > 0, has exactly n − 1 edges.

Proof: Each element (except the root) has one parent. §exactly one
edge between each child and its parent. Hence, §n − 1 edges. j

P2: The number of elements at level i is B2i−1, i > 0.

Proof: By induction on i.
Basis: i = 1; number of elements = 1 = 20
Ind. Hypothesis: i = k; number of elements at level k B2k−1.
Look at level i = k + 1
(number of elements at level k + 1) B2 (number of elements at level k)
B2 × 2k−1 = 2k . j

yoan Estru turas de Datos 168


P3: A binary tree of height h, h > 0, has at least h and at most 2h − 1
elements.

Poof: Let n be the number of elements. §must be C1 elements at each


level, hence, n Ch.
Now, if h = 0, then n = 0 = 20 − 1.
For h > 0, we have by P2 that

h
n BQ 2i−1 = 2h − 1
i=1
j

P4: Let h be the height of an n-elements binary tree, n C0. Then,


log2ˆ
n + 1
Bh Bn

Proof: §must be C1 element at each level, hence, h Bn.


P3  n B2h − 1  2h Cn + 1  h Clog2ˆn + 1
.
Since h is an integer, we have that h Clog2ˆ
n + 1
.j

yoan Estru turas de Datos 169

Full binary tree: A binary tree of height h is full if contains exactly 2h −1


elements.
1

2 3

4 5 6 7

Complete binary tree: Is a binary tree of height h in which all levels


(except perhaps for the last) have a maximum number of elements.

2 3

4 5 6

Number the elements from 1 through 2h − k, starting from level 1 and


proceed in a left-to-right fashion, for some k C1.

yoan Estru turas de Datos 170


P5: Let i, 1 Bi Bn, be the number assigned to an element v of a
complete binary tree. Then:
(i) If i = 1, then v is the root. If i > 1, then the parent of v has been
assigned the number
2
i~ .
(ii) If 2i > n, then v has no left child. Otherwise, its left child has been
assigned the number 2i.
(iii) If 2i + 1 > n, then v has no right child. Otherwise, its right child
has been assigned the number 2i + 1.

Proof: By induction on i. j

yoan Estru turas de Datos 171

Binary Tree Data Structure


– Array-based Representation –

Uses P5
1
A
2 3
B C
4 5 6 7
D E

1 2 3 4 5 6 7

A B C D E

Note: An n−element binary tree may require an array of size 2n − 1


for its representation.  Can be a waste of space.

yoan Estru turas de Datos 172


Binary Tree Data Structure
– Linked Representation –

The most popular way to represent a binary tree is by using links or


pointers. Each node is represented by three fields:

root

LeftChild RightChild
● data data
● LeftChild
● RightChild

data data

yoan Estru turas de Datos 173

Binary Tree Traversal


There are four common ways to traverse a binary tree:
● Preorder: Visit-Left-Right (VLR)
● Inorder: Left-Visit-Right (LVR)
● Postorder: Left-Right-Visit (LRV)
● Level order

Example:
A

B C

D E F

● Preorder: ABDECF ● Postorder: DEBFCA


● Inorder: DBEAFC ● Level order: ABCDEF

yoan Estru turas de Datos 174


binarytree.h

#ifndef BINARYTREE
#define BINARYTREE

#include <stdio.h>
#include <stdlib.h>

typedef struct TreeNode TreeNode;


typedef struct Tree Tree;

struct TreeNode{
int item;
TreeNode * left;
TreeNode * right;
};

struct Tree{
TreeNode * root;
void (*makeTree) ( Tree *, int, Tree *, Tree * );
void (*preorder) ( TreeNode * );
void (*inorder) ( TreeNode * );
void (*postorder) ( TreeNode * );
void (*levelorder) ( TreeNode * );
int (*empty) ( TreeNode * );
int (*size) ( TreeNode * );
int (*height) ( TreeNode * );
};

yoan Estru turas de Datos 175

void makeTree( Tree * x, int e, Tree * l, Tree * r ){ ... }


void preorder( TreeNode * p ){ ... }
void inorder( TreeNode * p ){ ... }
void postorder( TreeNode * p ){ ... }
void givenLevel( TreeNode * p, int level ){ ... }
void levelorder( TreeNode * p ){ ... }
int empty( TreeNode * p ){ ... }
int size( TreeNode * p ){ ... }
int height( TreeNode * p ){ ... }
Tree createTree( ){ ... }

#endif

yoan Estru turas de Datos 176


createTree

Tree createTree( ){
Tree t;
t.root = NULL;
t.makeTree = &makeTree;
t.preorder = &preorder;
t.inorder = &inorder;
t.postorder = &postorder;
t.levelorder = &levelorder;
t.empty = &empty;
t.size = &size;
t.height = &height;
return t;
}

yoan Estru turas de Datos 177

makeTree

void makeTree( Tree * x, int e, Tree * l, Tree * r ){


x->root = malloc( sizeof( TreeNode ) );
x->root->item = e;
x->root->left = l->root;
x->root->right = r->root;
l->root = r->root = NULL;
return;
}

yoan Estru turas de Datos 178


preorder, inorder, postorder
void preorder( TreeNode * p ){
if( p ){
printf( "%d ", p->item );
preorder( p->left );
preorder( p->right );
}
}

void inorder( TreeNode * p ){


if( p ){
inorder( p->left );
printf( "%d ", p->item );
inorder( p->right );
}
}

void postorder( TreeNode * p ){


if( p ){
postorder( p->left );
postorder( p->right );
printf( "%d ", p->item );
}
}

yoan Estru turas de Datos 179

levelorder

void givenLevel( TreeNode * p, int level ){


if( !p )
return;
if( level == 1 )
printf( "%d ", p->item );
else if( level > 1 ){
givenLevel( p->left, level - 1 );
givenLevel( p->right, level - 1 );
}
}

void levelorder( TreeNode * p ){


int h = height( p );
int i;
for( i = 1; i <= h; i++)
givenLevel( p, i );
}

yoan Estru turas de Datos 180


empty, size, height

int empty( TreeNode * p ){


return p == NULL;
}

int size( TreeNode * p ){


if( p )
return 1 + size( p->left ) + size( p->right );
else
return 0;
}

int height( TreeNode * p ){


int hl, hr;
if( p ){
hl = height( p->left );
hr = height( p->right );
if( hl > hr ) return ++hl;
else return ++hr;
}
else
return 0;
}

yoan Estru turas de Datos 181

testbinarytree.c

#include <stdio.h>
#include "binarytree.h"

int main(){
Tree a = createTree( );
Tree x = createTree( );
Tree y = createTree( );
Tree z = createTree( );
y.makeTree( &y, 1, &a, &a );
z.makeTree( &z, 2, &a, &a );
x.makeTree( &x, 3, &y, &z );
y.makeTree( &y, 4, &x, &a );
printf( "Preorder sequence is " );
y.preorder( y.root );
printf( "\n" );
printf( "Inorder sequence is " );
y.inorder( y.root );
printf( "\n" );
printf( "Postorder sequence is " );
y.postorder( y.root );
printf( "\n" );
printf( "Level sequence is " );

yoan Estru turas de Datos 182


y.levelorder( y.root );
printf( "\n" );
printf( "empty = %d\n", y.empty( y.root ) );
printf( "size = %d\n", y.size( y.root ) );
printf( "height = %d\n", y.height( y.root ) );
return 0;
}

yoan Estru turas de Datos 183

Compilation and Running

C:\Users\Yoan\Desktop\code\progs>gcc testbinarytree.c

C:\Users\Yoan\Desktop\code\progs>a
Preorder sequence is 4 3 1 2
Inorder sequence is 1 3 2 4
Postorder sequence is 1 2 3 4
Level sequence is 4 3 1 2
empty = 0
size = 4
height = 3

C:\Users\Yoan\Desktop\code\progs>

yoan Estru turas de Datos 184


Binary Tree Application
– Expression Trees –

+
+
* d
(a*b)+(c/d) * / (((a-b)*c)+d)
- c
a b c d
a b
Infix form: a*b+c/d a-b*c+d
Prefix form: +*ab/cd +*-abcd
Postfix form: ab*cd/+ ab-c*d+

● Infix: ambiguous; pre/postfix: unambiguous

● Postfix evaluation:
lScan left-to-right
lPut operator to a stack
lApply the encountered operator to the operands in the stack and
delete them from the stack.

yoan Estru turas de Datos 185


Estructuras de Datos

Priority Queue Data Structure

© 2020

In This Session

● Priority Queue Data Structure


⊳ Max Priority Queues
lHeaps
lAn Application

yoan Estru turas de Datos 187


Priority Queue Data Structure

● Priority Queues: FIFO structure where elements are deleted in in-


creasing (decreasing) order of priority rather than in the order in which
they arrived in the queue.

● Max Priority Queues: The Find/Delete operations apply to the ele-


ment of maximum priority.

● Min Priority Queues: The Find/Delete operations apply to the ele-


ment of minimum priority.

yoan Estru turas de Datos 188

Representation of a Max Priority Queue

● Linear list.

● Heap.

yoan Estru turas de Datos 189


Heaps

● Max tree (min tree): is a tree in which the value in a each node is
greater (less) than or equal to those in its children.

● Max heap (min heap): is a max (min) tree that is also a complete
binary tree.

14 2

12 7 7 4

10 8 6 10 8 6

(a) MaxHeap (b) MinHeap

yoan Estru turas de Datos 190

Representation of a Heap

● Formula-based, since it is a complete Binary tree.

● Use of property P5.

● A heap with n elements has height 


log2ˆ
n + 1


yoan Estru turas de Datos 191


Insertion

● Insert a new element as a leaf of the heap.

● Walk up to the root to restore the heap properties.

Time Complexity: Oˆ
log n

yoan Estru turas de Datos 192

Example: Insert 5.

20 20 20

15 2 15 2 15 5

14 10 14 10 5 14 10 2

yoan Estru turas de Datos 193


Example: Insert 21.

20 20 20

15 5 15 5 15 21

14 10 2 14 10 2 21 14 10 2 5

21

15 20

14 10 2 5

yoan Estru turas de Datos 194

Deletion

● Delete the root element.

● Delete the rightmost leaf at the highest level and put it in the root.

● Restore the heap properties by walking down from root to a leaf by


following the path determined by the child having the largest value.

Time Complexity: Oˆ
log n

yoan Estru turas de Datos 195


Example: Delete 21.

21 2

15 20 15 20 15 20

14 10 2 14 10 2 14 10

20

15 2

14 10

yoan Estru turas de Datos 196

Example: Delete 20.

20 10

15 2 15 2 15 2

14 10 14 10 14

15 15

14 2 10 2

10 14

yoan Estru turas de Datos 197


Initializing a Max Head

● n insert operations. Time Oˆ


n log n
.

● Playing a tournament. Time Oˆ


n.

yoan Estru turas de Datos 198

maxheap.h
#ifndef MAXHEAP
#define MAXHEAP

#include <stdio.h>
#include <stdlib.h>
#define CAP 100

typedef struct Heap Heap;

struct Heap{
int * a;
int n;
void (*put) ( Heap *, int );
void (*delete) ( Heap * );
int (*top) ( Heap * );
int (*initialize) ( Heap *, int *, int );
void (*display) ( Heap * );
int (*empty) ( Heap * );
};

void put( Heap * x, int e ){ ... }


void delete( Heap * x ){ ... }
int top( Heap * x ){ ... }
int initialize( Heap * x, int * b, int size ){ ... }
void display( Heap * x ){ ... }
int empty( Heap * x ){ ... }
Heap createHeap( ){ ... }

#endif

yoan Estru turas de Datos 199


createHeap

Heap createHeap( ){
Heap h;
h.n = 0;
h.a = malloc( sizeof( int ) * CAP + 1 );
h.put = &put;
h.delete = &delete;
h.top = &top;
h.initialize = &initialize;
h.display = &display;
h.empty = &empty;
return h;
}

yoan Estru turas de Datos 200

put

void put( Heap * x, int e ){


if( x->n == CAP ){
fprintf( stderr, "Error: Heap is full\n" );
return;
}
int p = ++x->n;
while( p != 1 && x->a[ p / 2 ] < e ){
x->a[ p ] = x->a[ p / 2 ];
p /= 2;
}
x->a[ p ] = e;
}

yoan Estru turas de Datos 201


delete
void delete( Heap * x ){
if( empty( x ) ){
fprintf( stderr, "Error: Heap is empty\n" );
return;
}
int e = x->a[ x->n-- ];
int p = 1, child = 2;
while( child <= x->n ){
if( child < x->n && x->a[ child ] < x->a[ child + 1 ] )
child++;
if( e >= x->a[ child ] )
break;
x->a[ p ] = x->a[ child ];
p = child;
child *= 2;
}
x->a[ p ] = e;
}

yoan Estru turas de Datos 202

top, display, empty

int top( Heap * x ){


if( empty( x ) ){
fprintf( stderr, "Error: Heap is empty\n" );
exit( 1 );
}
return x->a[ 1 ];
}

void display( Heap * x ){


int i;
printf( "Heap: " );
for( i = 1; i <= x->n; i++ )
printf( "%d ", x->a[ i ] );
printf( "\n" );
return;
}

int empty( Heap * x ){


return !x->n;
}

yoan Estru turas de Datos 203


initialize

int initialize( Heap * x, int * b, int size ){


int root, rootElement, child;
free( x->a );
x->a = b;
x->n = size;
for( root = x->n / 2; root >= 1; root-- ){
rootElement = x->a[ root ];
child = 2 * root;
while( child <= x->n ){
if( child < x->n && x->a[ child ] < x->a[ child + 1 ] )
child++;
if( rootElement >= x->a[ child ] )
break;
x->a[ child / 2 ] = x->a[ child ];
child *= 2;
}
x->a[ child / 2 ] = rootElement;
}
}

yoan Estru turas de Datos 204

testheap.c
#include <stdio.h>
#include "maxheap.h"

int main(){
int array[] = { 0, 8, 23, 89, 100, 35, 11, 52, 77, 44, 60 };
Heap maria = createHeap( );
maria.put( &maria, 100 );
maria.put( &maria, 80 );
maria.put( &maria, 15 );
maria.put( &maria, 24 );
maria.put( &maria, 135 );
maria.display( &maria );
printf( "Top element is %d\n", maria.top( &maria ) );
maria.delete( &maria );
maria.display( &maria );
maria.initialize( &maria, array, 10 );
maria.display( &maria );
while( !maria.empty( &maria ) ){
printf( "Deleting max element %d\n", maria.top( &maria ) );
maria.delete( &maria );
}
return 0;
}

yoan Estru turas de Datos 205


Compilation and Running

C:\Users\Yoan\Desktop\code\progs>gcc testheap.c

C:\Users\Yoan\Desktop\code\progs>a
Heap: 135 100 15 24 80
Top element is 135
Heap: 100 80 15 24
Heap: 100 77 89 44 60 11 52 23 8 35
Deleting max element 100
Deleting max element 89
Deleting max element 77
Deleting max element 60
Deleting max element 52
Deleting max element 44
Deleting max element 35
Deleting max element 23
Deleting max element 11
Deleting max element 8

C:\Users\Yoan\Desktop\code\progs>

yoan Estru turas de Datos 206

Priority Queue Application


– Heap Sort –

A heap can be used to sort n elements in Oˆ


n log ntime.

1) Initialize a max heap with n elements (time Oˆ


n)

2) Extract (i.e. delete) elements from the heap one at a time. Each
deletion takes Oˆlog ntime, so the total time is Oˆ
n log n

yoan Estru turas de Datos 207

You might also like