You are on page 1of 7

Clasificacin de algoritmos * Algoritmo determinista: en cada paso del algoritmo se determina de forma nica el siguiente paso.

* Algoritmo no determinista: deben decidir en cada paso de la ejecucin entre varias alternativas y agotarlas todas antes de encontrar la solucin. Todo algoritmo tiene una serie de caractersticas, entre otras que requiere una serie de recursos, algo que es fundamental considerar a la hora de implementarlos en una mquina. Estos recursos son principalmente: El tiempo: perodo transcurrido entre el inicio y la finalizacin del algoritmo. La memoria: la cantidad (la medida vara segn la mquina) que necesita el algoritmo para su ejecucin. Obviamente, la capacidad y el diseo de la mquina pueden afectar al diseo del algoritmo. En general, la mayora de los problemas tienen un parmetro de entrada que es el nmero de datos que hay que tratar, esto es, N. La cantidad de recursos del algoritmo es tratada como una funcin de N. De esta manera puede establecerse un tiempo de ejecucin del algoritmo que suele ser proporcional a una de las siguientes funciones:

1 : Tiempo de ejecucin constante. Significa que la mayora de las instrucciones se ejecutan una vez o muy pocas. logN : Tiempo de ejecucin logartmico. Se puede considerar como una gran constante. La base del logaritmo (en informtica la ms comn es la base 2) cambia la constante, pero no demasiado. El programa es ms lento cuanto ms crezca N, pero es inapreciable, pues logN no se duplica hasta que N llegue a N2. N : Tiempo de ejecucin lineal. Un caso en el que N valga 40, tardar el doble que otro en que N valga 20. Un ejemplo sera un algoritmo que lee N nmeros enteros y devuelve la media aritmtica. NlogN : El tiempo de ejecucin es NlogN. Es comn encontrarlo en algoritmos como Quick Sort y otros del estilo divide y vencers. Si N se duplica, el tiempo de ejecucin es ligeramente mayor del doble. N2 : Tiempo de ejecucin cuadrtico. Suele ser habitual cuando se tratan pares de elementos de datos, como por ejemplo un bucle anidado doble. Si N se duplica, el tiempo de ejecucin aumenta cuatro veces. El peor caso de entrada del algoritmo Quick Sort se ejecuta en este tiempo. N3 : Tiempo de ejecucin cbico. Como ejemplo se puede dar el de un bucle anidado triple. Si N se duplica, el tiempo de ejecucin se multiplica por ocho. 2N : Tiempo de ejecucin exponencial. No suelen ser muy tiles en la prctica por el elevadsimo tiempo de ejecucin. El problema de la mochila resuelto por un algoritmo de fuerza bruta -simple vuelta atrs- es un ejemplo. Si N se duplica, el tiempo de ejecucin se eleva al cuadrado.

* Algoritmos polinomiales: aquellos que son proporcionales a Nk. Son en general factibles. * Algoritmos exponenciales: aquellos que son proporcionales a kN. En general son infactibles salvo un tamao de entrada muy reducido. - Notacin O-grande En general, el tiempo de ejecucin es proporcional, esto es, multiplica por una constante a alguno de los tiempos de ejecucin anteriormente propuestos, adems de la suma de algunos trminos ms pequeos. As, un algoritmo cuyo tiempo de ejecucin sea T = 3N2 + 6N se puede considerar proporcional a N2. En este caso se dira que el algoritmo es del orden de N2, y se escribe O(N2) Los grafos definidos por matriz de adyacencia ocupan un espacio O(N2), siendo N el nmero de vrtices de ste. La notacin O-grande ignora los factores constantes, es decir, ignora si se hace una mejor o peor implementacin del algoritmo, adems de ser independiente de los datos de entrada del algoritmo. Es decir, la utilidad de aplicar esta notacin a un algoritmo es encontrar un lmite superior del tiempo de ejecucin, es decir, el peor caso. A veces ocurre que no hay que prestar demasiada atencin a esto. Conviene diferenciar entre el peor caso y el esperado. Por ejemplo, el tiempo de ejecucin del algoritmo Quick Sort es de O(N2). Sin embargo, en la prctica este caso no se da casi nunca y la mayora de los casos son proporcionales a NlogN. Es por ello que se utiliza esta ltima expresin para este mtodo de ordenacin. Una definicin rigurosa de esta notacin es la siguiente: Una funcin g(N) pertenece a O(f(N)) si y slo si existen las constantes c0 y N0 tales que: |g(N)| <= |c0f(N)| , para todo N >= N0.

1.1Collection A collection is an object that represents a group of objects. Collections typically represent data items that form a natural group, like a mail folder (a collection of letters) or a telephone directory (a collection of name-to-phone-number mappings). The Java Software Development Kit (SDK) provides a collections API, a unified framework for representing and manipulating collections. This framework provides premade classes for creating and manipulating typical data structures. There are a number of advantages to providing a set of prebuilt collections. They include:

Reduces programming effort because useful data structures and algorithms are already written Increases performance because the provided collections are high-performance implementations of useful data structures and algorithms

Provides interoperability between unrelated APIs because a common language is used to pass collections back and forth Reduces effort to learn APIs by eliminating the need to learn multiple ad hoc collection APIs

Interfaces The six interfaces pictured here make up the core of the collections framework. Each defines a unique group of features and methods that define unique behaviors for each object type.

The Collection Interface The Collection interface is the base interface for the List and Set interfaces. The interface includes any operations that are common to both descendant interfaces. A collection defines a group of objects known as elements. Operations that can be performed on the group include:

Adding new elements to the collection Removing elements from the collection Searching the collection for an element Returning the size of a collection

Note: Elements in any collection are stored using the Object class. This means a cast is required when an element is retrieved from a collection.

The Set Interface The Set interface represents a group of elements that contains no duplicates. Each element in the group is unique. Note: The uniqueness of an element is determined by the equals method.

The SortedSet Interface The SortedSet interface is a set of elements that are kept in ascending order. The interface includes methods that take advantage of this ordering. The List Interface The List interface represents an ordered list of elements. Duplicate elements are allowed. List objects provide control over where elements are inserted. In addition, each element can be accessed through an index. The Map Interface The Map interface represents a group of key/value pairs. Each object stored in a Map interface has a key that uniquely identifies the object associated with it. Each value stores an object and duplicate objects are allowed. Because the Map interface stores a key and value pair and not individual objects, it does not inherit from the Collection interface. The SortedMap Interface The SortedMap interface keeps the keys of the Map interface in a sorted order. This interface also includes methods that take advantage of this ordering. 1.2 Interface Implementations With the discussion of each interface's characteristics out of the way, you can now look at some general implementations of collection interfaces.

The List Interface Implementations There are two main implementations of the List interface, the ArrayList and LinkedList classes. The ArrayList class is used to create a dynamic growable array. Unlike a regular array, which is a fixed sized, an ArrayList class grows as elements are added to the array object. The following code example demonstrates the use of an ArrayList class.
1) import java.util.*; 2) 3) public class ReadArr{ 4) public static void main(String[] args){ 5) List myList = new ArrayList(); 6) 7) // Populate the ArrayList 8) for (int i = 0; i < args.length ; i++){ 9) myList.add(args[i]); 10) } 11) 12) //Print the ArrayList 13) for (int i = 0; i < myList.size(); i++){ 14) System.out.println("Element "+ i + ": "+ myList.get(i)); 15) } 16) } 17)}

The Iterator Interface One of the features of collections is a built-in way of stepping through the contents of a collection. In the previous example, a for loop is used to print out the contents of the ArrayList class. With a collection, the Iterator and ListIterator interfaces can be used instead. An Iterator object provides a standard way for stepping through each element in a collection. The following example replaces the for loop with an Iterator object.
1) import java.util.*; 2) 3) public class ReadArrIt{ 4) public static void main(String[] args){ 5) List myList = new ArrayList(); 6) 7) // Populate the ArrayList 8) for (int i = 0; i < args.length ; i++){ 9) myList.add(args[i]); 10) } 11) 12) //Print the ArrayList 13) String temp = ""; 14) Iterator i = myList.iterator(); 15) while(i.hasNext()){

16) 17) 18) 19) 20)}

temp = (String) i.next(); System.out.println("Element: "+ temp); } }

An Iterator interface is defined on line 14. The call to the iterator method creates an Iterator object i. The hasNext method on line 15 returns true if there are more elements to step through. The next method in line 16 retrieves the element currently pointed to and moves the object pointer to the next object. Remember, elements in a collection are stored using the Object class and a cast is required to retrieve the object from a collection. The use of the temp variable is unnecessary in this example. The use of the variable illustrates the normal steps required to retrieve an object. Often, you would be doing more than simply printing a value. 1.3 The ListIterator Interface The ListIterator interface provides additional options for stepping through a list. The ListIterator interface includes methods that access the next item in the list or the previous item in the list. This allows traversal in either direction. Also, the index is accessible through the nextIndex or previousIndex methods. The following example demonstrates the use of a ListIterator interface:
1) import java.util.*; 2) 3) public class ReadArrLIt{ 4) public static void main(String[] args){ 5) List myList = new ArrayList(); 6) 7) // Populate the ArrayList 8) for (int i = 0; i < args.length ; i++){ 9) myList.add(args[i]); 10) } 11) 12) //Print the ArrayList 13) String temp = ""; 14) int index = 0; 15) ListIterator i = myList.listIterator(); 16) while(i.hasNext()){ 17) index = i.nextIndex(); 18) temp = (String) i.next(); 19) System.out.println("Element "+ index + " :" + temp); 20) } 21) } 22)}

1.4 The LinkedList Class The other general purpose implementation of List interface is a LinkedList class. The LinkedList class is an implementation of a doubly linked list. This implementation is a good choice if you need to iterate through a list and delete elements from the list's

interior. However, it does take more time to access individual elements in a LinkedList class than an ArrayList class. To demonstrate how easy it is to change implementations, the following program is a rewrite of the Iterator example. In this program the ArrayList class is swapped for a LinkedList class. The program produces the same output as before.
1) import java.util.*; 2) 3) public class ReadArrLinked{ 4) public static void main(String[] args){ 5) List myList = new LinkedList(); 6) 7) // Populate the ArrayList 8) for (int i = 0; i < args.length ; i++){ 9) myList.add(args[i]); 10) } 11) 12) //Print the ArrayList 13) String temp = ""; 14) Iterator i = myList.iterator(); 15) while(i.hasNext()){ 16) temp = (String) i.next(); 17) System.out.println("Element: "+ temp); 18) } 19) } 20)}

Notice the only change from the previous example is the new statement on line 5. Otherwise, the program is unchanged.

You might also like