II UNIVERSITY OF THE STUDIES OF
ROME
Tor Vergata
Course of
Foundations of Computer science II
prof. Giovanni Cantone
The Grafi Orients To You
1) Introduction
2) Definitions
3) Representation of the
abstract data Graph
to) Location objects base
i. ARC_NODE
II. ARC_LIST
III. VERTEX_NODE
iv. GRAPH (Vertex_List)
b) Description and
implementation of the polimorfismo
i. ELEMENT
II. INT_OBJ
III. CHAR_OBJ
iv. FLOAT_OBJ
c) applicativo Development
based on class GRAPH
1) Introduction
The first testimony of employment of the grafi
laughed them to 1736 when Leonhard Euler used them in order to resolve
the classic problem of the bridges of Koenigsberg where the Pregal
river slides around the island of Kneiphof. There are four firm
lands identified from letters To, B, C, D in Figure 1, that they have
this river to their borders. Seven bridges identify to you from
letters act, connect four firm lands. The problem of the bridge
of Koenigsberg is following: leaving from a firm earth, it is
possible to return to the position iniziale after to have crossed
every bridge one single time?
A possible way is following:
· To leave from the firm earth B
· To cross the bridge to in order catching up the
island To
· To use the bridge and in order to catch up the D
area
· To use the bridge g in order to catch up area
C
· To use the bridge d in order to catch up the
area To
· To use the bridge b in order to catch up the B
area
· To use the bridge f in order to catch up the D
area
This distance does not cross all the
bridges neither leads to the position of B. departure Euler discovered
that people of Koenigsberg cannot cross every bridge one single time
and return to the departure position. Euler resolved the problem
using graph (a multigraph in effects) in which firm lands they were you concern ( or nodes to us ) and the bridges were the sides ( arch ). Its solution is not only elegant but it applies to
all the grafi.
Euler defined the degree of an apex like the number of
sides incidents on it, demonstrated also that a distance exists that
leave from an apex whichever, crosses a single time every side and
finishes in the apex only begins them, if and if the degree of every
apex is equal. A similar distance will be called covered of Euler. This distance does
not exist for the bridges of Koenigsberg, in how much all concerns is
of uneven degree.
From this first application,
the grafi has been uses in one immense range you of applications, like
the analysis of the circuits electrical workers, the planning of the
plans, the identification of chemical compounds or the determination
of the shorter roads.
2) Definitions
A graph it is a collection that comprises two
sets , one of you concern to us and one of arches, while with of it
arches can it are empty, with of concerns to us, if the graph it
exists, pu² not to turn out empty. An apex also is called node and constitutes the
structural element base of the graph . An arc is the logon
between two concerns to us, if it arches it of the graph are orients
to you, then is spoken about graph oriented otherwise is spoken about graph not
oriented.
To every apex and arc they can be associated of the
labels, if that happens is spoken about graph labeled in concerns to us or in it
arches, the two labels arches, not necessarily must be various, is
possible to have two arches with the same attribute. In the
case in which the labels they are constituted from entire numbers or
decimates them and the elements of the graph they are labeled in
ordered way, then is spoken about graph weighed.
To the oriented inside of a graph , way is defined a sequence of concerns to
us such that exists an arc between every apex and that successive one.
The length of the equal way e' to the number of arches that
they connect you concern to us. A single apex will constitute a
way of length zero. The way says simple if, to the inside of the way, they do not exist
you concern to us that they appear more than once, in contrary case is
said not simple. In a
graph oriented, a cycle e' a
way of greater or equal length to that it begins and it finishes on
the same apex. A graph it is defined cyclical if in it there are or more
cycles, in contrary case, we will say that the graph it is acyclic. In the oriented case
of graph , one says that the Vj node is adjacent to the node You if an arc exists who leave from
and you reach to You in Vj, such arc comes said incident to the nodes Vi and Vj.
In the case in which it is had to that making with a graph not
oriented, it does not have sense to speak about you concern to us
adjacent in how much such definition closely is tied to the arc
concept orientato (arc in the which e' important order of its
extreme points).
From every apex pu² to dipartirsi a imprecisato number
of it arches which can finish in one whichever of concern us of the
graph , it can happen that from a dipartano apex two it is arched that
both in the same apex finish, various from that one of departure, in
this case you concern us of departure and of arrival for every arc
they are equal, such arches come sayings parallels, a graph that does not
contain arches parallels is said simple.
For an apex the degree is defined as the number of arches relati you to it,
more just, is spoken about income degree, in order to indicate the number of arches that they
finish in the considered apex e degree of
escape in order to indicate the number of arches
that dipartono from the considered apex. An apex that has a
null degree is said isolated and represents an apex from which dipartono neither they
are not reached arches. A graph it is said connected if there is a distance
between every brace of nodes pertaining to the graph same, obviously,
a graph that it contains nodes isolates to you is not connected.
A graph one closely says
connected if for every apex exists
a direct distance every towards other apex. The figures that
follow, illustrate a graph labeled oriented (on the left) and the not
oriented labeled correspondent graph (to right).
After to have supplied some general idea on the
type of abstract data GRAFO, we take care hour to define of hour the
representation .
3) Representation of the abstract
data Graph
A way to represent the abstract data Graph is
known with the name of matrix of the
adjacency, in such case, a graph is represented
from a square matrix of N order where N is the number of concerns us
pertaining to the graph , they are in correspondence biunivoca with the
values of the indices of line and column of the square matrix.
The elements of the matrix are of booleano type and their value
comes established from the following rule:
the element in the line and the column j is worth True if in the graph an arc from the apex to the apex exists j, otherwise is worth False.
A "loop" will be represented from the True value place
in the case characterized from (i , i).
Advantages :
Such representation is much simple one and less concurs the
directed access with the relative information to the existence or than
an arc that connects two you concern to us
Disadvantages :
a graph constituted from N you concern to us, demands one
matrice NxN, this is a
problem when the numero of you concern cresce poiché increases
the memory to us remarkablly occupied. An other disadvantage of
this representation consists nel made that we cannot increase the
number of you concern us of the graph moreover cannot be represented
grafi in which they appear arches parallels.
According to type of representation a graph consists
in representing through a list of sottoliste, such representation is
famous with the name of list of the
adjacency, all concerns to us of the graph is
inserted in a list and every apex has, associated to if, an ulterior
list that will contain all arches it that they are originated from
such apex.
Advantages :
the memory requirement comes to only depend on the effective number of
concerns to us and arches that they constitute the graph , moreover,
the representation is dynamics
Disadvantages :
the access to an element of the graph is not directed, but it
needs the scansion of the list
In our case, in order to realize the graph , we will take in
consideration the representation by means of list of the adjacency,
of the graph we will consider a representation limited from the
single availability of memory of the system that implements it
(Unbounded Form), moreover, the representation from we taken in
consideration will manage the memory space that is created for
eventual cancellations.
The complexity of the algorithm that implements the
grafi orients to you has carried see again the approach to the problem
in terms of sottoproblemi of inferior complexity that has been
optimizes to you singularly and subsequently it coordinates to you.
This same logical distance will be followed in the trattazione
that therefore turns out articulated in the following points:
to) Location of the objects base in which decomposing
the problem
b) Description and implementation of the
polimorfismo
c) Development of a applicativo based on class
GRAPH
to) Location objects base
One of the possible computer science
rappresentazioni of the grafi is that one of the adjacency lists that,
like previously exposed, are based on a containing list all concern
making part to us of the graph from everyone of which originate the
list of arch outgoing from the same apex.
In this optical it turns out enough intuitivo to
characterize which primitivo object that is not using other objects
the ARC_NODE, subsequently characterizes object ARC_LIST that is the
list that re-unites all the ARC_NODE, continuing in the logical
development the dipana VERTEX_NODE from which the ARC_LIST is had and
finally the VERTEX_LIST is had that gives a logical point of view
coincides with object GRAFO.
We pass hour to the analysis of the single objects in
the overexposed order:
//Arc_Node.h: interface for the Arc_Node
class.
/
# if!defined(AFX_ARC_NODE_H__4D70C386_7844_11D1_BECF_444553540000__INCLUDED
_)
# define AFX_ARC_NODE_H__4D70C386_7844_11D1_BECF_444553540000__INCLUDED
_
# if _ MSC_VER > = 1000
# pragma ounces
# endif //_ MSC_VER > =
1000
# it includes "Element.h"
class Arc_Node
{
friend class Arc_List;
protected:
Gen_Data_Ptr Arc_Destination;
Gen_Data_Ptr
Arc_Attribute ;
Arc_Node * Next_Arc
;
public:
void
Display_An_Arc();
Arc_Node(Gen_Data_Ptr The_Attribute, Gen_Data_Ptr The_Destination);
virtual
~Arc_Node();
};
# endif /
/!defined(AFX_ARC_NODE_H__4D70C386_7844_11D1_BECF_444553540000__INCLUDED
_)
As the Arc_List is looked at is declared friend
that therefore will be able to approach the data described in the
private part that is 2 gunlayers of Gen_Data_Ptr type which in class
ELEMENT comes defined like a gunlayer to an object of type ELEMENT.
These 2 gunlayers concur therefore not to bind the type neither
of the attribute of the arc of of the attribute of the destination
apex. A gunlayer to the successive node in the list is had then
of arches inherent a data apex.
The operations defined on every object of type ARC_NODE
are its creation and contemporary initialization, the destruction and
the following visualization second declaration:
//Arc_Node.cpp: implementation of the Arc_Node
class.
//
/
# it includes "Arc_Node.h"
# it includes < iostream.h
>
/
//Construction/Destruction
/
Arc_Node::Arc_Node(Gen_Data_Ptr
The_Attribute, Gen_Data_Ptr The_Destination)
{
Arc_Attribute = The_Attribute ;
Arc_Destination = The_Destination;
}
Arc_Node::~Arc_Node()
{
}
/
//
Display
/
void Arc_Node::Display_An_Arc()
{
Arc_Attribute->Display();
cout < <
"-->" ;
Arc_Destination->Display();
cout < <
"\t";
}
The Display_An_Arc does not make other that to
apply the Display method defined for class ELEMENT and its derived
classes to Arc_Attribute and Arc_Destination that are gunlayers to
this class, obtaining therefore the visualization of the attribute of
the arc and the apex of destination.
//Arc_List.h: interface for the Arc_List
class.
//
# if!defined(AFX_ARC_LIST_H__4D70C384_7844_11D1_BECF_444553540000__INCLUDED
_)
# define AFX_ARC_LIST_H__4D70C384_7844_11D1_BECF_444553540000__INCLUDED
_
# if _ MSC_VER > = 1000
# pragma ounces
# endif //_ MSC_VER > =
1000
# it includes "Arc_Node.h"
class Arc_List
{
protected:
Arc_Node *
Arc_List_Head ;
public:
Arc_Node *
Is_Member_Of(Gen_Data_Ptr The_Arc, Gen_Data_Ptr
The_Destination);
void
Clear();
int
Number_Of_Arcs_In();
bool
Remove(Gen_Data_Ptr The_Arc, Gen_Data_Ptr The_Destination);
void
Display_Arcs();
void
Insert(Gen_Data_Ptr The_Attribute, Gen_Data_Ptr The_Destination);
Arc_List();
virtual
~Arc_List();
};
# endif /
/!defined(AFX_ARC_LIST_H__4D70C384_7844_11D1_BECF_444553540000__INCLUDED
_)
The only protected data of this class is a
gunlayer to a ARC_NODE which it will be the first one of the list of
arches outgoing from the data apex for which the class it comes
istanziata. In the Public part there is the definition of the
operations eseguibili standards on a list, their declaration is
following:
//Arc_List.cpp: implementation of the Arc_List
class.
//
/
# it includes < iostream.h
>
# it includes "Arc_List.h"
/
//Construction/Destruction
/
Arc_List::Arc_List()
{
Arc_List_Head = 0;
}
Arc_List::~Arc_List()
{
}
/
/
void Arc_List::Insert(Gen_Data_Ptr
The_Attribute, Gen_Data_Ptr The_Destination)
{
Arc_Node * Arc_Node_Ptr;
//Vertex_Node_Ptr tip to a new Vertex_Node
Arc_Node_Ptr = new Arc_Node(The_Attribute,
The_Destination);
//places in head to the list the new apex
if(Arc_List_Head == 0)
{ //EMPTY
LIST
Arc_List_Head =
Arc_Node_Ptr;
Arc_Node_Ptr->Next_Arc = 0;
}
else
{ //NOT EMPTY LIST
Arc_Node_Ptr->Next_Arc =
Arc_List_Head;
Arc_List_Head = Arc_Node_Ptr;
}
}
/
void Arc_List::Display_Arcs()
{
if(Arc_List_Head == 0)
{
cout < < "\tNo Arcs leave
from this Vertex" < < endl;
}
else
{
Arc_Node * Arc_Node_Ptr;
Arc_Node_Ptr = Arc_List_Head;
while(Arc_Node_Ptr! = 0)
{// the cycle is repeated
sin when it is not NULL
Arc_Node_Ptr->Display_An_Arc();
Arc_Node_Ptr = Arc_Node_Ptr->Next_Arc;
}
}
}
/
bool Arc_List::Remove(Gen_Data_Ptr The_Arc,
Gen_Data_Ptr The_Destination)
{
//
Point a gunlayer to the head of the list
Arc_Node * Arc_Node_Ptr_1;
Arc_Node *
Arc_Node_Ptr_2;
Arc_Node_Ptr_1 = Arc_List_Head ;
Arc_Node_Ptr_2 = Arc_List_Head ;
//search of the node to remove
while((Arc_Node_Ptr_1! = 0) &&
((!(The_Arc->Is_Equal(Arc_Node_Ptr_1->Arc_Attribute))) ||
(!(The_Destination->Is_Equal(Arc_Node_Ptr_1->Arc_Destination)))))
{
Arc_Node_Ptr_2 =
Arc_Node_Ptr_1;
Arc_Node_Ptr_1 =
Arc_Node_Ptr_1->Next_Arc;
}
if(Arc_Node_Ptr_1! = 0)
{
// I HAVE FOUND the ELEMENT TO REMOVE
if(Arc_Node_Ptr_1! = Arc_List_Head)
Arc_Node_Ptr_2->Next_Arc =
Arc_Node_Ptr_1->Next_Arc;
else// the ARC
TO REMOVE Is The FIRST One Of the LIST
Arc_List_Head =
Arc_List_Head->Next_Arc;
//elimination of
the arc
delete Arc_Node_Ptr_1;
return true;
}
else
{
// ELEMENT NOT FOUND
return false;
}
}
int Arc_List::Number_Of_Arcs_In()
{
int N_Arcs = 0;
Arc_Node *
Arc_Node_Ptr;
Arc_Node_Ptr = Arc_List_Head;
while(Arc_Node_Ptr! = 0)
{// the cycle is repeated sin when it is not NULL
N_Arcs ;
Arc_Node_Ptr =
Arc_Node_Ptr->Next_Arc;
}
return N_Arcs;
}
/
void Arc_List::Clear()
{
Arc_Node * Arc_Node_Ptr;
Arc_Node_Ptr = Arc_List_Head;
while(Arc_Node_Ptr! = 0)
{// the cycle is repeated sin when it is not NULL
Remove(Arc_Node_Ptr->Arc_Attribute,
Arc_Node_Ptr->Arc_Destination);
Arc_Node_Ptr = Arc_List_Head;
}
}
/
Arc_Node * Arc_List::Is_Member_Of(Gen_Data_Ptr
The_Arc, Gen_Data_Ptr The_Dest)
{
Arc_Node * Arc_Node_Ptr;
Arc_Node_Ptr = Arc_List_Head;
while((Arc_Node_Ptr! = 0) &&
(!(The_Arc->Is_Equal(Arc_Node_Ptr->Arc_Attribute))) &&
(!(The_Dest->Is_Equal(Arc_Node_Ptr->Arc_Destination))))
{
Arc_Node_Ptr =
Arc_Node_Ptr->Next_Arc;
}
return Arc_Node_Ptr;
}
You notice yourself in the REMOVE and in the
IS_MEMBER_OF I use it of method IS_EQUAL defined on type ELEMENT and
derives to you, which it concurs to establish the equality of the data
aims from 2 gunlayers previa conversion to you by means of
Type_Casting from gunlayer to an object ELEMENT to gunlayer to
FLOAT_OBJ or CHAR_OBJ or INT_OBJ.
/
# if!defined(AFX_VERTEX_NODE_H__4D70C387_7844_11D1_BECF_444553540000__INCLUDED
_)
# define AFX_VERTEX_NODE_H__4D70C387_7844_11D1_BECF_444553540000__INCLUDED
_
# if _ MSC_VER > = 1000
# pragma ounces
# endif //_ MSC_VER > =
1000
# it includes "Graph.h"
# it includes "Arc_List.h"
class Vertex_Node
{
friend class Graph;
protected:
Gen_Data_Ptr Vertex_Attribute ;
unsigned
int Reference_Count ;
Arc_List
* Arc_List_Ptr ;
Vertex_Node
* Next_Vertex
;
public:
void
Display_Vertex_And_Arcs();
void
Display_Vertex();
Vertex_Node(Gen_Data_Ptr The_Attribute);
virtual
~Vertex_Node();
};
# endif /
/!defined(AFX_VERTEX_NODE_H__4D70C387_7844_11D1_BECF_444553540000__INCLUDED
_)
Also in this case it comes defined like friend
class GRAPH (that we remember equivalent to the VERTEX_LIST) in how
much must have free access to the fields of the single Vertex_Node of
which is made up. In the segment protected the information
appear of which every Vertex_Node is made up that is an attribute
whose type a priori does not come bound second how much already
described for the Vertex_Node, entire positive indicating a number of
arches entering in the apex, information of primary importance
allorchè will have to be decided if the apex is dismissable or less,
is then a gunlayer to a type ARC_LIST therefore every apex knows where
it begins the list of its arches outgoing. Finally there is a
gunlayer to the next VERTEX_NODE in the VERTEX_LIST.
We pass hour to the declaration of the member function:
//Vertex_Node.cpp: implementation of the
Vertex_Node class.
//
/
# it includes < iostream.h
>
# it includes "Vertex_Node.h"
/
//Construction/Destruction
/
Vertex_Node::Vertex_Node(Gen_Data_Ptr
The_Attribute)
{
Arc_List_Ptr = new Arc_List
;
Next_Vertex = 0
;
Reference_Count = 0
;
Vertex_Attribute = The_Attribute
;
}
Vertex_Node::~Vertex_Node()
{
}
/
/
void Vertex_Node::Display_Vertex()
{
Vertex_Attribute->Display();
if(Next_Vertex! = 0)
cout < < ",";
else
cout < < endl;
}
void Vertex_Node::Display_Vertex_And_Arcs()
{
"\nVertice" cout < <;
Vertex_Attribute->Display();
cout < < "\n\tArchi entering: "< <
Reference_Count;
cout < <
"\n\tArchi uscenti: ";
Arc_List_Ptr->Display_Arcs();
}
As far as the constructor you notice yourself
that second how much demanded from the VISUAL C the 5,0 gunlayers
comes directly inizializzati to 0 and not to NULL as happens in other
languages or previous versions. Moreover the initialization of
field ARC_LIST_PTR happens directly demanding to the operating system
memory for an object of type ARC_LIST that exactly will be aimed from
ARC_LIST_PTR.
There are two various functions of visualization defined
on a VERTEX_NODE, before the Display method of class ELEMENT
visualizes alone the apex recalling and its derivatives while the
second one visualizes also arch it outgoing using the Display_Arcs
method defined on type ARC_LIST.
GRAPH (Vertex_List)
//Graph.h: interface for the Graph
class.
//
/
# if!defined(AFX_Graph_H__4D70C385_7844_11D1_BECF_444553540000__INCLUDED
_)
# define AFX_Graph_H__4D70C385_7844_11D1_BECF_444553540000__INCLUDED
_
# if _ MSC_VER > = 1000
# pragma ounces
# endif //_ MSC_VER > =
1000
# it includes "Arc_List.h"
# it includes "Arc_Node.h"
class Graph
//class that implements
the list of you concern to us
{
friend class Vertex_Node;
protected:
Vertex_Node * Head ; //tip always to the head of the list
public:
int
Number_Of_Arcs_In();
void
Clear();
bool
Remove_Arc(Gen_Data_Ptr Source_Vertex, Gen_Data_Ptr Dest_Vertex,
Gen_Data_Ptr The_Arc);
void
Display_Graph();
bool
Create_An_Arc(Gen_Data_Ptr Source_Vertex, Gen_Data_Ptr Dest_Vertex,
Gen_Data_Ptr The_Attribute);
Vertex_Node
* Is_Member_Of(Gen_Data_Ptr The_Attribute);
int
Number_Of_Vertices_In();
bool
Remove_Vertex(Gen_Data_Ptr The_Source);
void
Display_Only_Vertex();
void
Insert(Gen_Data_Ptr The_Attribute);
Graph();
virtual
~Graph();
};
# endif /
/!defined(AFX_Graph_H__4D70C385_7844_11D1_BECF_444553540000__INCLUDED
_)
Also in this case therefore as it had happened
for the ARC_LIST the only private data is the gunlayer to the first
VERTEX_NODE pertaining to the list and in the Public part the
operations appear eseguibili standards on one list.
//Graph.cpp: implementation of the Graph class.
//
/
# it includes < iostream.h
>
# it includes "Graph.h"
# it includes "Vertex_Node.h"
/
//Construction/Destruction
/
Graph::Graph()
{
Head = 0;
}
Graph::~Graph()
{
}
/
void Graph::Insert(Gen_Data_Ptr The_Attribute)
{
if(Is_Member_Of(The_Attribute))
{
cerr < < "the apex is
already present in the graph ." < < endl;
return;
}
Vertex_Node * Vertex_Node_Ptr;
//Vertex_Node_Ptr tip to a new Vertex_Node
Vertex_Node_Ptr = new Vertex_Node(The_Attribute);
//places in head to the list the new apex
if(!Head)
{ // EMPTY LIST
Head = Vertex_Node_Ptr;
Vertex_Node_Ptr->Next_Vertex = 0;
}
else
{ // NOT EMPTY LIST
Vertex_Node_Ptr->Next_Vertex
= Head;
Head = Vertex_Node_Ptr;
}
}
void Graph::Display_Only_Vertex()
{
if(Head == 0)
{
cout < < "Not Vertex in this
Graph" < < endl;
}
else
{
Vertex_Node *
Vertex_Node_Ptr;
Vertex_Node_Ptr = Head;
while(Vertex_Node_Ptr! = 0)
{
// the cycle is repeated sin when it is not
NULL
Vertex_Node_Ptr->Display_Vertex();
Vertex_Node_Ptr = Vertex_Node_Ptr->Next_Vertex;
}
}
}
bool Graph::Remove_Vertex(Gen_Data_Ptr
Vertex_To_Remove)
{ // Point a
gunlayer to the head of the list
Vertex_Node * Vertex_Node_Ptr_1;
Vertex_Node *
Vertex_Node_Ptr_2;
Vertex_Node_Ptr_1 = Head ;
Vertex_Node_Ptr_2 = Head ;
//search of the node to remove
while((Vertex_Node_Ptr_1! = 0) &&
(!(Vertex_To_Remove->Is_Equal(Vertex_Node_Ptr_1->Vertex_Attribute))))
{
Vertex_Node_Ptr_2 =
Vertex_Node_Ptr_1;
Vertex_Node_Ptr_1 =
Vertex_Node_Ptr_1->Next_Vertex;
}
//
control that the apex exists and that it is not headed from some arc
if((Vertex_Node_Ptr_1! = 0)&&
((Vertex_Node_Ptr_1->Reference_Count == 0) ||
((Vertex_Node_Ptr_1->Reference_Count!=0) &&
(!(Vertex_To_Remove->Is_Equal(Vertex_Node_Ptr_1->Vertex_Attribute))))))
{
// gate all arches to it
outgoing from the apex
Arc_Node * Arc_Node_Ptr;
Arc_Node_Ptr =
Vertex_Node_Ptr_1->Arc_List_Ptr->Arc_List_Head;
while(Arc_Node_Ptr! = 0)
{// the cycle is repeated
sin when it is not NULL
Remove_Arc(Vertex_To_Remove,
Arc_Node_Ptr->Arc_Destination,
Arc_Node_Ptr->Arc_Attribute);
Arc_Node_Ptr =
Vertex_Node_Ptr_1->Arc_List_Ptr->Arc_List_Head;
}
//I
HAVE FOUND the ELEMENT TO REMOVE
if(Vertex_Node_Ptr_1! = Head)
Vertex_Node_Ptr_2->Next_Vertex =
Vertex_Node_Ptr_1->Next_Vertex;
else //the ARC TO REMOVE Is The FIRST One Of the LIST
Head = Head->Next_Vertex;
//I eliminate
vertice the
delete Vertex_Node_Ptr_1;
return true;
};
if(Vertex_Node_Ptr_1 == 0)
{
cerr < < "the apex to
eliminate has not been found" < < endl;
}
else
{
cerr < < "the apex is not
dismissable in how much destination of";
cerr < <
Vertex_Node_Ptr_1->Reference_Count < < "Arches." <
< endl;
}
return false;
}
int Graph::Number_Of_Vertices_In()
{
int N_Vertex = 0;
Vertex_Node
* Vertex_Node_Ptr;
Vertex_Node_Ptr = Head;
while(Vertex_Node_Ptr! = 0)
{ //the cycle is repeated
sin when it is not NULL
N_Vertex ;
Vertex_Node_Ptr =
Vertex_Node_Ptr->Next_Vertex;
}
return N_Vertex;
}
/
//it comes characterized, otherwise it comes
given back the gunlayer that closes list 0 that is and therefore the
function gives back
//FALSE if the apex does not come
characterized.
/
Vertex_Node * Graph::Is_Member_Of(Gen_Data_Ptr
The_Attribute)
{
Vertex_Node * Vertex_Node_Ptr;
Vertex_Node_Ptr = Head;
while((Vertex_Node_Ptr! = 0) &&
!(The_Attribute->Is_Equal(Vertex_Node_Ptr->Vertex_Attribute)))
{
Vertex_Node_Ptr =
Vertex_Node_Ptr->Next_Vertex;
}
return Vertex_Node_Ptr;
}
/
/
bool Graph::Create_An_Arc(Gen_Data_Ptr
Source_Vertex, Gen_Data_Ptr Dest_Vertex, Gen_Data_Ptr
The_Attribute)
{
Vertex_Node * Source_Vertex_Ptr;
Source_Vertex_Ptr = Is_Member_Of(Source_Vertex);
if(Source_Vertex_Ptr == 0)
{
cerr < < "the apex source is
inesistente\n";
return false;
}
Vertex_Node * Dest_Vertex_Ptr;
Dest_Vertex_Ptr = Is_Member_Of(Dest_Vertex);
if(Dest_Vertex_Ptr == 0)
{
cerr < < "the destination
apex is inesistente\n";
return false;
}
//Increment the reference count of the
destination arc
Dest_Vertex_Ptr->Reference_Count ;
//Creation of the arc
Source_Vertex_Ptr->Arc_List_Ptr->Insert(The_Attribute, Dest_Vertex);
return true;
}
/
/
void Graph::Display_Graph()
{
if(Head == 0)
{
cout < < "Not Vertex in this
Graph" < < endl < < endl;
}
else
{
Vertex_Node *
Vertex_Node_Ptr;
Vertex_Node_Ptr = Head;
while(Vertex_Node_Ptr! = 0)
{ //the cycle is repeated sin when it is not NULL
Vertex_Node_Ptr->Display_Vertex_And_Arcs();
Vertex_Node_Ptr =
Vertex_Node_Ptr->Next_Vertex;
}
}
}
/
/
bool Graph::Remove_Arc(Gen_Data_Ptr
Source_Vertex, Gen_Data_Ptr Dest_Vertex, Gen_Data_Ptr
The_Arc)
{
//control that the apex source exists
Vertex_Node * Source_Vertex_Ptr;
Source_Vertex_Ptr = Is_Member_Of(Source_Vertex);
if(Source_Vertex_Ptr == 0)
{
cerr < < "\nIl apex source
is nonexistent";
//monster the
list of you concern to us
Display_Only_Vertex();
return false;
}
Vertex_Node * Dest_Vertex_Ptr;
Dest_Vertex_Ptr = Is_Member_Of(Dest_Vertex);
if(Dest_Vertex_Ptr == 0)
{
cerr < < "\nIl destination
apex is nonexistent";
Source_Vertex_Ptr->Display_Vertex_And_Arcs();
return false;
}
Arc_Node * Arc_Node_Ptr;
Arc_Node_Ptr = Source_Vertex_Ptr->Arc_List_Ptr->Is_Member_Of(The_Arc,
Dest_Vertex);
if(Arc_Node_Ptr == 0)
{
cerr < < "\nL' arc to
eliminate is nonexistent";
Source_Vertex_Ptr->Display_Vertex_And_Arcs();
return false;
}
else
{
Source_Vertex_Ptr->Arc_List_Ptr->Remove(The_Arc, Dest_Vertex);
Dest_Vertex_Ptr->Reference_Count --;
return
true;
}
}
/
void Graph::Clear()
{
Vertex_Node * Vertex_Node_Ptr;
Vertex_Node_Ptr = Head;
//Removal of arches from all concerns to us
while(Vertex_Node_Ptr! = 0)
{ //the cycle is repeated sin when it is not NULL
Vertex_Node_Ptr->Arc_List_Ptr->Clear();
Vertex_Node_Ptr->Reference_Count =
0;
Vertex_Node_Ptr =
Vertex_Node_Ptr->Next_Vertex;
}
//Removal of you concern to us
Vertex_Node_Ptr = Head;
while(Vertex_Node_Ptr! = 0)
{ //the cycle is repeated
sin when it is not NULL
Remove_Vertex(Vertex_Node_Ptr->Vertex_Attribute);
Vertex_Node_Ptr = Head;
}
}
/
int Graph::Number_Of_Arcs_In()
{
int N_Arcs = 0;
Vertex_Node
* Vertex_Node_Ptr;
Vertex_Node_Ptr = Head;
while(Vertex_Node_Ptr! = 0)
{ //the cycle is repeated
sin when it is not NULL
N_Arcs
= N_Arcs (Vertex_Node_Ptr->Arc_List_Ptr->Number_Of_Arcs_In());
Vertex_Node_Ptr =
Vertex_Node_Ptr->Next_Vertex;
}
return N_Arcs;
}
b) Description and
implementation of the polimorfismo
With the term polimorfismo we mean the ability
to a class base to define of the functions which come redefined from
the derived classes, and the possibility of the compiler to execute
late binding that you recall the method for the just class derived by
means of a control on the recalling object the function.
Perhaps in such context the more meaningful application is just
this from we implemented that is the possibility to avoid to write for
every function others n functions in order to implement n possible
types of data.
The solution consists in setting up an abstract class
ELEMENT from which real classes to n various types of data derive n
relative, in our case have been implemented FLOAT_OBJ, INT_OBJ and
CHAR_OBJ, ognuna di.le which redefine the constructor, the Display
function and function IS_EQUAL subsequently described.
//Element.h: interface for the Element
class.
/
# if!defined(AFX_ELEMENT_H__25FF6141_7852_11D1_BECF_444553540000__INCLUDED
_)
# define AFX_ELEMENT_H__25FF6141_7852_11D1_BECF_444553540000__INCLUDED
_
# if _ MSC_VER > = 1000
# pragma ounces
# endif //_ MSC_VER > =
1000
typedef char Class_Name[20 ];
# it includes < string.h >
class Element
{
public:
virtual
bool Is_Equal(Element * Element_Ptr);
virtual
void Display();
char *
Get_Class();
Element();
virtual
~Element();
protected:
Class_Name
My_Class;
};
typedef Element * Gen_Data_Ptr;
//defines a gunlayer to the Element class
# endif /
/!defined(AFX_ELEMENT_H__25FF6141_7852_11D1_BECF_444553540000__INCLUDED
_)
This class has like only data protected and
therefore ereditabile from the derived classes the name of the class,
information that will be useful laddove of a data object will have to
determine which derived class belongs and if it is aimed from a
gunlayer to the class mother ELEMENT.
It comes moreover defined a gunlayer to this class that
then will be used in all the functions that will import ELEMENT.H in
order to characterize a gunlayer to a type of generic data.
The declaration of the functions public is following:
//Element.cpp: implementation of the Element
class.
//
/
# it includes "Element.h"
/
/
Element::Element()
{
strcpy(My_Class, "Element");
}
Element::~Element()
{
}
char * Element::Get_Class()
{
return My_Class;
}
/
void Element::Display()
{
}
bool Element::Is_Equal(Element * Element_Ptr)
{
return false;
}
We see hour as the derived classes redefine the
functions virtual of class ELEMENT:
//Int_Obj.h: interface for the Int_Obj
class.
/
# if!defined(AFX_INT_OBJ_H__25FF6142_7852_11D1_BECF_444553540000__INCLUDED
_)
# define AFX_INT_OBJ_H__25FF6142_7852_11D1_BECF_444553540000__INCLUDED
_
# if _ MSC_VER > = 1000
# pragma ounces
# endif //_ MSC_VER > =
1000
# it includes "Element.h"
class Int_Obj: public Element
{
public:
void
Display();
bool
Is_Equal(Element * Element_Ptr);
int
Get_Val();
Int_Obj();
Int_Obj(int
Int_Data);
virtual
~Int_Obj();
protected:
int Value;
};
# endif /
/!defined(AFX_INT_OBJ_H__25FF6142_7852_11D1_BECF_444553540000__INCLUDED
_)
In this case the only data protected is Value
which it is accessible solo from the Int_Obj class and they do not
give to the class mother that it imposes that even if the code of the
Display is equal for all and the 3 derived classes, such code is not
implementabile in the class base.
The correspondent declaration is following:
//Int_Obj.cpp: implementation of the Int_Obj
class.
/
# it includes < iostream.h
>
# it includes "Int_Obj.h"
/
//Construction/Destruction
/
Int_Obj::Int_Obj()
{
strcpy(My_Class, "Int_Obj");
}
Int_Obj::~Int_Obj()
{
}
/
Int_Obj::Int_Obj(int Int_Data)
{
strcpy(My_Class, "Int_Obj");
Value =
Int_Data;
}
/
//
Get_Val
/
Int_Obj::Get_Val()
{
return Value;
}
/
//
Display
/
void Int_Obj::Display()
{
cout < < Value;
}
/
bool Int_Obj::Is_Equal(Element * Element_Ptr)
{
//the strcmp gives back 0 if the 2 stringhe they
are equal
if(strcmp(Element_Ptr->Get_Class(), "Int_Obj"))
return false;
else
{
// I convert the generic
gunlayer in a gunlayer to entire
Int_Obj * Int_Obj_Ptr = (Int_Obj *)Element_Ptr;
//comparison the
data heads to you from the 2 gunlayers
return(Get_Val()==(Int_Obj_Ptr->Get_Val()));
}
}
/
# if!defined(AFX_HAR_OBJ_H__882EFA81_7A44_11D1_BECF_444553540000__INCLUDED
_)
# define AFX_HAR_OBJ_H__882EFA81_7A44_11D1_BECF_444553540000__INCLUDED
_
# if _ MSC_VER > = 1000
# pragma ounces
# endif //_ MSC_VER > =
1000
# it includes "Element.h"
class Char_Obj: public Element
{
protected:
char Value;
public:
Char_Obj();
Char_Obj(char Char_Data);
virtual
~Char_Obj();
void
Display();
bool
Is_Equal(Element * Element_Ptr);
char
Get_Val();
};
# endif /
/!defined(AFX_HAR_OBJ_H__882EFA81_7A44_11D1_BECF_444553540000__INCLUDED
_)
The correspondent declaration is following:
//Char_Obj.cpp: implementation of the Char_Obj
class.
//
/
# it includes "har_Obj.h"
# it includes <
iostream.h >
/
//Construction/Destruction
/
Char_Obj::Char_Obj()
{
strcpy(My_Class, "Char_Obj");
}
/
Char_Obj::Char_Obj(char Char_Data)
{
strcpy(My_Class, "Char_Obj");
Value =
Char_Data;
}
Char_Obj::~Char_Obj()
{
}
/
//
GET_VAL
/
char Char_Obj::Get_Val()
{
return Value;
}
bool Char_Obj::Is_Equal(Element *
Element_Ptr)
{
//the strcmp gives back 0 if the 2 stringhe they
are equal
if(strcmp(Element_Ptr->Get_Class(),
"Char_Obj"))
return false;
else
{
// I convert the generic
gunlayer in a gunlayer
//to
entire
Char_Obj * Char_Obj_Ptr =
(Char_Obj *)Element_Ptr;
//comparison the
data heads to you from the 2 gunlayers
return(Get_Val()==(Char_Obj_Ptr->Get_Val()));
}
}
/
/
void Char_Obj::Display()
{
cout < < Value;
}
//Float_Obj.h: interface for the
Float_Obj class.
/
# if!defined(AFX_FLOAT_OBJ_H__882EFA82_7A44_11D1_BECF_444553540000__INCLUDED
_)
# define AFX_FLOAT_OBJ_H__882EFA82_7A44_11D1_BECF_444553540000__INCLUDED
_
# if _ MSC_VER > = 1000
# pragma ounces
# endif //_ MSC_VER > =
1000
# it includes "Element.h"
class Float_Obj: public Element
{
public:
Float_Obj();
Float_Obj(float Float_Data);
virtual
~Float_Obj();
void
Display();
bool
Is_Equal(Element * Element_Ptr);
float
Get_Val();
protected:
float
Value;
};
# endif /
/!defined(AFX_FLOAT_OBJ_H__882EFA82_7A44_11D1_BECF_444553540000__INCLUDED
_)
The declaration of class FLOAT_OBJ is following:
//Float_Obj.cpp: implementation of the Float_Obj
class.
//
# it includes <
iostream.h >
# it includes "Float_Obj.h"
/
//Construction/Destruction
/
Float_Obj::Float_Obj()
{
strcpy(My_Class, "Float_Obj");
}
Float_Obj::~Float_Obj()
{
}
/
/
Float_Obj::Float_Obj(float Float_Data)
{
strcpy(My_Class, "Float_Obj");
Value =
Float_Data;
}
/
//
GET_VAL
/
float Float_Obj::Get_Val()
{
return Value;
}
/
//
IS_EQUAL
/
bool Float_Obj::Is_Equal(Element *
Element_Ptr)
{
//the strcmp gives back 0 if the 2 stringhe they
are equal
if(strcmp(Element_Ptr->Get_Class(),
"Float_Obj"))
return false;
else
{
//I
convert the generic gunlayer in a gunlayer to Float_Obj
Float_Obj * Float_Obj_Ptr = (Float_Obj *)Element_Ptr;
//comparison
the data heads to you from the 2 gunlayers
return(Get_Val()==(Float_Obj_Ptr->Get_Val()));
}
}
/
//
DISPLAY
/
void Float_Obj::Display()
{
cout < < Value;
}
As these classes can be used in order to
implement a graph with arch and concern having attributes to us of
whichever kind between this hour defined are illustrated in the
following paragraph.
c) applicativo Development based on class GRAPH
Applicativo following is born from the
requirement to see to work the member function defined for the Graph
class therefore is limited to set up a menu of the eseguibili
operations on the same one, to ognuna di.le which a function is
associated that, laddove necessary, supplies to demand to the customer
of the income data which to eempio the attributes for the arc or the
apex of destination or the apex source. The Type_Selection
function is moreover present that for everyone of the cases over
points out to you concurs with the customer to insert the tipologia of
since it agrees to insert, such function will not make other that to
go to istanziare the just object between FLOAT_OBJ, CHAR_OBJ and
INT_OBJ and making to aim it from one of the gunlayers to having class
ELEMENT general visibility ossia Source_Name_Ptr, Dest_Name_Ptr
ed Arc_Name_Ptr.
# it includes "Graph.h"
# it includes "Arc_List.h"
# it includes "Element.h"
# it includes "Int_Obj.h"
# it includes "har_Obj.h"
# it includes "Float_Obj.h"
# it includes < ctype.h
>
# it includes < string.h
>
# it includes <
iostream.h>
# it includes < conio.h >
//MANIPULATING OF THE GRAFO
void Insert();
void Create();
void Display();
void Number_Of_Vertices_In();
void Number_Of_Arcs_In();
void Right y_Arc();
void Right y_Vertex();
void Right y_Graph();
char Type_Selection();
void Set_Arc_Name();
void Set_Source_Vertex_Name();
void Set_Dest_Vertex_Name();
Element * Source_Name_Ptr, * Dest_Name_Ptr, *
Arc_Name_Ptr ;
Graph * My_Graph ;
void main()
{
cout<<"\n\n";
cout<<"
____________________________________________________________ \n";
cout<<" |
|\n ";
cout<<"
| - PROGRAM OF MANAGEMENT OF A ORIENTED
GRAFO - |\n ";
cout<<" |____________________________________________________________ |\n ";
cout<<"
|
* Version 1.0 *
|\n ";
cout<<"
|
****************
|\n ";
cout<<"
|
|\n ";
cout<<"
|
Programmers:
|\n ";
cout<<"
|
------------
|\n ";
cout<<"
|
|\n ";
cout<<"
|
|\n ";
cout<<"
|
|\n ";
cout<<"
|
|\n ";
cout<<"
|
|\n ";
cout<<" | IANNONE ALESSIO CRICKETS GIANLUCA
D`OTTAVIO ANTONIO |\n ";
cout<<" |
|\n ";
cout<<"
|__________________________________________________________ __|\n ";
char response
;
cin > > response
;
cout < < "\n\n\n\n\n\n\n\n\n\n\n\n"
;
bool again
;
My_Graph = new Graph
;
I give
{
cout<<"\n";
cout < < "
************************************************************ \n";
cout < < " * Prego to select one
of the following options:
* \n";
cout < < "
* 1) Insertion of vertice a
* \n";
cout < < "
* 2) Insertion of arco a
* \n";
cout < < "
* 3) Visualizzazione
* \n";
cout < < "
* 4) Determination of the number of
vertici
* \n";
cout < < "
* 5) Determination of the number of archi
* \n";
cout < < "
* 6) Elimination of arco a
* \n";
cout < < "
* 7) Elimination of vertice a
* \n";
cout < < "
* 8) Elimination of graph a
* \n";
cout < < "
* 0) Fine
* \n ";
cout < < "
************************************************************* \n";
cin > >
response;
cout<<"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
switch(response)
{
houses ' 1 ':
cout < <
"\t\t\t**********************************\n";
cout < < "\t\t\t*
Insertion of vertice a * \n";
cout < <
"\t\t\t**********************************\n\n";
Insert() ;
again =
true;
continue ;
houses ' 2 ':
cout < <
"\t\t\t**********************************\n";
cout < < "\t\t\t*
Insertion of arco a
* \n";
cout < <
"\t\t\t**********************************\n\n";
Create();
again =
true;
continue ;
houses ' 3 ':
cout < <
"\t\t\t**********************************\n";
cout < < "\t\t\t*
Visualization of the Graph
* \n";
cout < <
"\t\t\t**********************************\n\n";
Display() ;
again =
true;
continue ;
houses ' 4 ':
cout < <
"\t\t\t**********************************\n";
cout < < "\t\t\t*
Determination of the n of vertici *
\n";
cout < <
"\t\t\t**********************************\n\n";
Number_Of_Vertices_In();
again = true;
continue
;
houses ' 5 ':
cout < <
"\t\t\t**********************************\n";
cout < <
"\t\t\t* Determination of the n of arches
* \n";
cout < <
"\t\t\t**********************************\n\n";
Number_Of_Arcs_In();
again = true;
continue
;
houses ' 6 ':
cout < <
"\t\t\t**********************************\n";
cout < <
"\t\t\t* Elimination of arco a
* \n";
cout < <
"\t\t\t**********************************\n\n";
Right y_Arc();
again =
true ;
continue ;
houses ' 7 ':
cout < <
"\t\t\t**********************************\n";
cout < < "\t\t\t*
Elimination of vertice a
* \n";
cout < <
"\t\t\t**********************************\n\n";
Right y_Vertex();
again =
true;
continuous;
houses ' 8 ':
cout < <
"\t\t\t**********************************\n";
cout < < "\t\t\t*
Elimination of graph the
* \n";
cout < <
"\t\t\t**********************************\n\n";
Right y_Graph();
again =
true;
continuous;
houses ' 0 ':
cout < <
"\t\t\t**********************************\n";
cout < < "\t\t\t*
See You......
* \n ";
cout < <
"\t\t\t**********************************\n\n";
again = false;
continuous;
default:
again = true;
continuous;
fine }// of the switch
Fine }
//of I give
while(again);
}
/
void Insert()
{
Set_Source_Vertex_Name();
My_Graph->Insert(Source_Name_Ptr);
}
/
/
void Create()
{
Set_Source_Vertex_Name();
Set_Dest_Vertex_Name();
Set_Arc_Name();
My_Graph->Create_An_Arc(Source_Name_Ptr, Dest_Name_Ptr, Arc_Name_Ptr);
}
/
/
void Display()
{
My_Graph->Display_Graph();
}
/
void Number_Of_Vertices_In()
{
cout < < "In the Graph is present";
cout < < My_Graph->Number_Of_Vertices_In();
cout < < "you concern to us." < < endl;
}
/
void Number_Of_Arcs_In()
{
cout < < "In the Graph is present";
cout < < My_Graph->Number_Of_Arcs_In();
cout < < "arches." < < endl;
}
/
void Right y_Arc()
{
Set_Source_Vertex_Name();
Set_Dest_Vertex_Name();
Set_Arc_Name();
My_Graph->Remove_Arc(Source_Name_Ptr, Dest_Name_Ptr, Arc_Name_Ptr);
}
/
void Right y_Vertex()
{
Set_Source_Vertex_Name();
My_Graph->Remove_Vertex(Source_Name_Ptr);
}
/
/
void Right y_Graph()
{
My_Graph->Clear();
}
/
/
char Type_Selection()
{
char Data_Type;
cout < <
"\t***************************************************************\n";
cout < <
"\t* C)
Char
-128 to 127
* \n ";
cout < < "\t*
F) Float 3.4*(10**-38)
to 3.4*(10** 38)
* \n";
cout < <
"\t*
I) Int -2,147,483,648 to
2,147,483,647
* \n";
cout < <
"\t***************************************************************\n";
cin > >
Data_Type;
return (toupper(Data_Type));
}
void Set_Source_Vertex_Name()
{
bool again;
cout < < "To
select the type of data for the apex sorgente:\n\n";
I give
{
switch(Type_Selection())
{
houses ' There:
char
Char_Data;
cout < <
"Immettere the attribute (Char): ";
cin > >
Char_Data;
Source_Name_Ptr = new Char_Obj(Char_Data);
again =
false;
continuous;
houses ' I':
int
Int_Data;
cout < <
"Immettere the attribute (Long Int): ";
cin > >
Int_Data;
Source_Name_Ptr = new Int_Obj(Int_Data);
again =
false;
continuous;
houses ' F':
float
Float_Data;
cout < <
"Immettere the attribute (Float): ";
cin > >
Float_Data;
Source_Name_Ptr = new Float_Obj(Float_Data);
again =
false;
continuous;
default:
again =
true;
cout < <
"\n\n\n\n\n\n\n\n\n\n\n\n";
continuous;
}
}while(again == true);
cout < <
"\n\n\n\n\n\n";
}
void Set_Dest_Vertex_Name()
{
bool again;
cout < < "To select the type of data for the apex of
destinazione:\n\n";
I give
{
switch(Type_Selection())
{
houses ' There:
char
Char_Data;
cout < <
"Immettere the attribute (Char): ";
cin > >
Char_Data;
Dest_Name_Ptr = new Char_Obj(Char_Data);
again =
false;
continuous;
houses ' I':
int
Int_Data;
cout < <
"Immettere the attribute (Long Int): ";
cin > >
Int_Data;
Dest_Name_Ptr = new Int_Obj(Int_Data);
again =
false;
continuous;
houses ' F':
float
Float_Data;
cout < <
"Immettere the attribute (Float): ";
cin > >
Float_Data;
Dest_Name_Ptr = new Float_Obj(Float_Data);
again =
false;
continuous;
default:
again =
true;
continuous;
}
}while(again == true);
cout < <
"\n\n\n\n\n\n";
}
/
void Set_Arc_Name()
{
bool again;
cout < < "To select the type of data for the arc:\n\n";
I give
{
switch(Type_Selection())
{
houses ' There:
char
Char_Data;
cout < <
"Immettere the attribute (Char): ";
cin > >
Char_Data;
Arc_Name_Ptr = new Char_Obj(Char_Data);
again =
false;
continuous;
houses ' I':
int
Int_Data;
cout < <
"Immettere the attribute (Long Int): ";
cin > >
Int_Data;
Arc_Name_Ptr = new Int_Obj(Int_Data);
again =
false;
continuous;
houses ' F':
float
Float_Data;
cout < <
"Immettere the attribute (Float): ";
cin > >
Float_Data;
Arc_Name_Ptr = new Float_Obj(Float_Data);
again =
false;
continuous;
default:
again =
true;
continuous;
}
}while(again == true);
cout < <
"\n\n\n\n\n\n";
}