Professional Documents
Culture Documents
Algoritmos
Contenido
n Listas
n Tipos abstractos de datos (ADTs
(ADTs))
n El ADT lista
n Implementació
Implementación usando arreglos
n Listas encadenadas
n Aplicaciones
n Implementació
Implementación mediante cursores
n El ADT pila (Stack
(Stack))
n Implementació
Implementación de pilas
n Aplicaciones
n El ADT cola
n Implementació
Implementación de colas
n Aplicaciones
1
Contenido
2
El ADT Lista
3
Lista usando arreglos
n Se de estimar el tamañ
tamaño del arreglo, lo que
puede resultar en un desperdicio de espacio.
n Las operaciones printList,
printList, find,
find, insert y
remove son O(N),
O(N), mientras que findKth es
O(1). (Si la lista esta ordenada por una clave
comparable el tiempo de find es O(log N)).
n Crear una lista mediante sucesivas inserciones
es O(N2).
4
Ejemplo: una lista ordenada de
números
public int find(double searchKey) {
int lowerBound = 0;
int upperBound = nElems-1;
int curIn;
while(true){
curIn = (lowerBound + upperBound ) / 2;
if(a[curIn]==searchKey)
return curIn; // found it
else if(lowerBound > upperBound)
return nElems; // can't find it
else { // divide range
if(a[curIn] < searchKey)
lowerBound = curIn + 1; // it's in upper half
else
upperBound = curIn - 1; // it's in lower half
} // end else divide range
} // end while
} // end find()
5
Ejemplo: una lista ordenada de
números
6
Listas encadenadas
n A diferencia de los arreglos los elementos
no está
están almacenados en forma contigua.
n Cada elemento, ademá
además de la data,
contiene una referencia a la ubicació
ubicación del
pró
próximo elemento.
n Los tiempos para insert y remove son
O(1), mientras que find y findKth
requieren O(N).
O(N).
A1 A2 A3 A4 A5
A1 A2 A3 A4 A5
A1 A2 A3 A4 A5
Agregando un elemento
en una lista encadenada X
7
Cabeza de lista
A1 A2 A3 A4
header
header
Una lista vacía
Nodos de la lista
package DataStructures;
class ListNode
{
// Constructors
ListNode( Object theElement )
{
this( theElement, null );
}
ListNode( Object theElement, ListNode n )
{
element = theElement;
next = n;
}
// Friendly data; accessible by other package routines
Object element;
ListNode next;
}
8
Iteradores
public class LinkedListItr {
LinkedListItr( ListNode theNode ) {
current = theNode;
}
public boolean isPastEnd( ) {
return current == null;
}
public Object retrieve( ) {
return isPastEnd( ) ? null : current.element;
}
public void advance( ) {
if( !isPastEnd( ) )
current = current.next;
}
private ListNode current; // Current position
}
La clase LinkedList
public class LinkedList {
private ListNode header;
public LinkedList( )
{
header = new ListNode( null );
}
public boolean isEmpty( )
{
return header.next == null;
}
public void makeEmpty( )
{
header.next = null;
}
public LinkedListItr zeroth( )
{
return new LinkedListItr( header );
}
9
La clase LinkedList
public LinkedListItr first( )
{
return new LinkedListItr( header.next );
}
public void insert( Object x, LinkedListItr p )
{
if( p != null && p.current != null )
p.current.next = new ListNode( x,
p.current.next );
}
public LinkedListItr find( Object x )
{
ListNode itr = header.next;
while( itr != null && !itr.element.equals( x ) )
itr = itr.next;
return new LinkedListItr( itr );
}
La clase LinkedList
10
La clase LinkedList
System.out.println( );
}
A1 A2 A3 A4 A5
A1 A2 A3 A4 A5
11
El ADT polinomio
n Se definirá
definirá un tipo de datos abstracto para
representar polinomios de una variable de la
forma: N
f ( x ) = ∑ ai x i
i=0
12
Polinomios usando arreglos
public Polynomial add( Polynomial rhs )
{
Polynomial sum = new Polynomial( );
sum.highPower = max( highPower, rhs.highPower );
for( int i = sum.highPower; i >= 0; i-- )
sum.coeffArray[i] = coeffArray[i] + rhs.coeffArray[i];
return sum;
}
public Polynomial multiply( Polynomial rhs ) throws Overflow
{
Polynomial product = new Polynomial( );
product.highPower = highPower + rhs.highPower;
if( product.highPower > MAX_DEGREE )
throw new Overflow( );
for( int i = 0; i <= highPower; i++ )
for( int j = 0; j <= rhs.highPower; j++ )
product.coeffArray[i+j]+=coeffArray[i]*rhs.coeffArray[j];
return product;
}
13
Polinomios usando listas
10 1000 5 14 1 0
P1
El polinomio 10 x1000 + 5x14 + 1
3 1990 -2 1492 11 1 5 0
P2
El polinomio 3x1990 − 2 x1492 + 11x + 5
Multilistas
S1 S2 S3 S4
C1
C2
C3
C4
C5
14
Listas encadenadas usando
cursores
n Se usa un arreglo para almacenar los nodos.
n Deben simularse las caracterí
características de las listas
encadenadas:
n Cada nodo contiene un enlace al siguiente. En el caso
de cursores los enlaces son índices del arreglo
n Se pueden obtener nuevos nodos cuando se
necesitan y los nodos son automá
automáticamente re-re-usados
al disponer de ellos.
n Esta implementació
implementación puede hacerse en
lenguajes que no manejan memoria diná
dinámica.
15
Iterador para CursorList
public class CursorListItr {
CursorListItr( int theNode ) {
current = theNode;
}
public boolean isPastEnd( ) {
return current == 0;
}
public Object retrieve( ) {
return isPastEnd( ) ? null :
CursorList.cursorSpace[ current ].element;
}
public void advance( ) {
if( !isPastEnd( ) )
current = CursorList.cursorSpace[ current ].next;
}
int current; // Current position
}
CusorList
public class CursorList
{
private static int alloc( )
{
int p = cursorSpace[ 0 ].next;
cursorSpace[ 0 ].next = cursorSpace[ p ].next;
if( p == 0 )
throw new OutOfMemoryError( );
return p;
}
16
CusorList
public CursorList( )
{
header = alloc( );
cursorSpace[ header ].next = 0;
}
public boolean isEmpty( )
{
return cursorSpace[ header ].next == 0;
}
public void makeEmpty( )
{
while( !isEmpty( ) )
remove( first( ).retrieve( ) );
}
public CursorListItr zeroth( )
{
return new CursorListItr( header );
}
CusorList
public CursorListItr first( )
{
return new CursorListItr( cursorSpace[ header ].next );
}
public void insert( Object x, CursorListItr p )
{
if( p != null && p.current != 0 )
{
int pos = p.current;
int tmp = alloc( );
cursorSpace[ tmp ].element = x;
cursorSpace[ tmp ].next = cursorSpace[ pos ].next;
cursorSpace[ pos ].next = tmp;
}
}
17
CusorList
public CursorListItr find( Object x )
{
int itr = cursorSpace[ header ].next;
while( itr != 0 && !cursorSpace[ itr].element.equals(x))
itr = cursorSpace[ itr ].next;
return new CursorListItr( itr );
}
public CursorListItr findPrevious( Object x )
{
int itr = header;
while( cursorSpace[ itr ].next != &&
!cursorSpace[cursorSpace[itr].next].element.equals(x))
itr = cursorSpace[ itr ].next;
return new CursorListItr( itr );
}
CusorList
public void remove( Object x ) {
CursorListItr p = findPrevious( x );
int pos = p.current;
if( cursorSpace[ pos ].next != 0 ) {
int tmp = cursorSpace[ pos ].next;
cursorSpace[ pos ].next = cursorSpace[ tmp ].next;
free( tmp ); }
}
static public void printList( CursorList theList ) {
if( theList.isEmpty( ) )
System.out.print( "Empty list" );
else {
CursorListItr itr = theList.first( );
for( ; !itr.isPastEnd( ); itr.advance( ) )
System.out.print( itr.retrieve( ) + " " ); }
System.out.println( );
}
18
CusorList
private int header;
static CursorNode[ ] cursorSpace;
private static final int SPACE_SIZE = 100;
static
{
cursorSpace = new CursorNode[ SPACE_SIZE ];
for( int i = 0; i < SPACE_SIZE; i++ )
cursorSpace[ i ] = new CursorNode( null, i + 1 );
cursorSpace[ SPACE_SIZE - 1 ].next = 0;
}
public static void main( String [ ] args )
{
CursorList theList = new CursorList( );
CursorListItr theItr;
int i;
theItr = theList.zeroth( );
printList( theList );
CusorList
for( i = 0; i < 10; i++ )
{
theList.insert( new MyInteger( i ), theItr );
printList( theList );
theItr.advance( );
}
19
El ADT Pila (Stack)
20
Pilas usando listas encadenadas
public class StackLi
{
public StackLi( )
{
topOfStack = null;
}
public boolean isFull( )
{
return false;
}
public boolean isEmpty( )
{
return topOfStack == null;
}
public void makeEmpty( )
{
topOfStack = null;
}
21
Pilas usando listas encadenadas
public void push( Object x )
{
topOfStack = new ListNode( x, topOfStack );
}
22
Pilas usando arreglos
public void makeEmpty( )
{
topOfStack = -1;
}
public Object top( )
{
if( isEmpty( ) )
return null;
return theArray[ topOfStack ];
}
public void pop( ) throws Underflow
{
if( isEmpty( ) )
throw new Underflow( );
theArray[ topOfStack-- ] = null;
}
23
Pilas usando arreglos
private Object [ ] theArray;
private int topOfStack;
static final int DEFAULT_CAPACITY = 10;
public static void main( String [ ] args )
{
StackAr s = new StackAr( 12 );
try
{
for( int i = 0; i < 10; i++ )
s.push( new MyInteger( i ) );
}
catch( Overflow e ) { System.out.println(
"Unexpected overflow" ); }
while( !s.isEmpty( ) )
System.out.println( s.topAndPop( ) );
}
}
Aplicaciones de pilas
n Balance de simbolos.
simbolos.
n Conversió
Conversión de expresiones de infix a
postfix.
postfix.
n Evaluació
Evaluación de expresiones.
n Eliminació
Eliminación de recursió
recursión
24
Balance de Parentesis
class BracketChecker
{
private String input; // input string
public BracketChecker(String in) // constructor
{ input = in; }
public void check()
{
int stackSize = input.length(); // get max stack size
StackX theStack = new StackX(stackSize); // make stack
for(int j=0; j<input.length(); j++)// get chars in turn
{
char ch = input.charAt(j); // get char
switch(ch)
{
case '{': // opening symbols
case '[':
case '(':
theStack.push(ch); // push them
break;
25
Infix to Postfix
class InToPost // infix to postfix conversion
{
private StackX theStack;
private String input;
private String output = "";
public InToPost(String in) // constructor
{
input = in;
int stackSize = input.length();
theStack = new StackX(stackSize);
}
Infix to Postfix
public String doTrans() // do translation to postfix
{
for(int j=0; j<input.length(); j++) // for each char
{
char ch = input.charAt(j); // get it
switch(ch)
{
case '+': // it's + or -
case '-':
gotOper(ch, 1); // go pop operators
break; // (precedence 1)
case '*': // it's * or /
case '/':
gotOper(ch, 2); // go pop operators
break; // (precedence 2)
case '(': // it's a left paren
theStack.push(ch); // push it
break;
26
Infix to Postfix
case ')': // it's a right paren
gotParen(); // go pop operators
break;
default: // must be an operand
output = output + ch; // write it to output
break;
} // end switch
} // end for
while( !theStack.isEmpty() ) // pop remaining opers
{
output = output + theStack.pop(); // write to output
}
return output; // return postfix
} // end doTrans()
Infix to Postfix
private void gotOper(char opThis, int prec1)
{ // got operator from input
while( !theStack.isEmpty() )
{
char opTop = theStack.pop();
if( opTop == '(' ) // if it's a '('
{
theStack.push(opTop); // restore '('
break;
}
else // it's an operator
{
int prec2; // precedence of new op
if(opTop=='+' || opTop=='-') // find new op prec
prec2 = 1;
else
prec2 = 2;
27
Infix to Postfix
if(prec2 < prec1) // if prec of new op less
{ // than prec of old
theStack.push(opTop); // save newly-popped op
break;
}
else // prec of new not less
output = output + opTop; // than prec of old
} // end else (it's an operator)
} // end while
theStack.push(opThis); // push new operator
} // end gotOper()
Infix to Postfix
28
Evaluación de una expresión Postfix
class ParsePost
{
private StackX theStack;
private String input;
public ParsePost(String s)
{ input = s; }
public int doParse()
{
theStack = new StackX(20); // make new stack
char ch;
int j;
int num1, num2, interAns;
for(j=0; j<input.length(); j++) // for each char,
{
ch = input.charAt(j); // read from input
if(ch >= '0' && ch <= '9') // if it's a number
theStack.push( (int)(ch-'0') ); // push it
29
Evaluación de una expresión Postfix
default:
interAns = 0;
} // end switch
theStack.push(interAns); // push result
} // end else
} // end for
interAns = theStack.pop(); // get answer
return interAns;
} // end doParse()
} // end class ParsePost
El ADT Cola
n A semejanza de una pila, una cola es una
lista en la que se restringen las
operaciones permitidas:
n Solo se puede insertar en un extremo de la
lista.
n Solo se permite extraer elementos en el otro
extremo de la lista.
n Cualquier implementació
implementación de lista es
adecuada para colas.
30
Colas Usando Arreglos
n Es posible implementar colas usando arreglos de
modo que las operaciones requieren un tiempo
O(1)
n Ademá
Además del arreglo se tienen dos variables que
contienen los índices al inicio y fin de la cola.
n Tambié
También se usa una tercera variable que
contiene la longitud de la cola para diferenciar
una cola vací
vacía de una que llena todo el arreglo.
31
Colas Usando Arreglos
public boolean isFull( )
{
return currentSize == theArray.length;
}
public void makeEmpty( )
{
currentSize = 0;
front = 0;
back = -1;
}
public Object getFront( )
{
if( isEmpty( ) )
return null;
return theArray[ front ];
}
32
Colas Usando Arreglos
private int increment( int x )
{
if( ++x == theArray.length )
x = 0;
return x;
}
Aplicaciones de Colas
n Colas de impresió
impresión.
n Simulació
Simulación de lílíneas de espera.
n Colas de acceso a archivos en servidores
33