Pero por suerte no estoy obligado a darle toda la razón, ya que el costo de las asignaciones es muy similar al de las comparaciones.
Y por lo tanto conviene evitarlas tanto como sea posible.
Yo nunca dije lo contrario. Por eso en mi programa cambié la condición
if (v[i] >= v[k]) por
if (v[i] > v[k]) (y de hecho estuve a punto de escribir algo al respecto), pero me limité a modificarlo solamente, pues lo consideré un detalle (no muy relevante), y además distraería al lector sobre lo que yo pretendía que fuera el foco de atención, que era pasar la longitud del vector como parámetro.
En particular, puede haber varios índices que contengan el valor máximo.
El algoritmo utilizado se queda con el último de estos índices.
En realidad, si no se exige nada al respecto, mi procedimiento es ineficiente.
Conviene elegir el primer índice k donde aparece el máximo...
Ahí te interpreté mal porque yo creí que estabas hablando de interrumpir la recorrida en algún momento, lo cual es obviamente imposible. Uno no se puede detener en un índice confiando en que ya tiene el máximo, pues el máximo podría estar en la parte del vector que aún nos es desconocida.
También es cierto que al momento de pensar en eficiencia (que lo hice al ver la idea de xamo), automáticamente pensé en número de comparaciones. Como de inmediato me di cuenta de que no se podía hacer nada mejor, me despreocupé por completo. Uno tiende a pensar que una recorrida con un
for, sin más, es algo poco inteligente. Pensé en comparaciones y no asignaciones, puesto que la mayoría de los libros de análisis de algoritmos toma como operación básica
la comparación entre elementos del arreglo. Así, por ejemplo, cuando se dice que QuickSort es \( O(n\log n) \) en el peor caso, se está refiriendo al número de comparaciones. Lo mismo cuando se dice que InsertionSort es \( O(n) \) en el caso promedio, etc.
Esto no quiere decir que las asignaciones sean despreciables en la realidad. Lo son en nuestro análisis, si tomamos como operación básica a la comparación.
Las asignaciones están ahí, y consumen tiempo.
Completamente de acuerdo.
Además, una cosa es el análisis teórico de los algoritmos, y otra es la practica.
El análisis teórico sirve para no hacer algoritmos desastrosos.
Pero los resultados quedan dependiendo de ciertas constantes que no se explicitan.
En la implementación real esas constantes cuentan.
Si uno va a ordenar vectores de \( n < 100 \) elementos con un algoritmo de complejidad "eficiente" \( 1000000\; n \log(n) \), contra otro algoritmo "ineficiente" de complejidad \( 5\;n^2 \), conviene el "ineficiente".
Sí, sí. Está claro. Cuando hacemos todas estas consideraciones nos estamos refiriendo al comportamiento asintótico del algoritmo. Por supuesto que un algoritmo que es óptimo para entradas arbitrariamente grandes, no tiene por que ser el mejor para \( n \) pequeño. Todo depende de para qué se lo va a usar.
Saludos