Este documento presenta varios algoritmos de ordenamiento como ordenamiento por selección, ordenamiento con árbol binario y ordenamiento heap. Explica que el ordenamiento por selección tiene una complejidad de O(n2) y funciona buscando el elemento mínimo en cada paso. El ordenamiento con árbol binario construye gradualmente un árbol binario de búsqueda con los elementos para ordenarlos. El ordenamiento heap primero convierte el arreglo en un montículo y luego extrae el máximo elemento en cada paso para construir el arreglo ordenado.
3. INTRODUCCION: En esta presentación veremos las ventajas del un algoritmo de selección que no es nada más que una ayuda para el análisis de la información.
4. TEMARIO: ORDENAMIENTO POR SELECCION Directa por Arboles Binarios. Método de Heap. Análisis de eficiencia.
5. ORDEMANIENTO POR SELECCION El ordenamiento por selección (SelectionSort en inglés) es un algoritmo de ordenamiento que requiere O (n2) operaciones para ordenar una lista de n elementos. Su funcionamiento es el siguiente: Buscar el mínimo elemento de la lista Intercambiarlo con el primero Buscar el mínimo en el resto de la lista Intercambiarlo con el segundo Y en general: Buscar el mínimo elemento entre una posición i y el final de la lista Intercambiar el mínimo con el elemento de la posición i
6. De esta manera se puede escribir el siguiente pseudocódigo para ordenar una lista de n elementos indexados desde el 1: para i=1 hasta n-1 minimo = i; para j=i+1 hasta n si lista[j] < lista[minimo] entonces minimo = j /* (!) */ fin si fin para intercambiar(lista[i], lista[minimo]) fin para Este algoritmo mejora ligeramente el algoritmo de la burbuja. En el caso de tener que ordenar un vector de enteros, esta mejora no es muy sustancial, pero cuando hay que ordenar un vector de estructuras más complejas, la operación intercambiar () sería más costosa en este caso. Este algoritmo realiza muchas menos operaciones intercambiar () que el de la burbuja, por lo que lo mejora en algo. Si la línea comentada con (!) se sustituyera por intercambiar (lista[i], lista[j]) tendríamos una versión del algoritmo de la burbuja (naturalmente eliminando el orden intercambiar del final). Otra desventaja de este algoritmo respecto a otros como el de burbuja o de inserción directa es que no mejora su rendimiento cuando los datos ya están ordenados o parcialmente ordenados.
7. ORDENAMIENTO CON ARBOL BINARIO El ordenamiento con árbol binario es un algoritmo de ordenamiento, el cual ordena sus elementos haciendo uso de un árbol binario de búsqueda. Se basa en ir construyendo poco a poco el árbol binario introduciendo cada uno de los elementos, los cuales quedarán ya ordenados. Después, se obtiene la lista de los elementos ordenados recorriendo el árbol en inorden.
8. Complejidad: Insertar elementos en un árbol binario de búsqueda tiene una complejidad O(log n). Entonces, agregar n elementos a un árbol cualquiera da como resultado una complejidad O(n log n). Además, recorrer los elementos del árbol en inorden tiene complejidad O(n). Características: Tiene un buen rendimiento. Es estable (no cambia el orden relativo de elementos iguales). No requiere espacio de almacenamiento extra. Puede ordenar listas tal cual las recibe.
9. Árboles Un árbol es un grafo dirigido acíclico que satisface las siguientes propiedades: Existe exactamente un vértice, llamado raíz, al que no llega ningún arco. Cada vértice excepto la raíz tiene exactamente un arco entrante. Existe un camino único de la raíz a cada vértice. Árboles La profundidad dev es la longitud del camino de la raíz a v. La altura de v es la longitud del camino más largo de v a una hoja. La altura de un árbol es la altura de la raíz. El nivel dev en un árbol es la altura del árbol menos la profundidad de v.
10. Árbol de decisión: Consideración de las instrucciones de ramificación (condicionales). En los ordenamientos, es razonable considerar un modelo en el cual todos los pasos de progresión sean ramificaciones de dos vías basadas en una comparación entre dos cantidades. Árbol de decisión: La representación para un programa de ramificaciones es un árbol binario llamado árbol de decisión. Cada vértice interior representa una decisión. La prueba representada por la raíz se hace primero, y el control pasa, dependiendo del resultado, a uno de sus hijos. En general, el control continúa pasando de un vértice a uno de sus hijos hasta que se alcanza una hoja (salida).
11. Árbol de decisión Lema. Un árbol binario de altura h tiene a lo más 2h hojas. Teorema. Un árbol para ordenar n elementos debe tener al menos n! hojas Teorema. Un árbol de decisión para ordenar n datos tiene altura de al menos log n! Corolario. Cualquier algoritmo de ordenamiento por comparaciones requiere al menos de cn log n comparaciones para ordenar n datos para alguna c>0 y n grande.
12. METODO HEAP SORT El significado de heap en ciencia computacional es el de una cola de prioridades (priorityqueue). Tiene las siguientes características: Un heap es un arreglo de n posiciones ocupado por los elementos de la cola. (Nota: se utiliza un arreglo que inicia en la posición 1 y no en cero, de tal manera que al implementarla en C se tienen n+1 posiciones en el arreglo.) Se mapea un árbol binario de tal manera en el arreglo que el nodo en la posición i es el padre de los nodos en las posiciones (2*i) y (2*i+1). El valor en un nodo es mayor o igual a los valores de sus hijos. Por consiguiente, el nodo padre tiene el mayor valor de todo su subárbol.
13. HeapSort consiste escencialmente en: convertir el arreglo en un heap construir un arreglo ordenado de atrás hacia adelante (mayor a menor) repitiendo los siguientes pasos: sacar el valor máximo en el heap (el de la posición 1) poner ese valor en el arreglo ordenado reconstruir el heap con un elemento menos utilizar el mismo arreglo para el heap y el arreglo ordenado.
14. Procedimiento Heapsort : /* Recibe como parámetros un arreglo a ordenar y un entero que indica el numero de datros a ordenar */ void heapsort(int a[], int N) { int k; for(k=N/2; k>=1; k--) downheap(a,N,k); while(N > 1) { swap(a,1,N); downheap(a,--N,1); } }
15. /* el procedimiento downheap ordena el &aacure;rbol de heap para que el nodo padre sea mayor que sus hijos */ void downheap(int a[], int N, int r) { int j, v; v = a[r]; while (r <= N/2) { j = 2*r; if(j < N && a[j] < a[j+1]); j++; if( v >= a[j]) break; a[r] = a[j]; r = j; } a[r] = v; }
16. INTRODUCCION AL ANALISIS DE EFICIENCIA Dados dos algoritmos que resuelven el mismo problema de forma diferente: ¿Cuál es el mejor? ¿Cómo se decide que un algoritmo es mejor que otro? Posibles respuestas: •El que consuma menos memoria (número de variables, número y tamaño de estructuras de datos usadas). •El que vaya más rápido (midiendo el tiempo que tarda en ejecutarse o el número de operaciones elementales que realiza). •El que funcione adecuadamente. •El más fácil para el humano de leer, escribir o entender. ¿Por qué deberíamos preocuparnos por la calidad de un algoritmo, si lo único que tenemos que hacer para que un programa vaya más rápido es utilizar un ordenador con más potencia, o si éste consume mucha memoria, añadirle algunos módulos de memoria más?
17. Problema: El aumento de las prestaciones no implica una clara mejora en el tiempo de ejecución. Ejemplo: Ejecución de un programa con n datos en 10-42n segundos: •Si n=10, el programa terminará en 0'1 segundos. •Si fuera 20, aproximadamente 10 minutos;•30, un día y•40, un año. Si cambiamos el ordenador que estamos usando por uno 100 veces más rápido: •Si n=45 datos, en un año. ¿Cómo podemos realizar el estudio de la eficiencia de un algoritmo? •Empíricamente: programar los algoritmos y ejecutarlos varias veces con distintos datos de entrada. •Teóricamente: determinar matemáticamente la cantidad de recursos (tiempo de ejecución y memoria) requeridos por la implementación en función del tamaño de la entrada.