Tema 3 - Ordenación
Tema 3 - Ordenación
Fundamentos de la programación II
Problema
‣ Dada una colección de datos que se pueden comparar con una relación de
orden, <, producir una secuencia de esos datos de tal forma que ninguno sea
menor que los que le preceden.
para i = 1 hasta N – 1:
// V[0..i) está ordenado
j=i
mientras j > 0 && V[ j ] < V[ j – 1]:
intercambiar V[ j ] con V[ j – 1]
j=j–1
// V[0..N) está ordenado
Ordenación por inserción. Ejemplo
Ordenación por inserción: implementación
‣ Ordenación de un vector de enteros:
void ordenar_insercion(vector<int> &/*ent/sal*/ array) {
size_t N = array.size();
// parte ordenada array[0..i), parte por procesar array[i..N)
for (size_t i = 1; i < N; ++i) { // desde el segundo hasta el último
int elemento = array[i]; // elemento a insertar
size_t j = i; // desplazar los mayores de la parte ordenada
while (j > 0 && elemento < array[j - 1]) {
array[j] = array[j - 1];
--j;
}
array[j] = elemento; // colocar en el hueco
}
// parte ordenada array[0..N)
}
Ordenación por inserción: implementación
‣ ¿Y si queremos ordenar strings?
void ordenar_insercion(vector<string> &/*ent/sal*/ array) {
size_t N = array.size();
// parte ordenada array[0..i), parte por procesar array[i..N)
for (size_t i = 1; i < N; ++i) { // desde el segundo hasta el último
string elemento = array[i]; // elemento a insertar
size_t j = i; // desplazar los mayores de la parte ordenada
while (j > 0 && elemento < array[j - 1]) {
array[j] = array[j - 1];
--j;
}
array[j] = elemento; // colocar en el hueco
}
// parte ordenada array[0..N)
}
Ordenación por inserción: implementación
‣ ¡Los templates nos salvan!
template <typename T>
void ordenar_insercion(vector<T> &/*ent/sal*/ array) {
size_t N = array.size();
// parte ordenada array[0..i), parte por procesar array[i..N)
for (size_t i = 1; i < N; ++i) { // desde el segundo hasta el último
T elemento = array[i]; // elemento a insertar
size_t j = i; // desplazar los mayores de la parte ordenada
while (j > 0 && elemento < array[j - 1]) {
array[j] = array[j - 1];
--j;
}
array[j] = elemento; // colocar en el hueco
}
// parte ordenada array[0..N)
}
Ordenación por inserción: implementación
‣ ¿Y si queremos ordenar de mayor a menor?
template <typename T>
void ordenar_insercion(vector<T> &/*ent/sal*/ array) {
size_t N = array.size();
// parte ordenada array[0..i), parte por procesar array[i..N)
for (size_t i = 1; i < N; ++i) { // desde el segundo hasta el último
T elemento = array[i]; // elemento a insertar
size_t j = i; // desplazar los mayores de la parte ordenada
while (j > 0 && elemento > array[j - 1]) {
array[j] = array[j - 1];
--j;
}
array[j] = elemento; // colocar en el hueco
}
// parte ordenada array[0..N)
}
Ordenación por inserción: implementación
‣ ¡Los templates nos salvan de nuevo! #include <functional>
vector<int> enteros;
enteros 20 7 14 32 5 14 17 12 13 15
ordenar_insercion(enteros);
enteros 5 7 12 13 14 14 15 17 20 32
ordenar_insercion(enteros, greater<int>());
enteros 32 20 17 15 14 14 13 12 7 5
Ordenación por inserción: ejemplo
vector<string> datos;
ordenar_insercion(datos);
vector<string> datos;
ordenar_insercion(datos, ComparaSinMayus());
insertar_ordenado(datos, string("buho"));
para i = 0 hasta N – 2:
// V[0..i) está ordenado
jMin = i
para j = i + 1 hasta N – 1:
si V[ j ] < V[ jMin ]:
jMin = j
intercambiar V[ i ] con V[ jMin ]
// V[0..N) está ordenado
Ordenación por selección. Ejemplo
Ordenación por selección: implementación
para i = 1 hasta N – 1:
// V[N – i + 1..N) está ordenado
para j = 0 hasta N – i:
si V[ j + 1 ] < V[ j ]:
intercambiar V[ j ] con V[ j + 1 ]
// V[0..N) está ordenado
Ordenación por el método de la burbuja. Ejemplo
Ordenación por el método de la burbuja: implementación
template <typename T, typename Comp = less<T>>
void ordenar_burbuja(vector<T> &/*ent/sal*/ array, Comp ord = Comp()) {
size_t N = array.size();
bool inter = true;
size_t i = 1;
// ordenado array[N-i+1..N) y todos los elementos de la parte
// ordenada son "mayores" (o iguales) que los de la parte no ordenada
while (i < N && inter) { // hasta el penúltimo
// colocar el mayor de la parte no ordenada en array[N-i]
// intercambiando, desde el primero, con los elementos menores
inter = false; // y comprobando si se realiza algún intercambio
for (size_t j = 0; j < N-i; ++j)
if (ord(array[j+1], array[j])) {
swap(array[j], array[j+1]);
inter = true;
}
++i;
}
}
// parte ordenada array[0..N)
Inserción vs Burbuja
std::sort en la librería algorithm de la STL
sort(datos.begin(), datos.end());
1 4 7 12 12 20 28 140
140 28 20 12 12 7 4 1
Comprobar si un vector está ordenado
Buscamos el 13
enteros 5 7 12 13 14 14 15 17 20 32
Búsqueda secuencial en un vector ordenado
‣ Buscamos un elemento en un vector. Queremos saber si está o no, y en caso
de que esté, dónde.
‣ No hace falta buscar en todo el vector. Si buscamos de izquierda a derecha
podemos parar en cuanto encontremos un elemento que no sea menor que el
buscado.
Buscamos el 13
enteros 5 7 12 13 14 14 15 17 20 32
Búsqueda secuencial en un vector ordenado
‣ Buscamos un elemento en un vector. Queremos saber si está o no, y en caso
de que esté, dónde.
‣ No hace falta buscar en todo el vector. Si buscamos de izquierda a derecha
podemos parar en cuanto encontremos un elemento que no sea menor que el
buscado.
Buscamos el 13
enteros 5 7 12 13 14 14 15 17 20 32
Búsqueda secuencial en un vector ordenado
‣ Buscamos un elemento en un vector. Queremos saber si está o no, y en caso
de que esté, dónde.
‣ No hace falta buscar en todo el vector. Si buscamos de izquierda a derecha
podemos parar en cuanto encontremos un elemento que no sea menor que el
buscado.
Buscamos el 13
enteros 5 7 12 13 14 14 15 17 20 32
Búsqueda secuencial en un vector ordenado
‣ Buscamos un elemento en un vector. Queremos saber si está o no, y en caso
de que esté, dónde.
‣ No hace falta buscar en todo el vector. Si buscamos de izquierda a derecha
podemos parar en cuanto encontremos un elemento que no sea menor que el
buscado.
Buscamos el 13
enteros 5 7 12 13 14 14 15 17 20 32
Búsqueda secuencial en un vector ordenado
‣ Buscamos un elemento en un vector. Queremos saber si está o no, y en caso
de que esté, dónde.
‣ No hace falta buscar en todo el vector. Si buscamos de izquierda a derecha
podemos parar en cuanto encontremos un elemento que no sea menor que el
buscado.
Buscamos el 10
enteros 5 7 12 13 14 14 15 17 20 32
Búsqueda secuencial en un vector ordenado
‣ Buscamos un elemento en un vector. Queremos saber si está o no, y en caso
de que esté, dónde.
‣ No hace falta buscar en todo el vector. Si buscamos de izquierda a derecha
podemos parar en cuanto encontremos un elemento que no sea menor que el
buscado.
Buscamos el 10
enteros 5 7 12 13 14 14 15 17 20 32
Búsqueda secuencial en un vector ordenado
‣ Buscamos un elemento en un vector. Queremos saber si está o no, y en caso
de que esté, dónde.
‣ No hace falta buscar en todo el vector. Si buscamos de izquierda a derecha
podemos parar en cuanto encontremos un elemento que no sea menor que el
buscado.
Buscamos el 10
enteros 5 7 12 13 14 14 15 17 20 32
Búsqueda secuencial en un vector ordenado
‣ Buscamos un elemento en un vector. Queremos saber si está o no, y en caso
de que esté, dónde.
‣ No hace falta buscar en todo el vector. Si buscamos de izquierda a derecha
podemos parar en cuanto encontremos un elemento que no sea menor que el
buscado.
Buscamos el 10
enteros 5 7 12 13 14 14 15 17 20 32
Búsqueda secuencial en un vector ordenado: implementación
enteros 5 7 12 13 14 14 15 17 20 32
iz m dr
enteros 5 7 12 13 14 14 15 17 20 32
iz m dr
enteros 5 7 12 13 14 14 15 17 20 32
iz m dr
enteros 5 7 12 13 14 14 15 17 20 32
iz dr
enteros 5 7 12 13 14 14 15 17 20 32
iz m dr
enteros 5 7 12 13 14 14 15 17 20 32
iz m dr
enteros 5 7 12 13 14 14 15 17 20 32
iz m dr
enteros 5 7 12 13 14 14 15 17 20 32
iz dr
0 1 2 3 4 5 6 7 8 9
enteros 5 7 12 13 20 23 30 35 40 48
Operaciones con listas ordenadas: Inserción
‣ Insertar sin repeticiones.
Insertar el 16
0 1 2 3 4 5 6 7 8 9
enteros 5 7 12 13 20 23 30 35 40 48
Operaciones con listas ordenadas: Inserción
‣ Insertar sin repeticiones.
Insertar el 16
0 1 2 3 4 5 6 7 8 9 10
enteros 5 7 12 13 20 23 30 35 40 48
Operaciones con listas ordenadas: Inserción
‣ Insertar sin repeticiones.
Insertar el 16
0 1 2 3 4 5 6 7 8 9 10
enteros 5 7 12 13 20 23 30 35 40 48
Operaciones con listas ordenadas: Inserción
‣ Insertar sin repeticiones.
Insertar el 16
0 1 2 3 4 5 6 7 8 9 10
enteros 5 7 12 13 16 20 23 30 35 40 48
Operaciones con listas ordenadas: Inserción
template <typename T>
void desplazar_derecha(vector<T> &/*ent/sal*/ array, size_t pos) {
array.push_back({}); // crear un nuevo hueco
for (size_t i = array.size() - 1; i > pos; --i)
array[i] = array[i - 1];
}
0 1 2 3 4 5 6 7 8 9
enteros 5 7 12 13 20 23 30 35 40 48
Operaciones con listas ordenadas: Eliminación
‣ Eliminar un elemento, si existe.
Eliminar el 23
0 1 2 3 4 5 6 7 8 9
enteros 5 7 12 13 20 23 30 35 40 48
Operaciones con listas ordenadas: Eliminación
‣ Eliminar un elemento, si existe.
Eliminar el 23
0 1 2 3 4 5 6 7 8 9
enteros 5 7 12 13 20 30 35 40 48
Operaciones con listas ordenadas: Eliminación
‣ Eliminar un elemento, si existe.
Eliminar el 23
0 1 2 3 4 5 6 7 8
enteros 5 7 12 13 20 30 35 40 48
Operaciones con listas ordenadas: Eliminación
template <typename T>
void desplazar_izquierda(vector<T> &/*ent/sal*/ array, size_t pos) {
for (size_t i = pos + 1; i < array.size(); ++i)
array[i - 1] = array[i];
array.pop_back();
}