Documente Academic
Documente Profesional
Documente Cultură
co/profesores/ypinzon/2016699
Estructuras de Datos
Lecture Notes
c 2009
Teacher opens the door, but you must enter by yourself Chinese Proverb
Estructuras de Datos
Sesi on 1
Preliminares, Introducci on al C++ (1ra Parte)
Yoan Pinz on, PhD Profesor Asociado Universidad Nacional de Colombia http://dis.unal.edu.co/profesores/ypinzon c 2009
Session 1
Preliminares Horario de Clases Horario de Consulta Cr editos Intensidad Horaria Formato de Clase Comportamiento en Clase Bibliograf a P agina Web Docente Monitor de Curso Calendario Acad emico Evaluaciones Formato de las Evaluaciones Parciales Evaluaciones Supletorias Publicaci on de Calicaciones Reclamaci on de Calicaciones ProgramaCalendario
Preliminares
Horario de Clases
Lunes 07-08 08-09 09-10 10-11 11-12 12-01 01-02 02-03 03-04
Martes
Miercoles
Jueves
Viernes
Grupo 2 Grupo 2
Grupo 2 Grupo 2
Salon 453-107
http://dis.unal.edu.co/profesores/ypinzon/2016699
Horario de Consulta
Lunes 07-08 08-09 09-10 10-11 11-12 12-01 01-02 02-03 03-04
Martes
Miercoles
Jueves
Viernes
Consulta Consulta
Ocina 453-116
Durante el horario de consulta, el estudiante tiene la oportunidad de consultar sus dudas sobre algunos de los aspectos vistos en clase, y/o discutir sobre los progresos de su trabajo
http://dis.unal.edu.co/profesores/ypinzon/2016699
Intensidad Horaria Esta es una asignatura te orico-pr actica de 4 horas presenciales y 5 horas de trabajo personal por semana Este curso NO es validable!
Formato de la Clase La clase comiez a transcurridos cinco minutos de la hora establecida para su inicio Si llega tarde: est e sucientemente preparado porque ... Se dar a un descanso de aproximadamente 10 minutos por cada hora de clase
http://dis.unal.edu.co/profesores/ypinzon/2016699
Comportamiento en Clase 1. Por respeto hacia los dem as (y hacia m ) LLegue a tiempo No conteste llamadas en clase 2. Por respeto hacia usted mismo (y otros) Haga preguntas Levante la mano; haga la pregunta No sea timido; recuerde que no existen preguntas est upidas! He who asks is a fool for ve minutes, but he who does not ask remains a fool forever. Old Chinese saying 3. Por respeto hacia el tema (y hacia m ) Haga preguntas propias Trate de entender el qu e, el c omo, el porqu e y el para qu e ciles no son aburridos Los temas dif Los temas aburridos no son dif ciles Est e preparado para corregirme (educadamente)
http://dis.unal.edu.co/profesores/ypinzon/2016699
Bibliograf a S. Sahni, Data Structures, Algorithms and Applications in C++, Silicon Press; 2nd edition, 2004. S. Sahni, Data Structures, Algorithms and Applications in C++, WCB/McGraw-Hill, 1998. M. A. Weis, Data Structures and Algorithm Analysis in C++, 2/E, Addison-Wesley, 1999. B. Stroustrup, The C++ Programming Language, 3/E, AddisonWesley, 2000. S. B. Lippman and J. Lajoie, C++ Primer, 3rd Edition, AddisonWesley, 1998. A Aho, J Hopcroft and J Ullman, Data Structures and Algorithms, Addison-Wesley, 1983.
http://dis.unal.edu.co/profesores/ypinzon/2016699
P agina Web La p agina web del curso (cuya direcci on aparece abajo) contendr a informaci on relevante para los alumnos, de modo que sugerir a que la revisara con frecuencia http://dis.unal.edu.co/profesores/ypinzon/2016699 Docente Yoan Pinz on Ocina : 453/116 eMail : ypinzon@unal.edu.co WWW : http://dis.unal.edu.co/profesores/ypinzon Monitor del Curso John Alexander Cely Suarez
http://dis.unal.edu.co/profesores/ypinzon/2016699
L 2
Feb 2009 M M J
3 4 5
V 6
W e e k
L 2
Mar 2009 M M J
3 4 5
V 6
W e e k 2 3 4 5 6
Abr 2009 M M J
1 2
V 3
W e e k 6 7 8 9 10
May 2009 M M J V
1
W e e k 10 11 12 13 14
L 1 8
Jun 2009 M M J V S
2 3 4 5
W e e k 15 16 17
9 10
11 12 13
9 10
11 12 13
9 10
9 10
11 12
16 17 18 19 20 23 24 25 26 27
1
16 17 18 19 20 23 24 25 26 27 30 31
13 14 15 16 17 20 21 22 23 24 27 28 29 30
11 12 13 14 15 18 19 20 21 22 25 26 27 28 29
15 16 17 18 19 20 22 23 24 25 26 29 30
inicio/fin de clases primera evaluacin ordinaria (1Abr2009) segunda evaluacin ordinaria (6May2009) tercera evaluacin ordinaria (3Jun2009) semana santa
http://dis.unal.edu.co/profesores/ypinzon/2016699
Valor Porcentaje
1ra evaluacin ordinaria escrita (1Abr)........... 2da evaluacin ordinaria escrita (6May)........ 3ra evaluacin ordinaria escrita (3Jun).......... talleres (23Feb - 20Jun) .........................................
Total: 100%
Todas las evaluaciones se dar an en el rango de 0.0 a 5.0
http://dis.unal.edu.co/profesores/ypinzon/2016699
Evaluaciones (cont.) El curso cuenta con un componente te orico (75%) y un componente pr actico (25%)
aaaaaaaa aaaaaaaaaaa Nota1 aaaaaaaa aaaaaaaaaaa aaaaaaaa 25%aaaaaaaaaaa aaaaaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaaaaa aaaaaaaaaaa Nota4 aaaaaaaa Nota2 aaaaaaaaaaa aaaaaaaaaaaaaaaaaa a a aaaaaaaa 25% a a a a aaaaaaaaaaaaaaaaaa aaaa 25% aaaaaaaa aaaaaaaaaaa a a aaaaaaaaaaaaaaaaaa aaaa aaaaaaaa aa aa aaaaaaaaaaa a a a aa aaaaaaaa aaaaa aaaaaaaaaaaaa aaaa Nota3 a aaaaaaaa aaaaaaaaaaaaaaaaaaa aaaaa aaaaaaaa aaaaaaaaaaa
aaaaa25% aaaaaaa aa aa aaaa a a a a a a aaaaaaa
Teora (75%)
Este curso NO es validable, quien lo repruebe deber a, forzosamente, cursar el curso nuevamente!
http://dis.unal.edu.co/profesores/ypinzon/2016699
a Prctic (25%)
10
Las notas 1, 2 y 3 ser an evaluaciones parciales escritas Cada evaluaci on tendra un valor de 25% de la nota nal
Evaluaciones Supletorias
Cuando existen causas justicadas a juicio del profesor La solicitud de evaluaci on supletoria debe hacerse por escrito al profesor dentro de los cinco (5) d as h abiles siguientes a la fecha de presentaci on de la evaluaci on ordinaria prevista
http://dis.unal.edu.co/profesores/ypinzon/2016699
11
Publicaci on de Calicaciones
Los resultados de las evaluaciones ordinarias se dar an a conocer dentro de los diez (10) d as h abiles siguientes a su realizaci on.
Reclamaci on de Calicaciones
La revisi on de las calicaciones de evaluaciones ordinarias podr a ser reclamada, por una sola vez, dentro de los cinco (5) d as h abiles siguientes a la entrega de la nota, ante el Director del Departamento de Ingenier a de Sistemas e Industrial.
http://dis.unal.edu.co/profesores/ypinzon/2016699
12
ProgramaCalendario
PROGRAMA-CALENDARIO a. Identificacin de la asignatura: nombre completo, cdigo y nmero de crditos
Estructuras de Datos, 2016699, 3 crditos Semana 11,12=Tree Data Structure (terminology, binary trees, properties, Binary Tree ADT, fomula based representation, linked representation, binary tree traversals, an application, binary search trees) Semana 13,14=Priority Queue Data Structure (max priority queues ADT, heaps, formula based representation, an application) Semana 15,16=Dictionary Data Structure (dictionary ADT, BST representation, linear list representation, skip list representation, hash table representation)
b. Metodologa a utilizar
Combinacin de clase magistral y clase prctica de 4 horas de duracin. Se introducen los temas tericos, se explica la estructura de datos, se especifica el ADT (tipo de dato abstracto), se explica la codificacin en C++ haciendo nfasis en las diferentes formas que existen para representar datos en la memoria del computador, se ven algunas aplicaciones, se desarrolla un taller sobre el tema visto.
(conding in C++, comparing array based representation and linked representation) Semana 7,8=Stack Data Structure (stack ADT, formula based representation using inheritance and a customised implementation, linked representation using inheritance and a customised implementation, two applications : parentheses matching and switchbox routing) Semana 9,10=Queue Data Structure (queue ADT, formula based representation using a customised implementation, linked representation using a customised implementation, two applications : image component labeling and lees wire router)
g. Bibliografa
S. Sahni, Data Structures, Algorithms and Applications in C++, Silicon Press; 2nd edition, 2004. A Aho, J Hopcroft and J Ullman, Data Structures and Algorithms, Addison-Wesley, 1983.
h. Si la asignatura es validable o no
NO es validable
http://dis.unal.edu.co/profesores/ypinzon/2016699
13
C++ was developed by Bjarne Stroustrup of AT&T Bell Laboratories in the early 1980s, and is based on the C language. C++ is intended as an incremental improvement of C. Most C programs can be compiled using a C++ compiler. ANSI C++ : The American National Standards Institution (ANSI) provides ocial and generally accepted standard denitions of many programming languages, including C and 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.
http://dis.unal.edu.co/profesores/ypinzon/2016699
14
Program Structure
#include <iostream.h> // other preprocessor directives function-definition 1; function-definition 2; . . . int main(){ declaration 1; declaration 2; . . . execution-statement 1; execution-statement 2; . . . return 0; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
15
1. Comments: In C++ comments can be included by using the double slash (//) - anything following the double slash will be ignored by the compiler but only to the end of the line. C-style comments (/* .... */) can also be used in C++ ; where multiple line comments are required. However it is better to stick to one form of comment throughout rather than mix dierent styles. 2. The header le: The header le included in the basic C++ program is iostream.h, rather than stdio.h which would be used in a basic C program. The le iostream.h provides the fundamental input and output denitions and functions for C++ . We will be using other header les 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 denition of a function called main.
http://dis.unal.edu.co/profesores/ypinzon/2016699
16
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, dened in a block only has scope (i.e. is only available) within that block. 5. Identiers: As we have seen, C++ programs can be written using many English words which are not reserved words as:
http://dis.unal.edu.co/profesores/ypinzon/2016699
17
http://dis.unal.edu.co/profesores/ypinzon/2016699
18
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 modiers (e.g. short, long, unsigned) are used to build more complex data types. Integral data types Data type [signed] char unsigned char short int unsigned short int unsigned int long unsigned long long long int unsigned long long int
These
Bytes 1 1 2 2 4 4 4 4 8 8
Values [-128, 127] [0, 255] [-32768, 32767] [0, 65535] [231, 231-1] [0, 4294967295] [-231, 231-1] [0, 4294967295] [-263, 263-1] [0, 264-1]
values depend on the particular system and are described in the header le limits.h
http://dis.unal.edu.co/profesores/ypinzon/2016699
19
Bytes 4 8 16
values depend on the particular system and are described in the header le float.h
http://dis.unal.edu.co/profesores/ypinzon/2016699
20
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.
User Dened Data Types Later in the course we will study the topic of data types in much more detail. We will see how the programmer may dene his own data types. This facility provides a powerful programming tool when complex structures of data need to be represented and manipulated.
http://dis.unal.edu.co/profesores/ypinzon/2016699
21
Operators
Arithmetic Operators
Operator ( ) * / % + Function parentheses multiply divide modulo plus minus Use (expr expr1 expr1 expr1 expr1 expr1 list) * expr2 / expr2 % expr2 + expr2 - expr2 Association L-to-R L-to-R L-to-R L-to-R L-to-R L-to-R
Example:
int main(){ int i=4, j=7, k=5, val1, val2; val1 val2 cout cout = i * j / 2 + k % 2 -3 ; = (i * j / ( 2 + k )) % 2 - 3; << "val1=" << val1 << endl; // outputs 12 << "val2=" << val2 << endl; // outputs -3
return 0; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
22
< expr2 <= expr2 > expr2 >= expr2 == expr2 != expr2 && expr2 || expr2
Examples:
Expression (6 <= 6) && (5 < 3) (6 <= 6) || (5 < 3) (5 != 6) (5 < 3) && (6 <= 6) || (5 != 6) (5 < 3) && ((6 <= 6) || (5 != 6)) !((5 < 3) && ((6 <= 6) || (5 != 6))) true/false false true true true false true
http://dis.unal.edu.co/profesores/ypinzon/2016699
23
Bitwise Operators
Operator << >> & | Function bitwise NOT shift left shift right bitwise AND bitwise XOR bitwise OR Use expr expr1 << expr2 expr1 >> expr2 expr1 & expr2 expr1 expr2 expr1 | expr2 Association R-to-L L-to-R L-to-R L-to-R L-to-R L-to-R
Example:
// Assumes int unsigned int a unsigned int b unsigned int c unsigned int d unsigned int e unsigned int f unsigned int g are 4 bits = 11; // = ~a; // = a << 1; // = a >> 2; // = a & c; // = a ^ c; // = a | c; // 1011 0100 0110 0010 0010 1101 1111
http://dis.unal.edu.co/profesores/ypinzon/2016699
24
Assignment Operators
Operator = *= /= %= += -= <<= >>= &= |= = Function conventional assignment multiply and assign divide and assign modulo and assign add and assign subtract and assign shift left and assign shift right and assign AND and assign OR and assign XOR and assign Use lvalue = expr lvalue *= expr lvalue /= expr lvalue %= expr lvalue += expr lvalue -= expr lvalue <<= expr lvalue >>= expr lvalue &= expr lvalue |= expr lvalue = expr Association R-to-L R-to-L R-to-L R-to-L R-to-L R-to-L R-to-L R-to-L R-to-L R-to-L R-to-L
http://dis.unal.edu.co/profesores/ypinzon/2016699
25
Unary Operators
Operator ++ -sizeof sizeof ++ -+ Function post increment post decrement size of object size of type pre increment pre decrement unary plus unary minus Use lvalue++ lvalue-sizeof(expr) sizeof(type) ++lvalue --lvalue +lvalue -lvalue Association L-to-R L-to-R R-to-L R-to-L R-to-L R-to-L R-to-L R-to-L
Example:
int main(){ int x=5; cout << x << endl; cout << x++ << endl; cout << x << endl; x=5; cout << x << endl; cout << ++x << endl; cout << x << endl; return 0; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
26
Operators
in decreasing precedence order Oper. ( ) ++ -sizeof sizeof ++ - ! + & * * / % + << >> < <= > >= Function parentheses post increment post decrement size of object size of type pre increment pre decrement bitwise NOT logical NOT unary minus unary plus address of dereference multiply divide modulo plus minus shift left shift right less than less than or equal greater than greater than or equal Use (expr list) lvalue++ lvalue-sizeof(expr) sizeof(type) ++lvalue --lvalue expr !expr -lvalue +lvalue &expr *expr expr1 * expr2 expr1 / expr2 expr1 % expr2 expr1 + expr2 expr1 - expr2 expr1 << expr2 expr1 >> expr2 expr1 < expr2 expr1 <= expr2 expr1 > expr2 expr1 >= expr2 Association L-to-R L-to-R L-to-R R-to-L R-to-L R-to-L R-to-L R-to-L R-to-L R-to-L R-to-L R-to-L R-to-L L-to-R L-to-R L-to-R L-to-R L-to-R L-to-R L-to-R L-to-R L-to-R L-to-R L-to-R
http://dis.unal.edu.co/profesores/ypinzon/2016699
27
Operators (Cont.)
in decreasing precedence order Oper. == != & | && || ?: << >> = *= /= %= += -= <<= >>= &= |= = Function equal not equal bitwise AND bitwise XOR bitwise OR logic AND logic OR alternative if stream insertion stream extraction conventional assignment multiply and assign divide and assign modulo and assign add and assign subtract and assign shift left and assign shift right and assign AND and assign OR and assign XOR and assign Use expr1 == expr2 expr1 != expr2 expr1 & expr2 expr1 expr2 expr1 | expr2 expr1 && expr2 expr1 || expr2 expr1 ? expr2 : expr3 expr1 << expr2 expr1 >> expr2 lvalue = expr lvalue *= expr lvalue /= expr lvalue %= expr lvalue += expr lvalue -= expr lvalue <<= expr lvalue >>= expr lvalue &= expr lvalue |= expr lvalue = expr Association L-to-R L-to-R L-to-R L-to-R L-to-R L-to-R L-to-R L-to-R L-to-R L-to-R R-to-L R-to-L R-to-L R-to-L R-to-L R-to-L R-to-L R-to-L R-to-L R-to-L R-to-L
http://dis.unal.edu.co/profesores/ypinzon/2016699
28
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); cout << "a=" cout << "b=" cout << "c=" cout << "d=" return 0; }
a b c d
http://dis.unal.edu.co/profesores/ypinzon/2016699
29
Constant Variables we can specify that a variables value cannot be altered during the execution of a program with the reserved word const. Example:
#include <iostream.h> const double Pi = 3.14159; int main(){ double radius, area, circumference; cout << "Circle radius: "; cin >> radius; area = Pi * radius * radius; circumference = Pi * 2 * radius; cout << "Area of circle with radius " << radius << " is " << area << endl; cout << "Circumference is " << circumference << endl; 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.
http://dis.unal.edu.co/profesores/ypinzon/2016699
30
Control Structures
If and If/Else selection structure
if(Boolean-expression){ i-statement-1; i-statement-2; . . . } else { e-statement-1; e-statement-2; . . . }
http://dis.unal.edu.co/profesores/ypinzon/2016699
31
Example 1. Get a candidates grade and reports whether the candidate has passed the test or not. The pass mark is 50%.
#include <iostream.h> int main(){ int grade; cout << "Enter the grade: "; cin >> grade; if(grade >= 50){ cout << "Passed" << endl; } else { cout << "Failed" << endl; cout << "You must take this course again" << endl; } return 0; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
32
Example 2. Get a candidates age and test score, and reports whether the candidate has passed the test. It uses the following criteria: candidates between 0 and 14 years old have a pass mark of 50%, 15 and 16 year olds have a pass mark of 55%, over 16s have a pass mark of 60%:
int main(){ int candidate_age, candidate_score; cout << "Enter the candidates age: "; cin >> candidate_age; cout << "Enter the candidates score: "; cin >> candidate_score; if (candidate_age <= 14 && candidate_score >= 50) cout << "This candidate passed the test." << endl; else if (candidate_age <= 16 && candidate_score >= 55) cout << "This candidate passed the test." << endl; else if (candidate_score >= 60) cout << "This candidate passed the test." << endl; else cout << "This candidate failed the test." << endl; return 0; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
33
switch(selector){ case label-1: statement-1; break; . . . . . . . . . case label-N: statement-N; break; default: d-statement; }
Example. Get a candidates 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 nally, if score has value 8, 9 or 10, print Well done!!!.
http://dis.unal.edu.co/profesores/ypinzon/2016699
34
int main(){ int score; cout << "Enter the score"; cin >> score; switch(score){ case 0: case 1: case 2: case 3: case 4: cout << "You have fail." << endl; break; case 5: cout << "You can do better." << endl; break; case 6: case 7: cout << "You have done quite well." << endl; break; case 8: case 9: case 10: cout << "Well done!!!." << endl; break; default: cout << "Wrong score." << endl; } return 0; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
35
A awed diamond is better than a common stone that is perfect. Chinese Proverb
Estructuras de Datos
Sesi on 2
Introducci on al C++ (2da Parte)
Yoan Pinz on, PhD Profesor Asociado Universidad Nacional de Colombia http://dis.unal.edu.co/profesores/ypinzon c 2009
Previous Session
Introduction to C++ (Part I)
The Origins of C++ Program Structure Data Types Operators Control Structures
http://dis.unal.edu.co/profesores/ypinzon/2016699
Session 2
Introduction to C++ (Part II)
Iteration Statements Break and Continue Arrays Pointers Dynamic Memory Allocation Functions Argument Passing Methods
http://dis.unal.edu.co/profesores/ypinzon/2016699
Iteration Statements
There are three types of iteration statements, which are informally known as loops:
The for-loop statement: for(init-statement; condition; expression) { loop-statement-1; loop-statement-2; . . . } The do-while-loop statement: do { loop-statement-1; loop-statement-2; . . . } while(condition); The while-loop statement: while(condition) { loop-statement-1; loop-statement-2; . . . }
To see how they work, let us use all three of then for the same purpose, namely to compute s = n i=1 i (s = 1 + 2 + 3 + . . . + n).
http://dis.unal.edu.co/profesores/ypinzon/2016699
http://dis.unal.edu.co/profesores/ypinzon/2016699
As you see there are not major dierences 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.
http://dis.unal.edu.co/profesores/ypinzon/2016699
Example:
#include <iostream> int main(){ double s=0.0, x; cout << "Enter numbers, separated by blanks." << endl; cout << "They are added up as long as they are positive." << endl << endl; for (;;){ // Example of a forever-loop cin >> x; if (x <= 0) break; s += x; } cout << "Sum of the positive numbers that have "; cout << "been read: " << s << endl; return 0; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
http://dis.unal.edu.co/profesores/ypinzon/2016699
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 <iostream> int main(){ int i, a[10]; for (i=0; i<10; i++){ cout << "a[" << i+1 << "]= "; cin >> a[i]; } cout << "The same integers, in reverse order: "; for (i=9; i>=0; i--) cout << a[i] << " "; return 0; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
http://dis.unal.edu.co/profesores/ypinzon/2016699
Pointers
Variables that contains a memory address as its value. There are two important pointer operators namely:
Operator & * Function address of dereference Meaning returns the address of the object given by the operand returns the object that has the address given by the operand
Example:
#include <iostream.h> int main(){ int i=16; int * pi; pi = &i; cout << *pi << endl; // Outputs 16 return 0; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
10
This line of code will allocate unnamed memory of type int and will initialize its value to 128. Example 2:
int * q = new int[128];
This line will allocate memory for an array of 128 elements of type int. Deallocation of dynamic objects: Using the keyword delete for single objects and delete[] for an array of objects. Example:
delete p; delete[] q;
http://dis.unal.edu.co/profesores/ypinzon/2016699
11
Functions
User-dened operation to facilitate the reuse of code within programs. a function basically consists of:
http://dis.unal.edu.co/profesores/ypinzon/2016699
12
http://dis.unal.edu.co/profesores/ypinzon/2016699
13
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 <iostream.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); cout << "a=" << a << endl << "b=" << b << endl; return 0; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
14
Learning is a treasure that will follow its owner everywhere. Chinese Proverb
Estructuras de Datos
Sesi on 3
Introducci on al C++ (3ra Parte)
Yoan Pinz on, PhD Profesor Asociado Universidad Nacional de Colombia http://dis.unal.edu.co/profesores/ypinzon c 2009
Previous Session
Introduction to C++ (Part II)
Iteration Statements Break and Continue Arrays Pointers Dynamic Memory Allocation Functions Argument Passing Methods
http://dis.unal.edu.co/profesores/ypinzon/2016699
Session 3
Introduction to C++ (Part III)
References Templates Inline Expansion Overloading Exception Handling Classes and Objects Constructors Destructor Inheritance
http://dis.unal.edu.co/profesores/ypinzon/2016699
References
A reference is an alias or a name to an existing object. They are similar to pointers in that they must be initialized before they can be used. Example 1:
#include <iostream.h> int main(){ int n = 10; int& r = n; r = - 10; cout << "n=" << n << endl; // Outputs -10 n = 7; cout << "r=" << r << endl; // Outputs 7 return 0; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
Example 2:
#include <iostream.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); cout << "a=" << a << endl << "b=" << b << endl; return 0; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
Templates
C++ templates may be used to parameterize functions or classes. Example:
#include <iostream.h> template <class T > void swap(T &x, T &y){ T t = x; x = y; y = t; } int main(){ int a = 10, b = 20; double d = 10.0, e = 20.0; char c = a, s = b; swap(a, cout << cout << cout << }
http://dis.unal.edu.co/profesores/ypinzon/2016699
b); swap(d, e); swap(c, "a=" << a << endl; cout "d=" << d << endl; cout "c=" << c << endl; cout
s); << "b=" << b << endl; << "e=" << e << endl; << "s=" << s << endl;
return 0;
Inline Expansion
Some functions are so small that the overhead of invoking the function call takes more time than the body of the function itself. C++ provides the inline keyword to inform the compiler to place the function inline rather than generate the code for calling the routine. Example 1:
inline int max(int x, int y) { return (x > y ? x : y); }
Example 3:
template<class T > inline T square(T x) { return x * x; }
Example 2:
inline void swap(int& x, int& y) { int temp = x; x = y; y = temp; return; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
Overloading
Simply, the same function name or operator symbol can be given several dierent denitions. The number and types of the arguments supplied to a function or operator tell the compiler which denition to use. Overloading is most often used to provide dierent denitions for member functions of a class. Overloading can also be used for functions that are not a member of any class. Example:
int Search(const int* data, const int key); int Search(const float* data, const float key); int Search(const double* data, const double key);
The compiler will ensure that the correct function is called based on the types of the arguments passed to Search(). When arguments do not exactly match the formal parameter types, the compiler will perform implicit type conversions (e.g., int to oat) in an attempt to nd a match.
http://dis.unal.edu.co/profesores/ypinzon/2016699
Exception Handling
An exception is just a run-time anomaly that a program may detect. Exceptions are thrown by the system or by the programmer and are caught using the try and catch keywords. Example:
try{ x = new long long int [n]; } catch(...){ cout << "Out of memory" << endl; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
Example:
1 2 3 4 5 6 7 8 9
class Point{ int _x, _y; // Point Coordinates public: void setX(const int void setY(const int int getX() { return int getY() { return }; void Point::setX(const int val){ _x = val; } void Point::setY(const int val){ _y = val; }
16 17 18 19
// Declaration
20 21 22 23 24 25 26 27
mypoint.setX(1); mypoint.setY(2); int x = mypoint.getX(); int y = mypoint.getY(); cout << "x =" << x << endl; cout << "y =" << y << endl; return 0; }
10 11 12
13 14 15
http://dis.unal.edu.co/profesores/ypinzon/2016699
10
This example declares a class Point and dene an object called mypoint. You can think of a class denition as a structure denition with functions (or methods). Currently, we need to call the set method to initialize a point object. However, we would like to initialize the point when we dene it. We therefore use special methods called constructors.
http://dis.unal.edu.co/profesores/ypinzon/2016699
11
Constructors
Constructors are methods which are used to initialize an object at its denition time. We extend our class Point such that it initializes a point to coordinates (0, 0):
class Point{ int _x, _y; public: Point(){ // Default _x = _y = 0; } void setX(const int void setY(const int int getX() { return int getY() { return }; Constructor val); val); _x; } _y; }
Constructors have the same name of the class. They have no return value. As other methods, they can take arguments. For example, we may want to initialize a point to other coordinates than (0, 0). We therefore dene a second constructor taking two integer arguments within the class:
http://dis.unal.edu.co/profesores/ypinzon/2016699
12
class Point{ int _x, _y; public: Point(){ // Default Constructor _x = _y = 0; } Point(const int x, const int y){ // Second Constructor _x = x; _y = y; } void setX(const int val); void setY(const int val); int getX() { return _x; } int getY() { return _y; } };
13
If we want to create a point from another point, hence, copying the properties of one object to a newly created one, we create a copy constructor. For example:
class Point{ int _x, _y; public: Point(){ // Default Constructor _x = _y = 0; } Point(const int x, const int y){ // Second Constructor _x = x; _y = y; } Point(const Point &from){ // Copy Constructor _x = from._x; _y = from._y; } void setX(const int val); void setY(const int val); int getX() { return _x; } int getY() { return _y; } };
http://dis.unal.edu.co/profesores/ypinzon/2016699
14
The third constructor takes a constant reference to an object of class Point as an argument and assigns x and y the corresponding values of the provided object. The copy constructor is called in the following cases:
Point bpoint(apoint); Point cpoint = apoint;
http://dis.unal.edu.co/profesores/ypinzon/2016699
15
Destructor
The destructor is the mechanism which automatically destroys an object when it gets invalid (for example, because of leaving its scope). Example:
1 2 3 4 5 6 7 8 9 10 11 12 13
class Point{ int _x, _y; public: // Default Constructor Point(){ _x = _y = 0; } // Second Constructor Point(const int x, const int y){ _x = x; _y = y; }
14 15 16 17 18 19 20 21 22 23 24 25
// Copy Constructor Point(const Point &from){ _x = from._x; _y = from._y; } // Destructor ~Point() { /* Nothing to do! */ } void setX(const int val); void setY(const int val); int getX() { return _x; } int getY() { return _y; } };
http://dis.unal.edu.co/profesores/ypinzon/2016699
16
Inheritance
In C++ this word is replaced by a colon. As an example lets design a class for 3D points. Of course we want to reuse our already existing class Point. We start designing our class as follows:
class Point3D : public Point{ int _z; public: Point3D(){ // Default Constructor setX(0); setY(0); _z = 0; } Point3D(const int x, const int y, const int z){ // Second Constructor setX(x); setY(y); _z = z; } ~Point3D() { /* Nothing to do */ } // Destructor int getZ() { return _z; } void setZ(const int val) { _z = val; } };
http://dis.unal.edu.co/profesores/ypinzon/2016699
17
A class species two interfaces: one to the users of the class (the public interface) and another to implementors of derived classes (the union of public and protected parts). Inheritance works almost identically. When the inheritance is public, the public interface of the base class becomes part of the public interface to users of the derived class. When the inheritance is protected, the public and protected parts of the base class are accessible to the member functions of the derived classes, but not to general users of the derived classes. Finally, when inheritance is private, the public and protected parts of the base class are only accessible to the implementor of the class, but not to users or derived classes. Inheritance public private protected Base Class public protected public protected public protected Derived Class public protected private private protected protected
http://dis.unal.edu.co/profesores/ypinzon/2016699
18
If your strength is small, dont carry heavy burdens. If your words are worthless, dont give advice. Chinese Proverb
Estructuras de Datos
Sesi on 4
Methods of Representing Data
Yoan Pinz on, PhD Profesor Asociado Universidad Nacional de Colombia http://dis.unal.edu.co/profesores/ypinzon c 2009
Previous Session
Introduction to C++ (Part III)
References Templates Inline Expansion Overloading Exception Handling Classes and Objects Constructors Destructor Inheritance
http://dis.unal.edu.co/profesores/ypinzon/2016699
Session 4
Preliminaries Methods of Representing Data Formula-based Representation Linked Representation Indirect Addressing Representation Simulating Pointers Representation LinearList Data Structure Formula-based Representation
http://dis.unal.edu.co/profesores/ypinzon/2016699
Preliminaries
Data Structure: 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 ecient implementation of functions ADT - Abstract Data Type: A general way that provides a specication of the instances as well as of the operations that are to be performed. This representation is completely independent of the implementation.
http://dis.unal.edu.co/profesores/ypinzon/2016699
[0]
[1]
[2]
[3]
[4]
...
[MaxSize-1]
FE300
5 2 4 8 9
element FE300
...
length 5
http://dis.unal.edu.co/profesores/ypinzon/2016699
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
http://dis.unal.edu.co/profesores/ypinzon/2016699
Indirect Addressing Representation: Is a combination of formulabased and linked representation where the addresses of the elements are collected into a table.
elements
table
[0]
[1]
[2]
[3]
[4]
http://dis.unal.edu.co/profesores/ypinzon/2016699
Simulating Pointers Representation: Similar to the linked list representation. However, pointers are replaced by integers.
2
[1] [2] [3] [4] [5] [6] [7] [8] [9]
-1
8 5
4 9 2
5
node[2]
2
node[7]
4
node[5]
8
node[1]
-1
node[6]
7
http://dis.unal.edu.co/profesores/ypinzon/2016699
A linear list is a data object whose instances are of the form (e1, e2, . . . , en ) where n is a nite natural number. The ei terms are the elements of the list and n is the length. A linear list may be dened as an abstract data type (ADT) as follows:
AbstractDataType LinearList { instances: ordered nite collection of zero or more elements operations: Create(): create an empty linear list Destroy(): erase the list IsEmpty(): return true if the list is empty. false otherwise Length(): return the number of elements in the list Find(k, x): return the kth element of the list in x,return false is no kth element Search(x): return the position of x in the list, return 0 if is not in the list Delete(k, x): delete the kth element and return it in x, returns the modied list Insert(k, x): insert x just after the kth element, returns the modied linear list Output(out): put the list into the output stream out }
http://dis.unal.edu.co/profesores/ypinzon/2016699
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: location(i) = i 1
This means that the ith element of the list (if it exists) is at position i 1 of the array.
http://dis.unal.edu.co/profesores/ypinzon/2016699
template<class T> class LinearList{ public: LinearList(int MaxListSize = 10); // constructor LinearList(){delete [] element;} // destructor bool IsEmpty() const {return length == 0;} int Length() const {return length;} bool Find(int k, T& x) const; // return the kth element of list in x int Search(const T& x) const; // return position of x LinearList<T>& Delete(int k, T& x); // delete kth element and return in x LinearList<T>& Insert(int k, const T& x); // insert x just after kth element void Output(ostream& out) const; private: int length; int MaxSize; T *element; // dynamic 1D array };
http://dis.unal.edu.co/profesores/ypinzon/2016699
10
An instance of this class (LinearList L of integers) with lenght=5 and MaxSize=10 will look like this:
[0]
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
[9]
FE300
5 2 4 8 9
element FE300 MaxSize 10 length 5
http://dis.unal.edu.co/profesores/ypinzon/2016699
11
Constructor
template<class T> LinearList<T>::LinearList(int MaxListSize) { // Constructor for formula-based linear list. MaxSize = MaxListSize; element = new T[MaxSize]; length = 0; }
Time Complexity: O(1) + time required by new. Remark: Time Complexity of destructor is O(1).
http://dis.unal.edu.co/profesores/ypinzon/2016699
12
Time Complexities: IsEmpty : Find : (1) (1) Length Search : : (1) O(n)
13
http://dis.unal.edu.co/profesores/ypinzon/2016699
Deleting the kth element If the list doesnt have a kth element, then throw an exception (OutOfBounds). Otherwise, move elements ek+1, ek+2, . . . , en one position to the left and reduce the value of n (length).
template<class T> LinearList<T>& LinearList<T>::Delete(int k, T& x) { // Set x to the kth element and delete it. // Throw OutOfBounds exception if no kth element. if (Find(k, x)) { // move elements k+1, ..., down for (int i = k; i < length; i++) element[i-1] = element[i]; length--; return *this; } else throw OutOfBounds(); }
Time Complexity : s :
14
Inserting after the kth element Move elements ek+1, ek+2, . . . , en one position to the right, insert the new element at position k + 1, and increase the value of n (length).
template<class T> LinearList<T>& LinearList<T>::Insert(int k, const T& x) { // Insert x after the kth element. // Throw OutOfBounds exception if no kth element. // Throw NoMem exception if list is already full. if (k < 0 || k > length) throw OutOfBounds(); if (length == MaxSize) throw NoMem(); // move one up for (int i = length-1; i >= k; i--) element[i+1] = element[i]; element[k] = x; length++; return *this; }
Time Complexity :
((n k)s).
http://dis.unal.edu.co/profesores/ypinzon/2016699
15
";
// overload << to actually print the list template <class T> ostream& operator<<(ostream& out, const LinearList<T>& x){ x.Output(out); return out; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
16
http://dis.unal.edu.co/profesores/ypinzon/2016699
17
File llist.out
Length = 0 IsEmpty = 1 List is 2 6 IsEmpty = 0 First element is 2 Length = 2 Deleted element is 2 List is 6
http://dis.unal.edu.co/profesores/ypinzon/2016699
18
The one who turns in his own, shall dig two graves. Chinese Proverb
Estructuras de Datos
Sesi on 5
Linked Representation
Yoan Pinz on, PhD Profesor Asociado Universidad Nacional de Colombia http://dis.unal.edu.co/profesores/ypinzon c 2009
Previous Session
Preliminaries Methods of Representing Data Formula-based Representation Linked Representation Indirect Addressing Representation Simulating Pointers Representation LinearList Data Structure Formula-based Representation
http://dis.unal.edu.co/profesores/ypinzon/2016699
Session 5
LinearList Data Structure Linked Representation
http://dis.unal.edu.co/profesores/ypinzon/2016699
Formula-based Representation: Uses a mathematical formula to determine 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 FE300
...
length 5
http://dis.unal.edu.co/profesores/ypinzon/2016699
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
http://dis.unal.edu.co/profesores/ypinzon/2016699
first
9
http://dis.unal.edu.co/profesores/ypinzon/2016699
1 2 3 4 5 6 7 8
template <class T> class ChainNode{ friend Chain<T>; private: T data; ChainNode<T> *link; };
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
template<class T> class Chain{ public: Chain(){first = 0;} Chain(); bool IsEmpty() const {return first == 0;} int Length() const; bool Find(int k, T& x) const; int Search(const T& x) const; Chain<T>& Delete(int k, T& x); Chain<T>& Insert(int k, const T& x); void Output(ostream& out) const; private: ChainNode<T> *first; // pointer to first node };
http://dis.unal.edu.co/profesores/ypinzon/2016699
An instance of this class (Chain L of integers) with lenght=5 will look like this:
first
L
Link Field Data Field
9
FE30
first FE30
5
FE45 link FA10 data FA10 link FF26 data
http://dis.unal.edu.co/profesores/ypinzon/2016699
Destructor
template<class T> Chain<T>::Chain() { // Chain destructor. Delete all nodes in chain. ChainNode<T> *next; // next node while (first){ next = first->link; delete first; first = next; } }
http://dis.unal.edu.co/profesores/ypinzon/2016699
Length
template<class T> int Chain<T>::Length() const { // Return the number of elements in the chain. ChainNode<T> *current = first; int len = 0; while (current){ len++; current = current->link; } return len; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
Find
template<class T> bool Chain<T>::Find(int k, T& x) const { // Set x to the kth element in the chain. // Return false if no kth; return true otherwise. if (k < 1) return false; ChainNode<T> *current = first; int index = 1; // index of current while (index < k && current){ current = current->link; index++; } if (current){ x = current->data; return true; } return false; // no kth element }
10
Search
template<class T> int Chain<T>::Search(const T& x) const { // Locate x. Return position of x if found. // Return 0 if x not in the chain. ChainNode<T> *current = first; int index = 1; // index of current while (current && current->data != x){ current = current->link; index++; } if (current) return index; return 0; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
11
Outputting a Chain
template<class T> void Chain<T>::Output(ostream& out) const { //Insert the chain elements into the stream out. ChainNode<T> *current; for (current=first; current; current=current->link) out << current->data << " "; } // overload << template <class T> ostream& operator<<(ostream& out, const Chain<T>& x){ x.Output(out); return out; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
12
first
link data
1
...
k-1 k k+1
...
n
(a) Before
first
link data
1
...
k-1 k
...
n+1
(b) After
Time Complexity : (k)
http://dis.unal.edu.co/profesores/ypinzon/2016699
13
Delete
template<class T> Chain<T>& Chain<T>::Delete(int k, T& x) { // Set x to the kth element and delete it. // Throw OutOfBounds exception if no kth element. if (k < 1 || !first) throw OutOfBounds(); // no kth // p will eventually point to kth node ChainNode<T> *p = first; // move p to kth & remove from chain if (k == 1) // p already at kth first = first->link; // remove else { // use q to get to k-1st ChainNode<T> *q = first; for (int index = 1; index < k - 1 && q; index++) q = q->link; if (!q || !q->link) throw OutOfBounds(); // no kth p = q->link; // kth q->link = p->link; // remove from chain } // save kth element and free node p x = p->data; delete p; return *this; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
14
link data
New Node
(a) Before
first ...
2 3 4 n+1
link data
(b) After
http://dis.unal.edu.co/profesores/ypinzon/2016699
15
If k=0
first
1
...
k k+1
...
n
link data
New Node
(a) Before
first
1
...
k k+2
...
n+1
link data
k+1
(b) After
http://dis.unal.edu.co/profesores/ypinzon/2016699
16
Insert
template<class T> Chain<T>& Chain<T>::Insert(int k, const T& x) { // Insert x after the kth element. Throw OutOfBounds exception if no kth element. // Pass NoMem exception if inadequate space. if (k < 0) throw OutOfBounds(); // p will eventually point to kth node ChainNode<T> *p = first; for (int index = 1; index < k && p; index++) p = p->link; // move p to kth if (k > 0 && !p) throw OutOfBounds(); // no kth // insert ChainNode<T> *y = new ChainNode<T>; y->data = x; if (k){ // insert after p y->link = p->link; p->link = y; } else{ // insert as first element y->link = first; first = y; } return *this; }
17
http://dis.unal.edu.co/profesores/ypinzon/2016699
18
File chain.out:
Length = 0 IsEmpty = 1 List is 2 6 IsEmpty = 0 First element is 2 Length = 2 Deleted element is 2 List is 6
http://dis.unal.edu.co/profesores/ypinzon/2016699
19
http://dis.unal.edu.co/profesores/ypinzon/2016699
20
Inserting/Deleting elements in an array based implementation requires the movement of other elements in the array (average insertion/deletion time is proportional to the length of the list) Inseting/Deleting elements in a linked implementation does not require the movement of other elements in the array, however the appropriate position has to be found (which on average is proportional to the length of the list)
If most of the activity is on inserting/deleting elements, there is little dierence in performance (theoretically), although arrays may require more time if the list length exceeds the bounds of the array. If most of the activity is on querying the list by their position, then the array-based implementation will have better performance.
http://dis.unal.edu.co/profesores/ypinzon/2016699
21
He who cannot agree with his enemies is controlled by them. Chinese Proverb
Estructuras de Datos
Sesi on 6
Stack Data Structure
Yoan Pinz on, PhD Profesor Asociado Universidad Nacional de Colombia http://dis.unal.edu.co/profesores/ypinzon c 2009
Previous Session
LinearList Data Structure Linked Representation
http://dis.unal.edu.co/profesores/ypinzon/2016699
Session 6
Stack Data Structure
Formula-based Representation Implementation using Inheritance Customised Implementation Linked Representation Implementation using Inheritance Customised Implementation Applications Parentheses Matching Switchbox Routing
http://dis.unal.edu.co/profesores/ypinzon/2016699
top
bottom
2 3
e e e
1
... ei
... en- en
1
e e e
1
... ei
... en- en
1
insertions deletions
In other words, a stack is a LIFO (last-in-rst out) list. Lists of this type appear frequently in computing.
http://dis.unal.edu.co/profesores/ypinzon/2016699
http://dis.unal.edu.co/profesores/ypinzon/2016699
Stack is a specialized or restricted version of a more general data object linear list. Every instance of the data object stack is also an instance of the data object linear list. Moreover, all the stack operations can be performed as linear list operations. As a result of these observations, we will dened the stack class as a class which inherit all the data member and function from the linear list class. We will also use two methods of representation. namely, formulabased and linked representation.
http://dis.unal.edu.co/profesores/ypinzon/2016699
http://dis.unal.edu.co/profesores/ypinzon/2016699
Basic design decision: designate the left end of the list as the bottom and the right end as the top
http://dis.unal.edu.co/profesores/ypinzon/2016699
Class Denition
template<class T> class Stack : private LinearList<T> { // LIFO objects public: Stack(int MaxStackSize = 10) : LinearList<T> (MaxStackSize) {} bool IsEmpty() const {return LinearList<T>::IsEmpty();} bool IsFull() const {return (Length() == GetMaxSize());} T Top() const {if (IsEmpty()) throw OutOfBounds(); T x; Find(Length(), x); return x;} Stack<T>& Add(const T& x) {Insert(Length(), x); return *this;} Stack<T>& Delete(T& x) {LinearList<T>::Delete(Length(), x); return *this;} }; template<class T> class LinearList{ public: // ... protected: int GetMaxSize() const {return MaxSize;} private: // ... };
http://dis.unal.edu.co/profesores/ypinzon/2016699
Complexity of Operations
Constructor
: : : : :
Destructor
Other operations
http://dis.unal.edu.co/profesores/ypinzon/2016699
http://dis.unal.edu.co/profesores/ypinzon/2016699
10
Constructor, Top
template<class T> Stack<T>::Stack(int MaxStackSize) { // Stack constructor. MaxTop = MaxStackSize - 1; stack = new T[MaxStackSize]; top = -1; }
template<class T> T Stack<T>::Top() const { // Return top element. if (IsEmpty()) throw OutOfBounds(); // Top fails else return stack[top]; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
11
Add, Delete
template<class T> Stack<T>& Stack<T>::Add(const T& x) { // Add x to stack. if (IsFull()) throw NoMem(); // add fails stack[++top] = x; return *this; }
template<class T> Stack<T>& Stack<T>::Delete(T& x) { // Delete top element and put in x. if (IsEmpty()) throw OutOfBounds(); // delete fails x = stack[top--]; return *this; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
12
Complexity of Operations
Constructor
: : : : :
Destructor
Other operations
http://dis.unal.edu.co/profesores/ypinzon/2016699
13
In both cases, we have to decide which end of the chain will be the top of the stack and which the bottom.
http://dis.unal.edu.co/profesores/ypinzon/2016699
14
http://dis.unal.edu.co/profesores/ypinzon/2016699
15
Complexity of Operations
: : :
http://dis.unal.edu.co/profesores/ypinzon/2016699
16
http://dis.unal.edu.co/profesores/ypinzon/2016699
17
Destructor, IsFull
template<class T> LinkedStack<T>::LinkedStack() { // Stack destructor.. Node<T> *next; while (top){ next = top->link; delete top; top = next; } } template<class T> bool LinkedStack<T>::IsFull() const { // Is the stack full? try { Node<T> *p = new Node<T>; delete p; return false; } catch (NoMem) {return true;} }
http://dis.unal.edu.co/profesores/ypinzon/2016699
18
Top, Add
template<class T> T LinkedStack<T>::Top() const { // Return top element. if (IsEmpty()) throw OutOfBounds(); return top->data; }
template<class T> LinkedStack<T>& LinkedStack<T>::Add(const T& x) { // Add x to stack. Node<T> *p = new Node<T>; p->data = x; p->link = top; top = p; return *this; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
19
Delete
template<class T> LinkedStack<T>& LinkedStack<T>::Delete(T& x) { // Delete top element and put it in x. if (IsEmpty()) throw OutOfBounds(); x = top->data; Node<T> *p = top; top = top->link; delete p; return *this; }
Time Complexity of Operations Constructor Destructor Other operations : : : (1) (n) (1)
http://dis.unal.edu.co/profesores/ypinzon/2016699
20
Stack Application
Parentheses Matching
http://dis.unal.edu.co/profesores/ypinzon/2016699
21
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
http://dis.unal.edu.co/profesores/ypinzon/2016699
22
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
- h ) )
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
( ( ( a + b ) * c + d * e ) / (
f + g )
http://dis.unal.edu.co/profesores/ypinzon/2016699
23
Parentheses Matching
Implementation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
void PrintMatchedPairs(char *expr){ Stack<int> s(MaxLength); int j, length = strlen(expr); // scan expression expr for ( and ) for (int i = 1; i <= length; i++){ if (expr[i - 1] == () s.Add(i); else if (expr[i - 1] == )) try { s.Delete(j); // unstack match cout << j << << i << endl; } catch (OutOfBounds) { cout << "No match for right parenthesis" << " at " << i << endl; } } // remaining ( in stack are unmatched while (!s.IsEmpty()){ s.Delete(j); cout << "No match for left parenthesis at " << j << endl; } }
http://dis.unal.edu.co/profesores/ypinzon/2016699
24
File paren.cc:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
const int MaxLength = 100; // max expression length void PrintMatchedPairs(char *expr){ // Presented in previous page } void main(void){ char expr[MaxLength]; cout << "Type an expression of length at most " << MaxLength << endl; cin.getline(expr, MaxLength); cout <<"The pairs of matching parentheses in" << endl; puts(expr); cout << "are" << endl; PrintMatchedPairs(expr); }
http://dis.unal.edu.co/profesores/ypinzon/2016699
25
Stack Application
Switchbox Routing
The switchbox routing problem arises in the fabrication of computer chips, where certain components need to be connected to other components.
1 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 2 3 4 5 6 7 8 9 10 11 12 13 14
Routing region
15 16 17 18 19 20
http://dis.unal.edu.co/profesores/ypinzon/2016699
26
Switchbox Routing
Example
3 4 5 6 1 2 7 8 9 10
Net={ 1, 2, 3, 4, 4, 3, 2, 5, 5, 1 }
1 10 2 3 4
Routable !
9 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 10 2 3 4
9 8
5 7 6
NOT Routable!
http://dis.unal.edu.co/profesores/ypinzon/2016699
27
Switchbox Routing
Implementation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
bool CheckBox(int net[], int n) { // Determine whether the switch box is routable. Stack<int> *s = new Stack<int> (n); for (int i = 0; i < n; i++) // scan nets clockwise if (!s->IsEmpty()) { // check with top net if (net[i] == net[s->Top()]) { // net[i] routable, delete from stack int x; s->Delete(x); } else s->Add(i); } else s->Add(i); // any unrouted nets left? if (s->IsEmpty()) { // no nets remain delete s; cout << "Switch box is routable" << endl; return true; } delete s; cout << "Switch box is not routable" << endl; return false; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
28
File switch.cc:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
#include <iostream.h> #include "stack.h" bool CheckBox(int net[], int n){ // Presented in previous page } void main(void){ int *net, n; cout << "Type number of pins in switch box " << endl; cin >> n; try{ net = new int [n]; cout << "Type net numbers for pins 1 through " << n << endl; for (int i = 0; i<n; i++) cin >> net[i]; CheckBox(net, n); } catch (NoMem){ cout << "Insufficient memory" << endl; } }
http://dis.unal.edu.co/profesores/ypinzon/2016699
29
A wise man makes his own decisions, an ignorant man follows the public opinion. Chinese Proverb
Estructuras de Datos
Sesi on 7
Queue Data Structure
Yoan Pinz on, PhD Profesor Asociado Universidad Nacional de Colombia http://dis.unal.edu.co/profesores/ypinzon c 2009
Previous Session
Stack Data Structure
Formula-based Representation Implementation using Inheritance Customised Implementation Linked Representation Implementation using Inheritance Customised Implementation Applications Parentheses Matching Switchbox Routing
http://dis.unal.edu.co/profesores/ypinzon/2016699
Session 7
Queue Data Structure Formula-based Representation Linked Representation Applications Image-Component Labeling Lees Wire Router
http://dis.unal.edu.co/profesores/ypinzon/2016699
front
rear
2 3
e e e
1
... ei
... en- en
1
deletions
insertions
http://dis.unal.edu.co/profesores/ypinzon/2016699
http://dis.unal.edu.co/profesores/ypinzon/2016699
front
rear
front rear
front
rear
F A T
[0] [1] [2]
...
A T
[0] [1]
...
A T E
[0] [1] [2]
...
Deletion:
http://dis.unal.edu.co/profesores/ypinzon/2016699
front
rear
front rear
front
rear
F A T
[0] [1] [2]
...
[0]
A T
[1] [2]
...
[0]
A T E
[1] [2] [3]
...
Empty queue: rear < front front = location(1); rear = location(n) Deletions & Insertions: O (1) time
http://dis.unal.edu.co/profesores/ypinzon/2016699
rear
rear
rear
T A F
front front
T A A
T E
front
front points one position before the position of the rst element in the
queue.
Empty queue: front = rear (initially front=rear=0) Full queue: (rear+1)%MaxSize = front
Class Denition
template<class T> class Queue { // FIFO objects public: Queue(int MaxQueueSize = 10); Queue() {delete [] queue;} bool IsEmpty() const {return front == rear;} bool IsFull() const {return (((rear + 1) % MaxSize == front) ? 1 : 0);} T First() const; // return front element T Last() const; // return last element Queue<T>& Add(const T& x); Queue<T>& Delete(T& x); private: int front; // one counterclockwise from first int rear; // last element int MaxSize; // size of array queue T *queue; // element array };
http://dis.unal.edu.co/profesores/ypinzon/2016699
Constructor, First
template<class T> Queue<T>::Queue(int MaxQueueSize) { // Create an empty queue whose capacity // is MaxQueueSize. MaxSize = MaxQueueSize + 1; queue = new T[MaxSize]; front = rear = 0; } template<class T> T Queue<T>::First() const { // Return first element of queue. Throw // OutOfBounds exception if the queue is empty. if (IsEmpty()) throw OutOfBounds(); return queue[(front + 1) % MaxSize]; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
Last, Add
template<class T> T Queue<T>::Last() const { // Return last element of queue. Throw // OutOfBounds exception if the queue is empty. if (IsEmpty()) throw OutOfBounds(); return queue[rear]; } template<class T> Queue<T>& Queue<T>::Add(const T& x) { // Add x to the rear of the queue. Throw // NoMem exception if the queue is full. if (IsFull()) throw NoMem(); rear = (rear + 1) % MaxSize; queue[rear] = x; return *this; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
10
Delete
template<class T> Queue<T>& Queue<T>::Delete(T& x) { // Delete first element and put in x. Throw // OutOfBounds exception if the queue is empty. if (IsEmpty()) throw OutOfBounds(); front = (front + 1) % MaxSize; x = queue[front]; return *this; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
11
...
front
rear
...
...
front
rear
front
rear
(a) Addition
Empty queue: front = 0 Deletions & Insertions:
(b) Deletion
O(1) time
http://dis.unal.edu.co/profesores/ypinzon/2016699
12
Class Denition
template<class T> class LinkedQueue{ // FIFO objects public: LinkedQueue() {front = rear = 0;} // constructor LinkedQueue(); // destructor bool IsEmpty() const {return ((front) ? false : true);} bool IsFull() const; T First() const; // return first element T Last() const; // return last element LinkedQueue<T>& Add(const T& x); LinkedQueue<T>& Delete(T& x); private: Node<T> *front; // pointer to first node Node<T> *rear; // pointer to last node };
http://dis.unal.edu.co/profesores/ypinzon/2016699
13
Destructor, IsFull
template<class T> LinkedQueue<T>::LinkedQueue() { // Queue destructor. Delete all nodes. Node<T> *next; while (front){ next = front->link; delete front; front = next; } } [lineskip=-0.02pt] template<class T> bool LinkedQueue<T>::IsFull() const { // Is the queue full? Node<T> *p; try { p = new Node<T>; delete p; return false; } catch (NoMem) {return true;} }
http://dis.unal.edu.co/profesores/ypinzon/2016699
14
First, Last
template<class T> T LinkedQueue<T>::First() const { // Return first element of queue. Throw // OutOfBounds exception if the queue is empty. if (IsEmpty()) throw OutOfBounds(); return front->data; } template<class T> T LinkedQueue<T>::Last() const { // Return last element of queue. Throw // OutOfBounds exception if the queue is empty. if (IsEmpty()) throw OutOfBounds(); return rear->data; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
15
Add, Delete
template<class T> LinkedQueue<T>& LinkedQueue<T>::Add(const T& x) { // Add x to rear of queue. Create node for new element Node<T> *p = new Node<T>; p->data = x; p->link = 0; // add new node to rear of queue if (front) rear->link = p; // queue not empty else front = p; // queue empty rear = p; return *this; } template<class T> LinkedQueue<T>& LinkedQueue<T>::Delete(T& x) { // Delete first element and put it in x. Throw // OutOfBounds exception if the queue is empty. if (IsEmpty()) throw OutOfBounds(); x = front->data; Node<T> *p = front; front = front->link; delete p; return *this; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
16
Queue Application
Image-Component Labelling
1 1 1
2 2 2
(a) Input
1 1 1 1 1 1 1
1 1 1 1
(b) Output
1 1 1 1 4 4 4 4 4 4 4
3 3 3 3
5 5 5 5
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.
http://dis.unal.edu.co/profesores/ypinzon/2016699
17
Image-Component Labelling
Implementation
1 2 3 4 5
class Position { friend void Label(); private: int row, col; }; // globals int **pixel, m; void Label(){ // initialize wall of 0 pixels for (int i = 0; i <= m+1; i++) { pixel[0][i] = pixel[m+1][i] = 0; // bottom & top pixel[i][0] = pixel[i][m+1] = 0; // left & right } // initialize offsets Position offset[4]; offset[0].row = 0; offset[0].col = 1; // right offset[1].row = 1; offset[1].col = 0; // down offset[2].row = 0; offset[2].col = -1; // left offset[3].row = -1; offset[3].col = 0; // up int NumOfNbrs = 4; // neighbors of a pixel position
6 7
8 9 10 11 12 13 14 15 16 17 18 19 20 21
http://dis.unal.edu.co/profesores/ypinzon/2016699
18
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
LinkedQueue<Position> Q; int id = 1; // component id Position here, nbr; // scan all pixels labeling components for (int r = 1; r <= m; r++) // row r of image for (int c = 1; c <= m; c++) // column c if (pixel[r][c] == 1) {// new component} pixel[r][c] = ++id; // get next id here.row = r; here.col = c; do {// find rest of component for (int i = 0; i < NumOfNbrs; i++) { // check all neighbors of here nbr.row = here.row + offset[i].row; nbr.col = here.col + offset[i].col; if (pixel[nbr.row][nbr.col] == 1) { pixel[nbr.row][nbr.col] = id; Q.Add(nbr);}} // end of if and for // any unexplored pixels in component? if (Q.IsEmpty()) break; Q.Delete(here); // a component pixel } while(true); } // end of if, for c, and for r }
http://dis.unal.edu.co/profesores/ypinzon/2016699
19
File image.cc:
// label image components #include <iostream.h> #include "lqueue.h" #include "make2db.h" void InputImage(); void Label(); void OutputImage(); void main(void){ InputImage(); cout << "The input image is" << endl; OutputImage(); Label(); cout << "The labeled image is" << endl; OutputImage(); }
http://dis.unal.edu.co/profesores/ypinzon/2016699
20
$ $ $ 7 0 0 0 0 1 1 1
g++ -o image image.cc ./image < image.dat > image.out cat image.dat 0 0 0 0 0 1 1 1 1 0 0 0 1 1 0 1 0 1 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
http://dis.unal.edu.co/profesores/ypinzon/2016699
21
File image.out:
Enter image size The input image is 0010000 0011000 0000100 0001100 1000100 1110000 1110000 The labeled image is 0020000 0022000 0000300 0003300 4000300 4440000 4440000
File image.dat:
7 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 1 0 0 0 1 1 0 1 0 1 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
http://dis.unal.edu.co/profesores/ypinzon/2016699
22
Queue Application
Lees Wire Router
S T
5 6 2 4 1 3 2 1 S 3 2 1 6 5 6 3 4 5 6 2 1 2 3 3 T 4 5 6 5 6 2 4 1 3 2 1 S 3 2 1 6 5 6 3 4 5 6 2 1 2 3 3 T 4 5 6
(a) Filing
(b) Retrace
http://dis.unal.edu.co/profesores/ypinzon/2016699
23
Implementation class Position { friend void InputGrid(Position&, Position&); friend void OutputPath(int, Position *); friend bool FindPath(Position, Position, int&, Position * &); private: int row, col; }; int **grid, m; bool FindPath(Position start, Position finish, int& PathLen, Position * &path) { // Find a path from start to finish. // Return true if successful, false if impossible. if ((start.row == finish.row) && (start.col == finish.col)) {PathLen = 0; return true;} // start = finish // initialize wall of blocks around grid for (int i = 0; i <= m+1; i++) { grid[0][i] = grid[m+1][i] = 1; // bottom & top grid[i][0] = grid[i][m+1] = 1; // left & right } // initialize offsets Position offset[4]; offset[0].row = 0; offset[0].col = 1; // right offset[1].row = 1; offset[1].col = 0; // down offset[2].row = 0; offset[2].col = -1; // left offset[3].row = -1; offset[3].col = 0; // up
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
http://dis.unal.edu.co/profesores/ypinzon/2016699
24
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
int NumOfNbrs = 4; // neighbors of a grid position Position here, nbr; here.row = start.row; here.col = start.col; grid[start.row][start.col] = 2; // block // label reachable grid positions LinkedQueue<Position> Q; do {// label neighbors of here for (int 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) { // unlabeled nbr, label it grid[nbr.row][nbr.col] = grid[here.row][here.col] + 1; if ((nbr.row == finish.row) && (nbr.col == finish.col)) break; // done Q.Add(nbr);} // end of if } // end of for // have we reached finish? if ((nbr.row == finish.row) && (nbr.col == finish.col)) break; // done // finish not reached, can we move to a nbr? if (Q.IsEmpty()) return false; // no path Q.Delete(here); // get next position } while(true);
http://dis.unal.edu.co/profesores/ypinzon/2016699
25
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
// construct path PathLen = grid[finish.row][finish.col] - 2; path = new Position [PathLen]; // trace backwards from finish here = finish; for (int j = PathLen-1; j >= 0; j--) { path[j] = here; // find predecessor position for (int 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 = nbr; // move to predecessor } return true; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
26
File wire.cc:
// Lees wire router #include #include #include #include <iostream.h> <stdlib.h> "lqueue.h" "make2db.h"
void InputGrid(Position &start, Position &finish); bool FindPath(Position start, Position finish, int& PathLen, Position * &path); void main(void){ Position s,f, *p; int l; InputGrid(s,f); if (FindPath(s,f,l,p)) OutputPath(l,p); else cout << "No path" << endl; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
27
$ $ $ 7 3 4 0 0 0 0 1 1 1
g++ -o wire wire.cc ./wire < wire.dat > wire.out cat wire.dat 2 6 0 0 0 0 0 1 1
1 1 0 0 0 1 1
0 1 0 1 0 0 0
0 0 1 1 1 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
http://dis.unal.edu.co/profesores/ypinzon/2016699
28
1 1 0 0 0 1 1
0 1 0 1 0 0 0
0 0 1 1 1 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
http://dis.unal.edu.co/profesores/ypinzon/2016699
29
Behind every able man, there are always other able men. Chinese Proverb
Estructuras de Datos
Sesi on 8
Tree Data Structure
Yoan Pinz on, PhD Profesor Asociado Universidad Nacional de Colombia http://dis.unal.edu.co/profesores/ypinzon c 2009
Previous Session
Queue Data Structure Formula-based Representation Linked Representation Applications Image-Component Labeling Lees Wire Router
http://dis.unal.edu.co/profesores/ypinzon/2016699
Session 8
Tree Data Structure Terminology Binary Trees Properties Formula-based Representation Linked Representation Traversals An Application Binary Search Trees
http://dis.unal.edu.co/profesores/ypinzon/2016699
http://dis.unal.edu.co/profesores/ypinzon/2016699
Terminology
A tree is a nite nonempty set of elements
root
level 1
v
Elements with no children are called leaves.
y
Level: root=level 1; children=level 2,3, ...
subtree subtree
http://dis.unal.edu.co/profesores/ypinzon/2016699
Binary Trees
A binary tree is a tree (possible empty) in which every element has degree 2, except for the leaves.
http://dis.unal.edu.co/profesores/ypinzon/2016699
P2:
Proof: By induction on i. Basis: i = 1; number of elements = 1 = 20 Ind. Hypothesis: i = k; number of elements at level k 2k1. Look at level i = k + 1 (number of elements at level k + 1) 2(number of elements at level k) 2 2k1 = 2k .
http://dis.unal.edu.co/profesores/ypinzon/2016699
P3: A binary tree of height h, h > 0, has at least h and at most h 2 1 elements. Poof: Let n be the number of elements. must be 1 elements at each level, hence, n h. Now, if h = 0, then n = 0 = 20 1. For h > 0, we have by P2 that
h
n
i=1
2i1 = 2h 1
P4: Let h be the height of an n-elements binary tree, n 0. Then, log2(n + 1) h n Proof: must be 1 element at each level, hence, h n. P3 n 2h 1 2h n + 1 h log2(n + 1). Since h is an integer, we have that h log2(n + 1).
http://dis.unal.edu.co/profesores/ypinzon/2016699
Full binary tree: A binary tree of height h is full if contains exactly 2h 1 elements.
2 4 5 6
3
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 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 1.
http://dis.unal.edu.co/profesores/ypinzon/2016699
P5: Let i, 1 i n, 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 i/2. (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.
http://dis.unal.edu.co/profesores/ypinzon/2016699
Uses P5
1
A
2
B
5
C
7
A B C
Note: An nelement binary tree may require an array of size 2n 1 for its representation. Can be a waste of space.
http://dis.unal.edu.co/profesores/ypinzon/2016699
10
The most popular way to represent a binary tree is by using links or pointers. Each node is represented by three elds:
root LeftChild
data LeftChild RightChild
RightChild data
data
data
http://dis.unal.edu.co/profesores/ypinzon/2016699
11
Preorder: Visit-Left-Right (VLR) Inorder: Left-Visit-Right (LVR) Postorder: Left-Right-Visit (LRV) Level order
Example:
A B D
Preorder: ABDECF Inorder: DBEAFC
C E F
Postorder: DEBFCA Level order: ABCDEF
http://dis.unal.edu.co/profesores/ypinzon/2016699
12
http://dis.unal.edu.co/profesores/ypinzon/2016699
13
class BinaryTreeNode{ public: BinaryTreeNode() {LeftChild = RightChild = 0;} BinaryTreeNode(const T& e) {data = e; LeftChild = RightChild = 0;} BinaryTreeNode(const T& e, BinaryTreeNode *l, BinaryTreeNode *r) {data = e; LeftChild = l; RightChild = r;} private: T data; BinaryTreeNode<T> *LeftChild, // left subtree *RightChild; // right subtree };
http://dis.unal.edu.co/profesores/ypinzon/2016699
14
http://dis.unal.edu.co/profesores/ypinzon/2016699
15
Root, MakeTree
BinaryTree<T>::Root(T& x) const { // Return root data in x. Return false if no root. if (root){ x = root->data; return true; } else return false; // no root } void BinaryTree<T>::MakeTree(const T& element, BinaryTree<T>& left, BinaryTree<T>& right) { // Combine left, right, and element to make new tree. // left, right, and this must be different trees. // create combined tree root = new BinaryTreeNode<T>(element, left.root, right.root); // deny access from trees left and right left.root = right.root = 0; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
16
BreakTree
void BinaryTree<T>::BreakTree(T& element, BinaryTree<T>& left, BinaryTree<T>& right) { // left, right, and this must be different trees. // check if empty if (!root) throw BadInput(); // tree empty // break the tree element = root->data; left.root = root->LeftChild; right.root = root->RightChild; delete root; root = 0; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
17
PreOrder, InOrder
void BinaryTree<T>::PreOrder(void(*Visit)(BinaryTreeNode<T> *u), BinaryTreeNode<T> *t) { // Preorder traversal. if (t){ Visit(t); PreOrder(Visit, t->LeftChild); PreOrder(Visit, t->RightChild); } } void BinaryTree<T>::InOrder(void(*Visit)(BinaryTreeNode<T> *u), BinaryTreeNode<T> *t) { // Inorder traversal. if (t){ InOrder(Visit, t->LeftChild); Visit(t); InOrder(Visit, t->RightChild); } }
http://dis.unal.edu.co/profesores/ypinzon/2016699
18
PostOrder, LevelOrder
template <class T> void BinaryTree<T>::PostOrder(void(*Visit)(BinaryTreeNode<T> *u), BinaryTreeNode<T> *t) { // Postorder traversal. if (t){ PostOrder(Visit, t->LeftChild); PostOrder(Visit, t->RightChild); Visit(t); } } template <class T> void BinaryTree<T>::LevelOrder(void(*Visit)(BinaryTreeNode<T> *u)) { // Level-order traversal. LinkedQueue<BinaryTreeNode<T>*> Q; BinaryTreeNode<T> *t; t = root; while (t) { Visit(t); if (t->LeftChild) Q.Add(t->LeftChild); if (t->RightChild) Q.Add(t->RightChild); try {Q.Delete(t);} catch (OutOfBounds) {return;} } }
http://dis.unal.edu.co/profesores/ypinzon/2016699
19
Visit, Height
void Visit(BinaryTreeNode<T> *x) {// Visit node *x, just output data field. cout << x->data << ; } int BinaryTree<T>::Height(BinaryTreeNode<T> *t) const { // Return height of tree *t. if (!t) return 0; // empty tree int hl = Height(t->LeftChild); // height of left int hr = Height(t->RightChild); // height of right if (hl > hr) return ++hl; else return ++hr; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
20
File binary.cc
#include <iostream.h> #include "binary.h" int count = 0; BinaryTree<int> a,x,y,z; template<class T> void ct(BinaryTreeNode<T> *t) {count++;} void main(void){ y.MakeTree(1,a,a); z.MakeTree(2,a,a); x.MakeTree(3,y,z); y.MakeTree(4,x,a); cout << "Preorder sequence is "; y.PreOutput(); cout << "Inorder sequence is "; y.InOutput(); cout << "Postorder sequence is "; y.PostOutput(); y.PreOrder(ct); cout << "Count of nodes is " << count << endl; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
21
$ g++ -o binary binary.cc $ ./binary Preorder sequence is 4 3 1 2 Inorder sequence is 1 3 2 4 Postorder sequence is 1 2 3 4 Count of nodes is 4
http://dis.unal.edu.co/profesores/ypinzon/2016699
22
+ +
(a*b)+(c/d)
* a b c
/ d
*
(((a-b)*c)+d)
d c
a b
Scan left-to-right Put operator to a stack Apply the encountered operator to the operands in the stack and delete them from the stack.
http://dis.unal.edu.co/profesores/ypinzon/2016699
23
20
16 6 2
10 12
43 18 35 45
46 48 50
An in-order traversal produces the elements in sorted order: 2, 6, 10, 12, 16, 18, 20, 35, 43, 45, 46, 48, 50.
http://dis.unal.edu.co/profesores/ypinzon/2016699
24
Searching for an element with key k Start at root. If k equals the key of the root, then stop. If the key is less (greater) than the key of the root, then search the left (right) subtree. Time Complexity: O(h) Inserting an element with key k Search if there is an element with the same key. If the search is unsuccessful, then insert the element at the point where the search was terminated. Time Complexity: O(h)
http://dis.unal.edu.co/profesores/ypinzon/2016699
25
Deleting an element with key k Search if there is an element e with the same key. If the search is successful, consider: e is a leaf delete this node. e has exactly one nonempty subtree If e is the root, then it is deleted and the root of its single subtree becomes the new root. Otherwise, change the pointer from the parent p(e) of e so that it points to the es only child, and delete e. e has exactly two nonempty subtrees replace this element either with the largest element in its left subtree, or with the smallest element in its right subtree. To nd the largest (smallest) element in the left (right) subtree simply follow the right-child (left-child) pointers from the root of the subtree until a node with null rightchild (left-child) pointer is reached. Time Complexity: O(h)
http://dis.unal.edu.co/profesores/ypinzon/2016699
26
Search
bool BSTree<E,K>::Search(const K& k, E &e) const { // Search for element that matches k. Pointer p starts at the root and // moves through the tree looking for an element with key k BinaryTreeNode<E> *p = root; while (p) // examine p->data if (k < p->data) p = p->LeftChild; else if (k > p->data) p = p->RightChild; else {e = p->data; return true;} // found element return false; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
27
Insert
template<class E, class K> BSTree<E,K>& BSTree<E,K>::Insert(const E& e) { // Insert e if not duplicate. BinaryTreeNode<E> *p = root, // search pointer *pp = 0; // parent of p // find place to insert while (p) {// examine p->data pp = p; // move p to a child if (e < p->data) p = p->LeftChild; else if (e > p->data) p = p->RightChild; else throw BadInput(); // duplicate } // get a node for e and attach to pp BinaryTreeNode<E> *r = new BinaryTreeNode<E> (e); if (root) {// tree not empty if (e < pp->data) pp->LeftChild = r; else pp->RightChild = r;} else // insertion into empty tree root = r; return *this; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
28
Delete
template<class E, class K> BSTree<E,K>& BSTree<E,K>::Delete(const K& k, E& e) { // Delete element with key k and put it in e. BinaryTreeNode<E> *p = root, *pp = 0; // parent of p while (p && p->data != k){// move to a child of p pp = p; if (k < p->data) p = p->LeftChild; else p = p->RightChild;} if (!p) throw BadInput(); // no element with key k e = p->data; // save element to delete // restructure tree if (p->LeftChild && p->RightChild) {// two children // find largest element in left subtree of p BinaryTreeNode<E> *s = p->LeftChild, *ps = p; while (s->RightChild) {ps = s; s = s->RightChild;} // move to larger element p->data = s->data; p = s; pp = ps;} BinaryTreeNode<E> *c; if (p->LeftChild) c = p->LeftChild; else c = p->RightChild; if (p == root) root = c; else {// is p left or right child of pp? if (p == pp->LeftChild) pp->LeftChild = c; else pp->RightChild = c;} delete p; return *this; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
29
If you are planning for a year, sow rice; if you are planning for a decade, plant trees; if you are planning for a lifetime, teach people. Chinese Proverb
Estructuras de Datos
Sesi on 9
Priority Queue Data Structure
Yoan Pinz on, PhD Profesor Asociado Universidad Nacional de Colombia http://dis.unal.edu.co/profesores/ypinzon c 2009
Previous Session
Tree Data Structure Terminology Binary Trees Properties Formula-based Representation Linked Representation Traversals An Application Binary Search Trees
http://dis.unal.edu.co/profesores/ypinzon/2016699
Session 9
Priority Queue Data Structure Max Priority Queues Heaps An Application
http://dis.unal.edu.co/profesores/ypinzon/2016699
creasing (decreasing) order of priority rather than in the order in which they arrived in the queue.
http://dis.unal.edu.co/profesores/ypinzon/2016699
AbstractDataType MaxPriorityQueue { instances: nite collection of elements, each with a priority. operations: Create(): creates an empty priority queue Size(): returns the number of elements in the queue Max(): returns the element of maximum priority Insert(x): inserts x in the queue DeleteMax(x): deletes the element of maximum priority and returns it to x.
http://dis.unal.edu.co/profesores/ypinzon/2016699
Linear list.
Heap.
http://dis.unal.edu.co/profesores/ypinzon/2016699
Heaps
Max tree (min tree): is a tree in which the value in a each node is
14 12 10 8 6 7 10 7 8
2 4 6
(a) MaxHeap
(b) MinHeap
http://dis.unal.edu.co/profesores/ypinzon/2016699
Representation of a Heap
http://dis.unal.edu.co/profesores/ypinzon/2016699
Insertion
http://dis.unal.edu.co/profesores/ypinzon/2016699
Example: Insert 5.
20 15 14 10 2 14 15 10
20 2 5 14 15 10
20 5 2
http://dis.unal.edu.co/profesores/ypinzon/2016699
20 15 14 10 2 5 14 15 10
20 5 2 21 14 15 10
20 21 2 5
21 15 14 10 2 20 5
http://dis.unal.edu.co/profesores/ypinzon/2016699
10
Deletion
Delete the rightmost leaf at the highest level and put it in the root.
following the path determined by the child having the largest value.
http://dis.unal.edu.co/profesores/ypinzon/2016699
11
21 15 14 10 2 20 14 15 10 2 20 14 15 10
2 20
20 15 14 10 2
http://dis.unal.edu.co/profesores/ypinzon/2016699
12
20 15 14 10 2 14 15 10 2 14 15
10 2
15 14 10 2 14 10
15 2
http://dis.unal.edu.co/profesores/ypinzon/2016699
13
http://dis.unal.edu.co/profesores/ypinzon/2016699
14
template<class T> class MaxHeap{ public: MaxHeap(int MaxHeapSize = 10); MaxHeap() {delete [] heap;} int Size() const {return CurrentSize;} T Max() {if (CurrentSize == 0) throw OutOfBounds(); return heap[1];} MaxHeap<T>& Insert(const T& x); MaxHeap<T>& DeleteMax(T& x); void Initialize(T a[], int size, int ArraySize); void Deactivate() {heap = 0;} void Output() const; private: int CurrentSize; int MaxSize; T *heap; // element array };
http://dis.unal.edu.co/profesores/ypinzon/2016699
15
Constructor, Insert
template<class T> MaxHeap<T>::MaxHeap(int MaxHeapSize) { // Max heap constructor. MaxSize = MaxHeapSize; heap = new T[MaxSize+1]; CurrentSize = 0; } template<class T> MaxHeap<T>& MaxHeap<T>::Insert(const T& x) { // Insert x into the max heap. if (CurrentSize == MaxSize) throw NoMem(); // no space // find place for x, i starts at new leaf and moves up tree int i = ++CurrentSize; while (i != 1 && x > heap[i/2]){ // cannot put x in heap[i] heap[i] = heap[i/2]; // move element down i /= 2; // move to parent } heap[i] = x; return *this; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
16
Delete
template<class T> MaxHeap<T>& MaxHeap<T>::DeleteMax(T& x) { // Set x to max element and delete // max element from heap. Check if heap is empty if (CurrentSize == 0) throw OutOfBounds(); // empty x = heap[1]; // max element T y = heap[CurrentSize--]; // last element // find place for y starting at root int i = 1, // current node of heap ci = 2; // child of i while (ci <= CurrentSize){ // heap[ci] should be larger child of i if (ci < CurrentSize && heap[ci] < heap[ci+1]) ci++; // can we put y in heap[i]? if (y >= heap[ci]) break; // yes // no heap[i] = heap[ci]; // move child up i = ci; // move down a level ci *= 2; } heap[i] = y; return *this; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
17
Initialize
template<class T> void MaxHeap<T>::Initialize(T a[], int size, int ArraySize) { // Initialize max heap to array a. delete [] heap; heap = a; CurrentSize = size; MaxSize = ArraySize; // make into a max heap for (int i = CurrentSize/2; i >= 1; i--){ T y = heap[i]; // root of subtree // find place to put y int c = 2*i; // parent of c is target location for y while (c <= CurrentSize) { // heap[c] should be larger sibling if (c < CurrentSize && heap[c] < heap[c+1]) c++; // can we put y in heap[c/2]? if (y >= heap[c]) break; // yes // no heap[c/2] = heap[c]; // move child up c *= 2; // move down a level } heap[c/2] = y; } }
http://dis.unal.edu.co/profesores/ypinzon/2016699
18
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)
http://dis.unal.edu.co/profesores/ypinzon/2016699
19
#include <iostream.h> #include "maxheap.h" template <class T> void HeapSort(T a[], int n) { // create a max heap of the elements MaxHeap<T> H(1); H.Initialize(a,n,n); // extract one by one from the max heap T x; for (int i = n-1; i >= 1; i--) {H.DeleteMax(x); a[i+1] = x;} // save array a from heap destructor H.Deactivate(); } void main(void){ int a[11], i, n = 10; // initialize descending data for (i = 1; i <= 10; i++) a[i] = n - i + 1; HeapSort(a,10); // output sorted data for (i = 1; i <= n; i++) cout << a[i] << ; cout << endl; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
20
You cannot prevent the birds of sorrow from ying over your head, but you can prevent them from building nests in your hair. Chinese Proverb
Estructuras de Datos
Sesi on 10
Dictionary Data Structure
Yoan Pinz on, PhD Profesor Asociado Universidad Nacional de Colombia http://dis.unal.edu.co/profesores/ypinzon c 2009
Previous Session
Priority Queue Data Structure Max Priority Queues Heaps An Application
http://dis.unal.edu.co/profesores/ypinzon/2016699
Session 10
Dictionary Data Structure BST Representation Linear List Representation Skip List Representation Hash Table Representation
http://dis.unal.edu.co/profesores/ypinzon/2016699
Dictionary Structure
Dictionary: collection of elements, where each element has a eld called key, supporting the following operations:
Insert an element with a specic key values. Search the dictionary for an element with a specic key value. Delete an element with a specic key value.
http://dis.unal.edu.co/profesores/ypinzon/2016699
http://dis.unal.edu.co/profesores/ypinzon/2016699
A dictionary is maintained as a binary search tree, where the nodes eis are dictionary elements and all keys are distinct.
http://dis.unal.edu.co/profesores/ypinzon/2016699
A dictionary is maintained as an ordered linear list (e1, e2, . . .), where the eis are dictionary elements and their keys increase from left to right. Using the linked representation, the class denition for a dictionary looks as follow:
http://dis.unal.edu.co/profesores/ypinzon/2016699
http://dis.unal.edu.co/profesores/ypinzon/2016699
Search
template<class E, class K> bool SortedChain<E,K>::Search(const K& k, E& e) const { // Put element that matches k in e. // Return false if no match. SortedChainNode<E,K> *p = first; // search for match with k while (p && p->data < k) p = p->link; // verify match if (p && p->data == k) // yes, found match { e = p->data; return true; } return false; // no match }
http://dis.unal.edu.co/profesores/ypinzon/2016699
Delete
template<class E, class K> SortedChain<E,K>& SortedChain<E,K>::Delete(const K& k, E& e) { // Delete element that matches k. // Put deleted element in e. // Throw BadInput exception if no match. SortedChainNode<E,K> *p = first, *tp = 0; // trail p // search for match with k while (p && p->data < k) { tp = p; p = p->link; } // verify match if (p && p->data == k) { // found a match e = p->data; // save data // remove p from chain if (tp) tp->link = p->link; else first = p->link; // p is first node delete p; return *this; } throw BadInput(); // no match }
http://dis.unal.edu.co/profesores/ypinzon/2016699
Insert
template<class E, class K> SortedChain<E,K>& SortedChain<E,K>::Insert(const E& e) { // Insert e, throw an exception if no space. SortedChainNode<E,K> *p = first, *tp = 0; // trail p // move tp so that e can be inserted after tp while (p && p->data < e){ tp = p; p = p->link; } // setup a new node *q for e SortedChainNode<E,K> *q = new SortedChainNode<E,K>; q->data = e; // insert node just after tp q->link = p; if (tp) tp->link = q; else first = q; return *this; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
10
Searching for a given element in a dictionary of size n represented as a sorted chain may required up to n comparisons. Can we do better? Number of comparisons can be reduced to n/2+1 if we keep a pointer to the middle element: Compare rst the given element to the middle one. If it is smaller, look at the left half of the chain; otherwise, look at the right half. Apply this idea recursively to each half of the chain.
http://dis.unal.edu.co/profesores/ypinzon/2016699
11
In general we generate chains at various levels: Level 0 chain includes all n elements. Level 1 chain includes every second element. Level 2 chain includes every fourth element. Level i chain includes every 2i th element. An element is a level i element i it is in the chain for level 0 through i and it is not on the level i + 1 chain. The above data structure is called skip list.
head
tail
20
24
30
40
60
75
80
http://dis.unal.edu.co/profesores/ypinzon/2016699
12
When insertion and deletion occur, we cannot maintain the regular structure of a skip list without doing O(n) work. However, we can approximate this structure. Observation: there are n/2i level i element. Hence, when insertion occurs, the element level is i with probability 1/2i. In general, we can allow any probability to be used: the newly inserted element is assigned to level i with probability pi , for some 0 < p < 1. Number of chain levels is log1/p n + 1. Level i includes every 1/pth element of level i 1.
http://dis.unal.edu.co/profesores/ypinzon/2016699
13
1. First search to check that no element with value K is present. 2. During the search determine those pointers of elements at various levels that could break after the insertion. 3. Make the insertion by assigning a level to the new element. This assignment can be made using a random number generator.
http://dis.unal.edu.co/profesores/ypinzon/2016699
14
Example:
head 20 head 24 30 40 60 75 80
tail
20 head
24
30
40
60
75
80 tail
20
24
30
40
60
75
77
80
(c) 77 Inserted
http://dis.unal.edu.co/profesores/ypinzon/2016699
15
Deletion of an element with value K 1. First search to nd the element with value K . 2. During the search determine those pointers of elements at various levels that need to be updated after the deletion. 3. Let the element to be delete be at level i chain. Then, the pointers determined during step 2 and belong to levels i to 0 should made to point to element after the one to be deleted.
http://dis.unal.edu.co/profesores/ypinzon/2016699
16
Assigning Levels Observation: in a regular skip list a fraction p of elements on the level i 1 chain are also on the level i chain. Hence, Pr[e level i 1 and e level i]=p. Assume that we have a uniform random number generator that generates numbers in the range 0 trough RAND MAX. Let CutOff = p RAND MAX. Then, Pr[next random number CutOff] = p. The above suggest the following method: 1. Generate a random number. If it is CutOff, then the new element should be at level 1 chain. 2. Generate another random number. If it is again CutOff, then the new element is also at level 2 chain. 3. Repeat the above steps until a random number > CutOff is generated. In C++ :
int lev=0; while (rand() <= CutOff) lev++;
http://dis.unal.edu.co/profesores/ypinzon/2016699
17
template<class E, class K> class SkipNode{ friend SkipList<E,K>; private: SkipNode(int size){link = new SkipNode<E,K> *[size];} SkipNode(); {delete [] link;} E data; SkipNode<E,K> **link; // 1D array of pointers };
http://dis.unal.edu.co/profesores/ypinzon/2016699
18
http://dis.unal.edu.co/profesores/ypinzon/2016699
19
Constructor
template<class E, class K> SkipList<E,K>::SkipList(K Large, int MaxE, float p) { // Constructor. CutOff = p * RAND_MAX; MaxLevel = ceil(log(MaxE) / log(1/p)) - 1; TailKey = Large; Levels = 0; // initial number of levels // create head & tail nodes and last array head = new SkipNode<E,K> (MaxLevel+1); tail = new SkipNode<E,K> (0); last = new SkipNode<E,K> *[MaxLevel+1]; tail->data = Large; // head points to tail at all levels as empty for (int i = 0; i <= MaxLevel; i++) head->link[i] = tail; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
20
Destructor
template<class E, class K> SkipList<E,K>::SkipList() { // Delete all nodes and array last. SkipNode<E,K> *next; // delete all nodes by deleting level 0 while (head != tail){ next = head->link[0]; delete head; head = next; } delete tail; delete [] last; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
21
Search
template<class E, class K> bool SkipList<E,K>::Search(const K& k, E& e) const { // Search for element that matches k. // Put matching element in e. // Return false if no match. if (k >= TailKey) return false; // position p just before possible node with k SkipNode<E,K> *p = head; for (int i = Levels; i >= 0; i--) // go down levels while (p->link[i]->data < k) // follow level i p = p->link[i]; // pointers // check if next node has key k e = p->link[0]->data; return (e == k); }
http://dis.unal.edu.co/profesores/ypinzon/2016699
22
http://dis.unal.edu.co/profesores/ypinzon/2016699
23
Insert
template<class E, class K> SkipList<E,K>& SkipList<E,K>::Insert(const E& e) { // Insert e if not duplicate. K k = e; // extract key if (k >= TailKey) throw BadInput(); // too large // see if duplicate SkipNode<E,K> *p = SaveSearch(k); if (p->data == e) throw BadInput(); // duplicate // not duplicate, determine level for new node int lev = Level(); // level of new node // fix lev to be <= Levels + 1 if (lev > Levels) {lev = ++Levels; last[lev] = head;} // get and insert new node just after p SkipNode<E,K> *y = new SkipNode<E,K> (lev+1); y->data = e; for (int i = 0; i <= lev; i++) { // insert into level i chain y->link[i] = last[i]->link[i]; last[i]->link[i] = y; } return *this; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
24
Delete
template<class E, class K> SkipList<E,K>& SkipList<E,K>::Delete(const K& k, E& e) { // Delete element that matches k. Put deleted // element in e. Throw BadInput if no match. if (k >= TailKey) throw BadInput(); // too large // see if matching element present SkipNode<E,K> *p = SaveSearch(k); if (p->data != k) throw BadInput(); // not present // delete node from skip list for (int i = 0; i <= Levels && last[i]->link[i] == p; i++) last[i]->link[i] = p->link[i]; // update Levels while (Levels > 0 && head->link[Levels] == tail) Levels--; e = p->data; delete p; return *this; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
25
It uses a hash function f to map keys into positions in a table called the hash table. Let K be the domain of all keys and let K be the set of natural numbers. Then, f : K N . The element with key k is stored in position f (k) of the hash table.
http://dis.unal.edu.co/profesores/ypinzon/2016699
26
Search for an element with key k: Compute f (k) and see if there is an element at position f (k) of the table. Delete an element with key k: Search for the element. If found, then make the position f (k) of the table empty. Insert an element with key k: Search for the element. If not found, i.e., position f (k) of the table is empty, then place the element at that position.
http://dis.unal.edu.co/profesores/ypinzon/2016699
27
If the key range is small, then we can easily implement hashing. E.g., let keys for a student record dictionary be 6 digit ID numbers, and that we have 1000 students with IDs ranging from 771000 to 772000. Then, f (k) = k 771000 maps IDs to positions 0 through 1000 of the hash table. The above situation is called ideal hashing. However, what we do when the key range is large? E.g., keys are 12-character strings; each key has to be covered into a numeric value by say mapping a blank to 0, an A to 1, . . ., and a Z to 26. This conversion maps the keys into integers in the range [1, 2712 1].
http://dis.unal.edu.co/profesores/ypinzon/2016699
28
Hashing with Linear Open Addressing The size of the hash is smaller than the key range. Find a hash function which maps several keys into the same position of the hash table. A commonly used such function is f (k) = k%D where D is the size of the hash table. If the keys are not of an integral type, then they have to be converted to non-negative integers before f (k) is computed. E.g., a long string can be converted into an unsigned integer by selecting two of its characters, or to an unsigned long integer by selecting four of its characters. Each position of the hash table is called a bucket.
http://dis.unal.edu.co/profesores/ypinzon/2016699
29
What happens if f (k1 ) = f (k2 ), for k1 = k2, i.e., a so-called collision has occurred. If the relevant bucket has space to store an additional element, then we are done. Otherwise, we have an overow problem. How do we overcome overows? Search the table (sequentially) to nd the next available bucket to store the new element. The above idea implements the Insert operation.
http://dis.unal.edu.co/profesores/ypinzon/2016699
30
Search for element with key k Search starting from the home bucket f (k) and by examining successive buckets (and considering the table as circular) until one of the following happens: 1. A bucket containing the element with the key k is found. 2. An empty bucket is reached. 3. We returned to the home bucket. In case 1, we have found the element we are looking for. In the other two cases, the table doesnt contain the requested element.
http://dis.unal.edu.co/profesores/ypinzon/2016699
31
Deleting the element with key k Deletion needs special care: if we simply make table position empty, then we may invalidate the correctness of the Search method. This implies that deletion may require to move several elements in order to leave the table in a state appropriate for the Search method. Alternative solution: introduce a eld NeverUsed in each bucket. Initially this is set to true. When an element is placed into a bucket, its NeverUsed eld becomes false. Case 2 of Search is replaced by: a bucket with NeverUsed eld equal to true is reached. Deletion is accomplished by simply vacating the relevant bucket. The alternative solution requires the organization of the hash table when the number of buckets with false NeverUsed is large.
http://dis.unal.edu.co/profesores/ypinzon/2016699
32
http://dis.unal.edu.co/profesores/ypinzon/2016699
33
Constructor
template<class E, class K> HashTable<E,K>::HashTable(int divisor) { // Constructor. D = divisor; ht = new E [D]; // allocate hash table arrays empty = new bool [D]; // set all buckets to empty for (int i = 0; i < D; i++) empty[i] = true; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
34
Search
template<class E, class K> int HashTable<E,K>::hSearch(const K& k) const { // Search an open addressed table. Return location of k if present. // Otherwise return insert point if there is space. int i = k % D; // home bucket int j = i; // start at home bucket do{ if (empty[j] || ht[j] == k) return j; j = (j + 1) % D; // next bucket } while (j != i); // returned to home? return j; // table full } template<class E, class K> bool HashTable<E,K>::Search(const K& k, E& e) const { // Put element that matches k in e. // Return false if no match. int b = hSearch(k); if (empty[b] || ht[b] != k) return false; e = ht[b]; return true; }
http://dis.unal.edu.co/profesores/ypinzon/2016699
35
Insert
template<class E, class K> HashTable<E,K>& HashTable<E,K>::Insert(const E& e) { // Hash table insert. K k = e; // extract key int b = hSearch(k); // check if insert is to be done if (empty[b]){ empty[b] = false; ht[b] = e; return *this; } // no insert, check if duplicate or full if (ht[b] == k) throw BadInput(); // duplicate throw NoMem(); // table full }
http://dis.unal.edu.co/profesores/ypinzon/2016699
36