Estructura de dades - 24967
Junio 1999

  1. Dada la clase X y la ejecución de las sentencias 1) 2) 3) 4):

Class X
{
char *p_c;
Public:
X(char *p)
{
p_c=new char(strlen(p)+1);
strcpy(p_c,p);
}
// imprimir el valor del puntero p_c
print()
{
printf("%p\n",p_c);
}
};


1) X a("xxxx");
2) X b=a;
3) a.print();
4) b.print();
     Es un constructor de compilación porque en la clase X no está definido el constructor de copia
     En 3) y 4) se imprimen valores distintos
     Error de compilación porque en la clase X no está definido el operador =
       En 3) y 4) se imprime el mismo valor
       No contesto...
 
  2. Dada una clase X y la ejecución de las siguientes sentencias en el orden dado:
1) X a;
2) X b;
3) X c=a;
4) b=c;
     En 3) se llama al constructor de copia y en 4) al operador =
     En 3) y 4) se produce una llamada al operador =
     En 3) y 4) se produce una llamada al constructor de copia
       En 4) se llama al constructor de copia y en 3) al operador =
       No contesto...
 
  3. Una clase template X, permite más de un parámetro template < class A, class B > class X {....};
     El segundo puede ser de cualquier tipo (class B)
     Sólo si el segundo es un valor predefinido ( pe. int z=5)
     Sólo si el segundo es para gestión de memoria
       Ninguna de las anteriores
       No contesto...
 
  4. La herencia privada en C++, class Z:private X{....};
     Convierte todos los miembros protected y public de la clase base (X) en privados de la clase derivada (Z)
     Impide el polimorfismo porque no hay conversiones de tipo implícitas
     Es equivalente a: class Z {
X x;
public:
....
};
con la diferencia de que si usamos herencia la calse Z puede utilizar los miembros de la parte protected de la clase
       Todas las anteriores
       No contesto...
 
  5. Los iteradores de la biblioteca STL que poseen todas las características de los punteros son:
     Los forward
     Los de acceso aleratorio (random)
     Los bidireccionales
       Los de input/output
       No contesto...
 
  6. El uso de templates para la construcción de containers (listas, pilas, colas, etc.):
     Permite cambiar las implementaciones de forma sencilla
     No afecta la eficiencia en tiempo de ejecución
     Permite un control estricto de tipos
       Todas las anteriores
       No contesto...
 
  7. Una lista donde los objetos almacenados se derivan del enlace (tipo I):
     Es óptima en cuanto a espacio/tiempo
     Permite la inserción de objetos duplicados de forma sencilla e inmediata
     Permite una recuperación eficiente de objetos float e int
       Todas las anteriores
       No contesto...
 
  8. La estructura que permite insertar y eliminar objetos en posiciones intermedias en tiempo constante es:
     Heap
     Vector
     Lista
       Ninguna de las anteriores
       No contesto...
 
  9. La organización de un vector en memoria
     Garantiza que los objetos en posiciones consecutivas del vector serán almacenados en posiciones consecutivas de memoria. Si no hay suficiente espacio consecutivo se produce un erro
     La relación entre posiciones del vector y las direcciones de memoria física dependerá de la gestión de memoria que se utilice
     Garantiza que los objetos en posiciones consecutivas del vector serán almacenados en posiciones consecutivas de memoria pero si no hay suficiente espacio consecutivo se utilizan fr
       Ninguna de las anteriores
       No contesto...
 
  10. La representación de un árbol binario mediante un vector:
     El árbol tiene que ser parcialmente ordenado para poder utilizar un vector
     Se puede utilizar el vector si queremos construir árboles enhebrados
     Sólo es aconsejable si el árbol es balanceado
       No se puede utilizar un vector
       No contesto...
 
  11. En un árbol de búsqueda binaria de n nodos:
     Se puede conseguir eficiencias de búsqueda del orden de log n
     A se comple mejor cuando más balanceado sea el árbol
     A y B
       El hecho de que esté más o menos balanceado no influye en la eficiencia de búsqueda
       No contesto...
 
  12. La estructura heap
     Es un vector ordenado
     Es un árbol binario parcialmente ordenado
     Es un arbol binario balanceado y parcialmente ordenado
       Ninguna de las anteriores
       No contesto...
 
  13. En un árbol enhebrado:
     Los algoritmos de recorrido de cualquier tipo son muy simples de codificar sin utilizar pilas
     Sólo el algoritmo de recorrido de un tipo (aquel que coincida con la forma en que el árbol fue construido) se puede codificar de forma simple sin utilizar pilas
     El enhebrado no tiene ningún efecto sobre los algoritmos de recorrido
       Normalmente existen muy pocas hebras y su uso principal viene de lo simple que es la inserción y eliminación de nodos
       No contesto...
 
  14. En los grafos el algoritmo de Warshall sirve para:
     Calcular la matriz de caminos a partir de la matriz de adyacencias
     Calcular la matriz de caminos a partir de la lista de adyacencias
     Recorrido primero en profundidad (DFS), a partir de la matriz de adyacencias
       Recorrido primero en amplitud (BFS), a partir de la lista de adyacencias
       No contesto...
 
  15. La representación de un grafo de n nodos y e aristas mendiante una matriz de adyacencia permite algoritmos con una complejidad que, en general, puede ser del orden de:
     La suma de n + e
     El cuadrado de n
     La complejidad algorítmica no depende de la estructura utilizada para implementar el grafo
       Ninguna de las anteriores
       No contesto...
 
  16. La representación de un grafo mediante una matriz de adyacencias es eficiente para:
     Recorridos primero en amplitud (breadth first search)
     Recorridos primero en profundidad (depth first search)
     La eficiencia que se obtiene mediante las matrices desaconseja utilizarlas para representar grafos siempre que exista alguna alternativa
       Ninguna de las anteriores
       No contesto...
 
  17. Tenim una implementació circular de la cua, tenim per declaracions:

class VectorSenser
{
protected:
int *Contingut;
int Tamany;
public:
...
};

class CuaSenser: public VectorSenser
{
int *Top;
int *Inici;
public:
int Status;
int EmptyQueue;
CuaSenser();
CuaSenser(unsigned int TamanyMaxim);
int Size();
void Push(int Element);
int Pop();
~CuaSenser();
};

Quina de les següents afirmacions es certa:
     El nombre d'elements ocupats de la cua es (Top-Contingut)
     Inici mai pot ser més gran que Top, perquè estariem sobrepassant el tamany màxim de la cua circular
     Si (Inici > Top), el nombre de posicions lliures (no ocupades) de la cua serà (Inici-Top)
       Si Top és més petit que Inici, aleshores el nombre d'elements ocupats és (*Top-*Contingut)+(*Contingut+Tamany-*Inici)
       Si Top=Inici i Inici=Contingut la cua ha d'estar buida
       No contesto...
 
  18. Hem implementat un arbre binari de "busqueda", mitjançant una classe template Arbre i una classe template NodeArbol. La primera te un apuntador al node arrel de l'arbre (que es diu arrel), i la classe NodeArbol, te un camp Dada, i dos apuntadors, un al seu fill dret (NodeDrt), i un al seu fill esquerra (NodeEsq).
Donada la següent implementació de la inserció en l'arbre,
template < class Tipus >
void Arbre< Tipus >::Insertar(const Tipus &x)
{
NodeArbol< Tipus > *p = arrel;
NodeArbol< Tipus > *q = 0;

while (p)
{
q=p;
if (x>p->Dada) p=p->NodEsq;
else p=p->NodeDrt;
}

p=new NodeArbre< Tipus >;
p -> NodeEsq = p-> NodeDrt=0;
p-> Dada=x;

if (!arrel) arrel=p;
else if (x > q->Dada) q-> NodeEsq=p;
else q->NodeDrt=p;
}

Es demana, que doneu la sortida obtinguda al fer un recorregut de l'arbre en POSTORDRE, tenint en compte que a l'arbre s'ha inserit els elements (7,9,8,10,0,4,7,2), en l'ordre indicat
     2 4 0 7 8 10 9 7
     10 9 8 7 7 4 2 0
     0 2 4 7 7 8 9 10
       10 8 9 7 2 4 0 7
       10 8 9 7 7 2 4 0
       No contesto...
 
  19. Tenint en compte els constructor definits per la classe node que es mostren a continuació,
class CNode;

class CNode
{
CNode *Esquerra;
float Data;
CNode *Dret;
public:
CNode (float num) { Esquerra=0;Dreta=0;Data=num;};
CNode (CNode &E, float num, CNode &D);
CNode (float num, CNode &D);
CNode (CNode &E, float num);
CNode (CNode &Node);
~CNode () {if (Esquerra) delete Esquerra; if (Dret) delete Dret;};
friend ostream & operator << (ostream & os, CNode & Node);
};

CNode::CNode(CNode &E,float num) { Data=num;Esquerra=new CNode(E);Dret=0;};
CNode::CNode(float num,CNode &D) { Data=num;Dret=new CNode(D);Esquerra=0;};
CNode::CNode(CNode &E,float num, CNode &D) { Esquerra=new CNode(E); Data=num; Dret=new CNode(D);};

CNode::CNode(CNode &Node)
{
Data = Node.Data;
if (Node.Esquerra)
{
Esquerra = new CNode (*(Node.Esquerra));
}
else Esquerra=0;

if (Node.Dret)
{
Dret=new CNode (* (Node.Dret));
}
else Dret=0;
};

Indiqueu quina seria la estructura d'arbre creada al executar el següent codi:
CNode Arbre(CNode(5),4,CNode(3,CNode(CNode(0),6,CNode(7,CNode(9)))));
     (5)
/ \
(3) (4)
/ /
(0) (6)
/ \
(7) (9)
     (5)
/ \
(6) (4)
/ \
(7) (3)
/ \
(9) (0)
     (4)
/ \
(5) (3)
\
(6)
/ \
(0) (7)
\ (9)
       (5)
/ \
(4) (6)
/ \
(3) (7)
/ \
(0) (9)
       (4)
/ \
(5) (3)
/
(0)
\
(6)
\
(7)
\
(9)
       No contesto...
 
  20. Tenint en compte la definició de la classe CNode del exercici anterior, indicar quina de les següents possibilitats, és una implementació recursiva correcta de la sobrecarga del operador d'enviament a stream,per tal d'obtenir un recorregut de l'arbre en inordre
     ostream &CNode::operator << (ostream &os, CNode &Node) {
if (Node.Esquerra os << Node.Esquerra;
os << Node.Data;
if(Node.Dret) os << Node.Dret;
return os; }
     ostream & operator << (ostream &os, CNode &Node) {
if(Node.Esquerra) cout << *(Node.Esquerra);
cout << Node.Data;
if(Node.Dret) cout << *(Node.Dret);
return os; }
     friend ostream &CNode::operator << (ostream &os, CNode &Node) {
if (Esquerra) os << *Esquerra;
os << Data;
if (Dret) os << *Dret;
return os;}
       ostream & operator << (ostream &os, CNode &CNode) {
if(Node.Esquerra) cout << Node->Esquerra;
cout << Node.Data;
if(Node.Dret) cout << Node->Dret;
return os;}
       Cap de les implementacions és correcta
       No contesto...
 

Check...