0% found this document useful (0 votes)
19 views

ch01 - Data Structue and Algorithms - Intro - en

data structure intro

Uploaded by

thomaselbitar
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
19 views

ch01 - Data Structue and Algorithms - Intro - en

data structure intro

Uploaded by

thomaselbitar
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 58

Université Antonine

Data Structures
and Algorithms
Course Outline
• Chapter 1: Introduction: Structures and
pointers
• Chapter 2: Algorithms complexity
• Chapter 3: Abstract data type: Arrays
• Chapter 4: Linked lists
• Chapter 5: Queues
• Chapter 6: Stacks
• Chapter 7: Trees
• Chapter 8: Heaps
2
Main References
• Principles of Data Structures using C and C++, Vinu V Das, New Age
International Ltd, 2006
• Algorithmes et structures de données génériques, Michel Divay,
DUNOD, 2ed, 2004
• Data Structures and Algorithm Analysis in C/C++ , by Mark Allen
Weiss, Addison Wesley

• Data structures using C and C++, Y. Langsam, M. Augenstein, A.


Tanenbaum, Prentice Hall international editions, 1996
• Data structures and program design in C, R. Kruze, C. Tondo, B.
Leung, Prentice Hall international editions, 1997
• Types de données et algorithmes – C. Froidevaux – Ediscience
international -1993.
• Cours sur les structures de données, Dr Margueritte Sayah, ULFS2,
cours info205
Extra References
• C/C++, How to Program, Deitel and Deitel,
Prentice Hall
• Programming and Problem Solving with C++,
Nell Dale; Jones & Bartlett Publishers
• C & Data Structure, P. S. Deshpande, O. G. Kakde,
Dreamtech Press, 2003.
• Apprendre le C++, Claude Delannoy, Eyrolles,
2007
• Algorithmique en C++, Jean-Michel Lery, Pearson,
2006

4
Chapter 1
Introduction: Structures and
Pointers
Data Structures and
Algorithms

5
Outline
• Structures
• Pointers

6
STRUCTURES

7
Introduction
• An array allows
– to designate with one name, a set of values with
the same type
– to access elements, we use indices
• A structure allows
– to designate with one name, a set of values with
different types
– to access elements, we use their names

8
Structure Declaration
• Declaration example:
struct record {
int number ;
int qt ;
float price ;
} ;
• The structure type is called record, and contain 3
fields: 2 of type int and 1 of type float
record item1, item2 ;
• It reserves 2 places in memory of type record:
one for item1 and another for item2

9
Structure fields usage
• The fields are manipulated as any variable.
• We use the operator « dot » (.)
• Examples
item1.number = 15 ;
cout << item1.price ;
cin >> item2.price ;
item1.number++
• The priority of “.” is very high.

10
Global usage of a structure
• The assignment operator “=“ is also used with the
structures
• Examples: item1 = item2 ;
• This gives
item1.number = item2.number ;
item1.qt = item2.qt ;
item1.price = item2.price ;
• The 2 structures should have the same type.
• We don’t use the operator “=“ when the stucture
contains string of characters (…)
11
Structure initialization
• A structure contains initially
– random values if it is local to a function
– zeros if it is global
• Example :
record item1 = {100, 285, 200 } ;
record item2=item1;
const record REF = {1, 10, 1.};

12
Structures nesting
1. Structure including arrays
2. Array of structures
3. Structures including other structures
4. Structure containing pointers (special case…)

13
Structure including arrays
• Structure declaration:
struct person {
char fname[30] ;
char lname [20] ;
float hours [31] ;
} ;
person employee, current ;
• The notation : employee.hours[4]
– Designate the 5th element of hours table of the employee
structure.
• The notation : &employee.hours[4]
– Designate the address of the 5th element of hours table of
the employee structure.

14
Array of structures
• Structure declaration:
struct point {
char name ;
int x ;
int y ;
} ;
point curve[50] ;
• The notations : (1) curve[i].x (2) curve[4]
– (1) designates the value of the field x of the ith element of
array curve.
– (2) represents the structure of type point that corresponds
to the 5th element of array curve

15
Structures including other structures
• Structures declarations :
struct date{ struct person {
int day ; char lname[30] ;
int month ; char fname [20] ;
int year ; float hours [31] ;
} ; date date_recruit ;
date date_post ;
} employee, current ;
• La notation : employe.date_recruit.year
– represent the year of recruitment corresponding to the
structure employee.
• We can write:
current.date_recruit = employee.date_post ;
16
The scope of a structure

• The scope depends on struct record{


int number ;
the declaration place in int qt ;
the program float price ;
– similar to any variable } ;
main ()
{ record x ;
....
}
fct ( ....)
{ record y, z ;
....
}

17
POINTERS

18
Data types in C++
The C++ manipulates addresses using variables called pointers

Data types in C++


Simple Composed
Address

Integer Real array struct union class

int, char, Float, double,


bool, etc etc

pointer reference
enum

19
Pointers variables
• Declaration: DataType* var;
• Multiple declarations: DataType *var1, *var2, …;
• Examples
int * ad ;
int n ;
n = 20 ;
ad = &n ; //assign the address of n to ad
*ad = 30 ;// assign *ad the value 30, n becomes 30
• The variable ad
– is a pointer to integers, pointer of type int*
– Contains the address of an integer
• * is a unary operator that designates the content of an address
• * indicates that a variable is a pointer (in the declaration)
• *ad is an object with address ad, we say that we dereference the pointer
20
Pointers variables
• Representation of pointers
Address Variable
ad n 5000 5008 ad
20

30 5008 30 n

ad = &n ; //assign the address of n to ad


*ad = 30 ;//assign *ad the value 30

21
Motivation
• Why do we need address types (pointers):
– They can make a program more efficient
• in terms of execution time and memory usage
• e.g., dynamic memory allocation and removal of this
memory during running time
– this can replace static arrays and structures
• e.g., passing arguments to functions by pointer avoid
copying variables and give direct access to original data
– They are used to create more complex data
structure
• e.g., linked list, stacks and queues etc.

22
Some examples
int * ad1, * ad2, *ad ;
int n = 10, p = 20 ;
ad1 = &n ;
ad2 = &p ;
*ad1 = *ad2 + 2 ; //n = p + 2 ;
*ad1 += 3; //n = n + 3
(*ad1)++; //n++
N.B.
• cout<<*ad1++; it will derefence ad1 and display the
value*ad1, then it will increase the address ad1 by 1
• cout<<(*ad1)++; it will dereference ad1 and display it, then it
will increase (*ad1) by 1
23
Some examples (cont.)
• Remarks:
1. ad et *ad are lvalues, but &ad is not
2. int * ad ; reserves a memory place for a pointer
pointing to an integer, but it does not reserve
the integer.

24
Pointer incrementation
int * ad ;
ad++;
• ad contains the address of the next integer
(element) (i.e. the integer that is after *ad)
• In fact, the address is increased by sizeof(int)
bytes.

25
Pointer on a pointer
int

#include<iostream.h> n 44 int *
int main(){
int n=44; pn
cout << " n = " << n << endl; int **
cout << " &n = " << &n << endl; ppn
int* pn=&n; // pn contains the address of n
cout << " pn = " << pn << endl;
cout << " &pn = " << &pn << endl; n = 44
cout << " *pn = " << *pn << endl; &n = 0x22ff44
int** ppn=&pn; // ppn contains the address of pn pn = 0x22ff44
cout << " ppn = " << ppn << endl; &pn = 0x22ff40
cout << " &ppn = " << &ppn << endl; *pn = 44
cout << " *ppn = " << *ppn << endl; ppn = 0x22ff40
cout << "**ppn = " << **ppn << endl; &ppn = 0x22ff3c
return 0; *ppn = 0x22ff44
} **ppn = 44

26
Passing argument to a function
• We have three modes of passing arguments
1. Passing arguments by value
2. Passing arguments by reference
3. Passing argument by address with pointers

27
Passing arguments by value
before call : 10 20
#include <iostream.h> start swap : 10 20
void swap (int , int ) ; end swap : 20 10
after call : 10 20
int main(){
int n=10, p=20 ;
cout << " before call:" <<n<<" "<<p<<"\n" ;
swap (n, p) ;
cout << “after call:"<<n<<" "<<p<<"\n" ;
return 0;
}
void swap (int a, int b){
int tmp ;
cout << " start swap : "<<a<<" "<< b<<"\n" ;
tmp = a ;
a = b ;
b = tmp ;
cout << " end swap : "<<a<<" "<<b<<"\n" ;
} 28
Passing arguments by reference
before call: 10 20
#include <iostream.h> start swap : 10 20
void swap (int &, int &) ; end swap : 20 10
int main(){ after call : 20 10
int n=10, p=20 ;
cout << "before call:"<<n<<" "<<p<< "\n" ;
swap (n, p) ;// attention, ici pas de &n, &p
cout << "after call:"<<n<<" "<< p << "\n" ;
return 0;
}
void swap (int & a, int & b)
{ int tmp ;
cout << “start swap:"<<a<<" "<< b << "\n" ;
tmp = a ; a = b ; b = tmp ;
cout << "end swap :"<<a<<" "<< b << "\n" ;
} 29
Passing argument by address with
pointers
#include <iostream.h>
void swap (int *, int *) ;

int main(){
int a=10, b=20 ;
cout << "before appel : " << a << " " << b << "\n" ;
swap (&a, &b) ;
cout << “after call : " << a << " " << b << "\n" ;
return 0;
}
void swap (int *ad1, int *ad2)
{ int tmp ;
tmp = *ad1 ;
*ad1 = *ad2 ;
*ad2 = tmp ;
}

before call: 10 20
30
after call: 20 10
Remark
• The prototype of the swap function can be
written as follows:
void swap (int * const ad1, int * const ad2)
– * const ad1 is of type int,
– ad1 is then a constant address pointing to an integer,
i.e. a constant pointer.
• i.e. the address or pointer cannot be changed
• If we had:const int * ad1
– int * ad1 is a constant, and then:
– ad1 is a pointer to a constant integer
• i.e. we cannot change the integer value pointed by ad1

31
Passing a structure as argument to a
function
• Passing structure by value
• Passing structure by reference
• Passing the address of a structure and
operator « -> »

32
#include <iostream>
using namespace std ;
Passing structure by value
struct record {// global scope
int a ;
float b ;
} ; before calling fct : 1 12.5
main() in fct : 0 1
{ record x ; returning to main : 1 12.5
void fct (record y) ;
x.a = 1 ; x.b = 12.5 ;
cout << "before calling fct : "<< x.a <<" "<< x.b <<
"\n" ;
fct (x) ;
cout << "returning to main : " << x.a << " " << x.b ;
}

void fct (record s)


{ s.a = 0 ; s.b=1 ;
cout << "in fct : " << s.a << " " << s.b << "\n" ;
33
}
#include <iostream> Passing structure by reference
using namespace std ;
struct record {
int a ;
float b ;
} ;
main()
{record x ;
void fct (record & y) ;
x.a = 1 ; x.b = 12.5 ;
cout << "before calling fct : "<< x.a <<" "<< x.b <<
"\n" ;
fct (x) ;
cout << "returning to main : " << x.a << " " << x.b ;
}
void fct (record & s)
{ s.a = 0 ; s.b=1 ;
cout << "in fct : " << s.a << " " << s.b << "\n" ;
}
before calling fct : 1 12.5
in fct : 0 1
returning to main : 0 1
34
#include <iostream>
Passing the address of a structure
using namespace std ;
struct record { int a ;
float b ;
} ; before calling fct : 1 12.5
in fct : 0 1
main()
returning to main : 0 1
{record x ;
void fct (record *) ;
x.a = 1 ; x.b = 12.5 ;
cout << " before calling fct : "<< x.a <<" "<< x.b <<
"\n" ;
fct (&x) ;
cout << " returning to main:"<< x.a <<" "<<x.b<< "\n" ;
}
void fct (record * ads)
{ ads->a = 0 ; ads->b = 1;
cout << “in fct :"<< ads->a <<" "<< ads->b << "\n" ;
}
35
Operator ->
• Given a pointer to a structure, there are two
methods to access the fields:
– Notation: (*ads).a and (*ads).b
– Notation with the operator ->: ads->a and ads->b
• Operator -> is usually used with dynamic
allocated structures
– see later

36
Returning a structure value from a
function
record fct (...)
{
record s ; /* local structure to a fct */
.....
return s ; /*the function returns the
value of the structure */
}

37
The name of an array is a constant
pointer
int t[10]
• t is equivalent to &t[0]
• t is a constant pointer to integers
• The following notations are the same
t+1 same as &t[1]
t+i same as &t[i]
t[i] same as *(t+i)
• These are two ways to store the value 1 to each
of 10 elements of the array t

38
The name of an array is a constant
pointer
• These are some examples to store the value 1 to each of 10
elements of the array t
int i ; int i ;
for (i=0;i<10;i++) int *p ://variable pointer
for (p=t, i=0 ; i<10 ; i++, p++)
*(t+i) = 1 ; *p = 1 ;
Remark: we cannot do t++ cout<<p[2]; //correct

int t[10] ; int t[10] ;


int * p ; int i ;
for (p=t ; p<t+10 ; p++) for (i=0 ; i<10 ; i++)
*p = 1 ; t[i] = 1 ;

39
Null Pointer
• A null pointer
– points on nothing
– has a value 0
– is a constant pointer
• int *ptr; ptr=0; // or ptr=NULL;
– NULL is a predifined constant in files cstdio and
cstddef
• It is very important to insure that the pointer
points somewhere known before using it (or it is
null)
40
Dynamic allocation:
operators new and delete
• We distinguish between static and automatic data:
1. static data exists during the lifetime of the program and lasts
when it ends
2. automatic data exists only during the lifetime of a bloc or a
function
• A new category of data is allocated dynamically
• Dynamic allocation of memory is done in a specific region
in memory called heap (or free store).
• The allocation (i.e. reservation) is done using the operator
new
• The deallocation (i.e. releasing) of this memory is only done
with the operator delete
• Even after leaving a function where the allocation is done,
the allocation persists if we don’t use delete
41
Operator new
ad
• Example 1 ?
int *ad ; ad = new int;//or
int *ad = new int ; 12
*ad = 12;
• Allocate the necessary memory for one element of type int, and
• Assign to ad the corresponding address
adc
• Example 2 ? ? … ?
char *adc ;
adc = new char[100] ;
• Allocate the necessary memory for an array of 100 characters, and
• Put the starting address in adc

42
Syntax and role of new
• Syntax of new:
– new type
– new type[n]
• n can be a variable or a constant
– new type [n] [MAX]; #e.g.: define MAX 4
• A preferred method to declare an array of 2 dimensions (n and m
are two variables)
int **a=new int*[n];
for(int i=0;i<n;i++)
a[i]=new int[m];
• Another method: (n is constant and m is a variable)
const int n = 3;
int *ptr[n];
for(int i=0;i<n;i++)
ptr[i]=new int[m];
43
Operator delete
• Deallocate allocated memory
• Is only applied to pointers with values obtained
from the operator new.
• Does not eliminate the pointer itself but the
value pointed by this pointer
• Example
delete ad ; // ad was a pointer on a variable
delete adc ; // delete [] adc
//adc was a pointer on an array
• Syntax: delete address
44
Remarks
• The main usage of pointers is to manipulate
dynamic allocated variables
• The main reason for dynamic allocation is to
save memory space
– the space is allocated only from the time we
execute the instruction with new
– the space is deallocated when we don’t need it
• it is possible to reach a case where we lack from heap
memory

45
Internal structure of a process
• A process is a running program
stack
• It is constituted with 4 parts in
memory:
– code: the binary code of the
program
– data: contain global variables
– heap: for dynamic allocation using heap
the new operator
– stack: contains temporary data (e.g. data
to manage the usage of functions:
code
local variables, arguments, returning
point address from function)
46
Examples
Example Example reviewed
int* ptr1 = new int; int* ptr1 = new int;
int* ptr2 = new int; int* ptr2 = new int;
*ptr2 = 44; *ptr2 = 44;
*ptr1 = *ptr2; *ptr1 =*ptr2;
ptr1 = ptr2; delete ptr1; //avoid Inaccessible.
object
delete ptr2; ptr1 = ptr2;
delete ptr2;
ptr1 = NULL; //avoid dangling
pointer
ptr2 = NULL;

Represent with figures the execution of these codes


Inaccessible object: A dynamic variable on the heap without any pointer pointing to it.
Dangling pointer: A pointer that points to a variable that has been deallocated.
47
Research Functions
• Exercise search functions
• Write two search functions Find and BinarySearch to
find the index of a given value
• Test the function
• The user specifies the number of values (i.e. we must
use dynamic allocation)

48
#include <iostream> Uing namespace std;

int Find(int *ptab, int size, int val){


for(int i=0;i<size; i++)
if(ptab[i]==val) return i;
return -1;
}

int BinarySearch(int *ptab, int size, int val){ int mid, left=0,
right=size ;

while(left<right){
mid=(left+right)/2;
if(val==ptab[mid])
return mid;
else if(val < ptab[mid])
right=mid;
else
left=mid+1;
}
return -1; 43
}
int main(){
int n,val; int
ind;
cout<<"Read the nber of elements :"<<endl;
cin>>n;
int *ptr=new int[n];
cout<<"Read the n ele. of
tab:"<<endl;
for(int i=0;i<n;i++) cin>>ptr[i];
cout<<"Read the ele. to search
for"<<endl; cin>>val;
ind=Find(ptr,n,val);
//ind=BinarySearch(ptr,n,val);
if(ind!=-1)
cout<<"The ele. is found at the index "<<ind<<endl;
else
cout<<"The ele is not found!"<<endl;
delete
ptr;
return 0;
}

44
Exercise Structure
Exercise
A student is defined by :
• last name
• first name
• age
• address
• GPA
Write a program that:
1. Reads the data of a student
2. Reads the data of n students (n<=20), in an array of structures
3. Displays the information of a student knowing his last and first name
4. Displays the average of GPA for all students
5. Displays the students with GPA < 3
6. Swap the place of the first and the last students
7. Sort the array in ascending order of GPA

Use the functions and pointers on structures. Use dynamic allocation.


51
Solution
• #include<iostream>
• using namespace std;

• struct Student{
• char lname[20];
• char fname[20];
• int age;
• char address[40];
• float gpa;
• };

• void readInfo(Student *);


• void readNinfo(Student *, int);
• void displayInfo(Student *);
• void displayNinfo(Student *, int);
• Student *searchInfo(Student *, int);
• float averGPA(Student *, int);
• void searchGPA(Student *, int);
• void swap(Student *, Student *);
• void sort(Student *, int);
52
Solution
• int main(){
• int N;

• Student *ast, *stdInfo;


• cout<<"Input N: ";
• cin>>N;

• ast = new Student[N];

• readNinfo(ast,N);
• stdInfo=searchInfo(ast, N);
• displayInfo(stdInfo);
• cout<<"Aver GPA: "<<averGPA(ast, N)<<endl;
• searchGPA(ast, N);
• cout<<"Swap the first and the last Student..."<<endl;
• swap(ast[0], ast[N-1]);
• displayNinfo(ast,N);
• cout<<"sorting Students by GPA"<<endl;
• sort(ast,N);
• displayNinfo(ast,N);

• return 0; 53
Solution
• void readInfo(Student *st){
• cout<<"Input Student Info"<<endl;
• cout<<"Fname Lname: ";
• cin>>st->fname>>st->lname;
• cout<<"Age: "; cin>>st->age;
• cout<<"Address: "; cin>>st->address;
• cout<<"GPA: "; cin>>st->gpa;
• }

• void readNinfo(Student *ast, int N){


• cout<<"Read "<<N<<" Student"<<endl;
• for(int i=0; i<N; i++){
• readInfo(ast+i);
• }
• }

54
Solution
• void displayInfo(Student *st){
• cout<<"Info of Student"<<endl;
• cout<<"Fname Lname: ";
• cout<<st->fname<<" "<<st->lname<<endl;
• cout<<"Age: "; cout<<st->age<<endl;
• cout<<"Address: "; cout<<st->address<<endl;
• cout<<"GPA: "; cout<<st->gpa<<endl;
• }

• void displayNinfo(Student *ast, int N){


• cout<<"Display All Students"<<endl;
• for(int i=0; i<N; i++){
• displayInfo(ast+i);
• }
• }

55
Solution
• Student *searchInfo(Student *ast, int N){
• Student *stdInfo;
• char fname[20],lname[20];
• cout<<"Input Student fname and lname: ";
• cin>>fname>>lname;
• for(int i=0; i<N; i++){
• if(strcmp(fname,ast[i].fname)==0 && strcmp(lname,ast[i].lname)==0){
• stdInfo=&ast[i];
• return stdInfo;
• }
• }
• }

• float averGPA(Student *ast, int N){


• float aver=0;
• for(int i=0; i<N; i++){
• aver+=ast[i].gpa;
• }
• aver=aver/N;
• return aver;
• } 56
Solution
• void searchGPA(Student *ast, int N){
• Student *stdInfo;
• cout<<"Student with gpa<3"<<endl;
• for(int i=0; i<N; i++){
• if(ast[i].gpa<3){
• stdInfo=&ast[i];
• displayInfo(stdInfo);
• }
• }
• }

• void swap(Student *st1, Student *st2){


• Student tmp;
• tmp=*st1;
• *st1=*st2;
• *st2=tmp;
• }
57
Solution
• void sort(Student *ast, int N){

• for(int pass=1; pass<=N-1; pass++){


• for(int i=0; i<N-pass;i++){
• if(ast[i].gpa>ast[i+1].gpa)
• swap(ast+i,ast+i+1);
• }
• }
• }

58

You might also like