#include <stdio.h>
#include <sys/time.h>
#include <math.h>
#include <stdlib.h>
#define TAM 128000
typedef struct {
int vector[TAM];
int ultimo;
} monticulo;
void listar_vector(int v[], int n){
int i;
printf("[");
for(i=0;i<n;i++){
printf("%4i",v[i]);
}
printf(" ]\n");
}
/* obtiene el tiempo actual en microsegundos */
double microsegundos(){
struct timeval t;
if (gettimeofday(&t, NULL) < 0)
return 0.0;
return (t.tv_usec + t.tv_sec * 1000000.0);
}
//Inicializacion de vector de forma aleatoria
void inicializar_semilla(){
srand(time(NULL));
}
void aleatorio(int v[], int n){
int i, m=2*n+1;
for(i=0;i<n;i++)
v[i] = (rand() % m) - n;
}
//Inicialización de vector ordenado de forma ascendente
void inicializar_asc(int v[], int n){
int i;
for(i=0;i<n;i++){
v[i] = i;
}
}
//Inicialización de vector ordenado de forma ascendente
void inicializar_des(int v[], int n){
int i;
for(i=n;i>=0;i--){
v[i] = n-i;
}
}
/* *** FUNCIONES DEL MONTICULO *** */
void ini_monticulo(monticulo *M) {
M->ultimo = -1;
}
void Hundir(monticulo *M,int i) {
int HijoIzq;
int HijoDer;
int j,aux;
do {
HijoIzq = (2*i) + 1;
HijoDer = (2*i) + 2;
j = i;
if ((HijoDer < M->ultimo+1) && (M->vector[HijoDer] > M->vector[i]))
i = HijoDer;
if ((HijoIzq < M->ultimo+1) && (M->vector[HijoIzq] > M->vector[i]))
i = HijoIzq;
aux = M->vector[i];
M->vector[i] = M->vector[j];
M->vector[j] = aux;
} while (j!=i);
}
void crear_monticulo(int v[], int n, monticulo *M){
int i;
for (i=0; i<n; i++){
M->vector[i] = v[i];
}
M->ultimo=n-1;
for (i=(n / 2); i>=0; i--)
Hundir(M,i);
}
int eliminar_mayor(monticulo *M){
int x;
if (M->ultimo == -1)
printf("Error: Monticulo Vacío\n");
else{
x = M->vector[0];
M->vector[0] = M->vector[M->ultimo];
M->ultimo = M->ultimo-1;
if (M->ultimo >=-1)
Hundir (M, 0);
}
return x;
}
void ordenar_monticulo(int v[],int n){
int i;
monticulo *M;
M = malloc(sizeof(monticulo));
crear_monticulo (v,n,M);
for (i=M->ultimo; i>0; i--)
v[i] = eliminar_mayor(M);
free(M);
}
/* *** FUNCION DE TEST *** */
void test_mont(){
int tam = 10;
int v[tam];
monticulo *M;
M = malloc(sizeof(monticulo));
printf("\nVALIDACION INICIALIZAR MONTICULO\n");
ini_monticulo(M);
if (M->ultimo == -1)
printf("Inicializacion correcta.\n");
printf("\nVALIDACION FUNCION CREAR MONTICULO\n");
inicializar_asc(v,tam);
printf("Vector inicializado ascendente\n");
listar_vector(v,tam);
printf("\nCreando monticulo...\n");
crear_monticulo(v,tam,M);
listar_vector(M->vector,tam);
printf("\nOrdenando vector por monticulo...\n");
ordenar_monticulo(v,tam);
listar_vector(v,tam);
free(M);
}
/* *** CALCULO DE TIEMPOS Y TABLAS PARA CREAR MONTICULO *** */
/* medicion de tiempos por debajo del umbral */
double umbral_crea(int v[], int n, monticulo *M){
int m,k;
int umbral=500 ,repeticiones=1000;
double ajustada,subestimada,sobrestimada,ta=0,tb=0,t,t1,t2;
ta = microsegundos();
for(k=0;k<repeticiones;k++){
inicializar_asc(v,n);
crear_monticulo(v,n,M);
}
tb = microsegundos();
t1 = tb-ta;
ta = microsegundos(); //Hay que restar el tiempo que tarda el bucle
for(k=0;k<repeticiones;k++){
inicializar_asc(v,n);
}
tb = microsegundos();
t2=tb-ta;
return (t1-t2)/repeticiones;
}
/* medicion de tiempos general */
double tiempos_crear(int v[], int n){
monticulo *M;
M = malloc(sizeof(monticulo));
int umbral=500;
double ajustada,subestimada,sobrestimada,ta=0,tb=0,t;
char flag=' ';
ta = microsegundos();
crear_monticulo(v,n,M);
tb = microsegundos();
t = tb -ta;
if(t < umbral){ //Se comprueba el tiempo umbral
t=umbral_crea(v,n,M);
flag='*';
}
printf("%c",flag);
free(M);
return t;
}
/* creacion de la tabla */
void tabla_crea_mont(){
int j,m,n = TAM;
int v[n];
double ajustada,subestimada,sobrestimada,t;
printf("\n%5s%15s%15s%13s%15s\n","n","t(n)","t(n)/n^0.9","t(n)/n","t(n)/n^1.1");
for(j=0;j<70;j++){
printf("-");
}
printf("\n");
for(m=1000;m<=n;m*=2){
inicializar_asc(v,m);
t = tiempos_crear(v,m);
subestimada = t/pow(m,0.9);
ajustada = t/m;
sobrestimada = t/pow(m,1.1);
printf("%6d%14.4f%13.6f%13.6f%13.6f\n",m,t,subestimada,ajustada,sobrestimada );
}
}
/* *** CALCULO DE TIEMPOS Y TABLAS PARA ORDENAR POR MONTICULO *** */
/* tiempos por debajo del umbral vector inicializado ascendente*/
double umbral_a(int v[], int n){
int m,k;
int umbral=500 ,repeticiones=1000;
double ajustada,subestimada,sobrestimada,ta=0,tb=0,t,t1,t2;
ta = microsegundos();
for(k=0;k<repeticiones;k++){
inicializar_asc(v,n);
ordenar_monticulo(v,n);
}
tb = microsegundos();
t1 = tb-ta;
ta = microsegundos(); //Hay que restar el tiempo que tarda el bucle
for(k=0;k<repeticiones;k++){
inicializar_asc(v,n);
}
tb = microsegundos();
t2=tb-ta;
return (t1-t2)/repeticiones;
}
/* tiempos por debajo del umbral vector inicializado descendente */
double umbral_d(int v[], int n){
int m,k;
int umbral=500 ,repeticiones=1000;
double ajustada,subestimada,sobrestimada,ta=0,tb=0,t,t1,t2;
ta = microsegundos();
for(k=0;k<repeticiones;k++){
inicializar_des(v,n);
ordenar_monticulo(v,n);
}
tb = microsegundos();
t1 = tb-ta;
ta = microsegundos(); //Hay que restar el tiempo que tarda el bucle
for(k=0;k<repeticiones;k++){
inicializar_des(v,n);
}
tb = microsegundos();
t2=tb-ta;
return (t1-t2)/repeticiones;
}
/* tiempos por debajo del umbral vector inicializado aleatorio */
double umbral_r(int v[], int n){
int m,k;
int umbral=500 ,repeticiones=1000;
double ajustada,subestimada,sobrestimada,ta=0,tb=0,t,t1,t2;
ta = microsegundos();
for(k=0;k<repeticiones;k++){
aleatorio(v,n);
ordenar_monticulo(v,n);
}
tb = microsegundos();
t1 = tb-ta;
ta = microsegundos(); //Hay que restar el tiempo que tarda el bucle
for(k=0;k<repeticiones;k++){
aleatorio(v,n);
}
tb = microsegundos();
t2=tb-ta;
return (t1-t2)/repeticiones;
}
/* funcion de calculo de tiempos */
double tiempos(int v[], int n, char ini){
monticulo *M;
M = malloc(sizeof(monticulo));
int umbral=500;
double ajustada,subestimada,sobrestimada,ta=0,tb=0,t;
char flag=' ';
ta = microsegundos();
ordenar_monticulo(v,n);
tb = microsegundos();
t = tb -ta;
if(t < umbral){ //Se comprueba el tiempo umbral
if (ini == 'a') t=umbral_a(v,n);
else if (ini == 'd') t=umbral_d(v,n);
else if (ini == 'r') t=umbral_r(v,n);
flag='*';
}
printf("%c",flag);
free(M);
return t;
}
/*** FUNCION TABLA ORDENAR POR MONTICULO VECTOR ASCENDENTE *** */
void tabla_ord_asc(){
int j,m,n = TAM;
int v[n];
double ajustada,subestimada,sobrestimada,t;
printf("\n%5s%15s%15s%13s%15s\n","n","t(n)","t(n)/n","t(n)/n*logn","t(n)/n^1.3");
for(j=0;j<70;j++){
printf("-");
}
printf("\n");
for(m=1000;m<=n;m*=2){
inicializar_asc(v,m);
t = tiempos(v,m,'a');
subestimada = t/m;
ajustada = t/(m*log(m));
sobrestimada = t/pow(m,1.3);
printf("%6d%14.4f%13.6f%13.6f%13.6f\n",m,t,subestimada,ajustada,sobrestimada );
}
}
/*** FUNCION TABLA ORDENAR POR MONTICULO VECTOR DESCENDENTE *** */
void tabla_ord_des(){
int j,m,n = TAM;
int v[n];
double ajustada,subestimada,sobrestimada,t;
printf("\n%5s%15s%15s%13s%15s\n","n","t(n)","t(n)/n","t(n)/n*logn","t(n)/n^1.3");
for(j=0;j<70;j++){
printf("-");
}
printf("\n");
for(m=1000;m<=n;m*=2){
inicializar_des(v,m);
t = tiempos(v,m,'a');
subestimada = t/m;
ajustada = t/(m*log(m));
sobrestimada = t/pow(m,1.3);
printf("%6d%14.4f%13.6f%13.6f%13.6f\n",m,t,subestimada,ajustada,sobrestimada );
}
}
/*** FUNCION TABLA ORDENAR POR MONTICULO VECTOR ALEATORIO *** */
void tabla_ord_ale(){
int j,m,n = TAM;
int v[n];
double ajustada,subestimada,sobrestimada,t;
printf("\n%5s%15s%15s%13s%15s\n","n","t(n)","t(n)/n","t(n)/n*logn","t(n)/n^1.3");
for(j=0;j<70;j++){
printf("-");
}
printf("\n");
for(m=1000;m<=n;m*=2){
aleatorio(v,m);
t = tiempos(v,m,'a');
subestimada = t/m;
ajustada = t/(m*log(m));
sobrestimada = t/pow(m,1.3);
printf("%6d%14.4f%13.6f%13.6f%13.6f\n",m,t,subestimada,ajustada,sobrestimada );
}
}
int main(){
int i;
test_mont();
printf("\n\nCREACION DEL MONTICULO");
for(i=1;i<4;i++){
printf("\niteracion %i",i);
tabla_crea_mont();
}
printf("\n\nORDENACION POR MONTICULOS VECTOR ASCENDENTE");
for(i=1;i<4;i++){
printf("\niteracion %i",i);
tabla_ord_asc();
}
printf("\n\nORDENACION POR MONTICULOS VECTOR DESCENDENTE");
for(i=1;i<4;i++){
printf("\niteracion %i",i);
tabla_ord_des();
}
printf("\n\nORDENACION POR MONTICULOS VECTOR ALEATORIO");
for(i=1;i<4;i++){
printf("\niteracion %i",i);
tabla_ord_ale();
}
}