Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > C++ Builder
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 01-12-2016
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Mi codigo de ordenacion por insercion no funciona bien

Hola amigos, estoy intentando crearme un pequeño codigo el cual coja dos arrays con enteros y los vaya insertando ordenados en un tercer array de forma ya ordenada sin tener que usar ningun otro metodo de ordenacion en ninguno de los 3 arrays. El caso es que no doy con la tecla y hace cosas raras. Os pongo mi codigo a ver si pueden echarme una mano:
Código PHP:
#include <stdio.h>
#include <stdlib.h>
 
int buscarPos(int valorint array[], int size_array)
{
    
int pos=0,aux_pos;
 
    do{
        
aux_pos=pos;
        if(
valor > array[pos]){
            
pos = (pos size_array) / 2;
            if(
aux_pos==pos && pos 0){
                
pos++;
            }
        }else{
            if(
pos && array[pos-1] < valor){
                break;
            }else if(
size_array && valor <= array[pos])
                break;
            
size_array size_array aux_pos;
            
pos size_array 2;
            if(
aux_pos==pos && pos 0){
                
pos--;
            }
        }
    }while(
pos size_array && aux_pos != pos);
    return 
pos;
}
 
int insertarElemento(int valorint array[], int size_arrayint pos)
{
    
int i;
 
    for (
i=size_arrayposi--) {
        array[
i]=array[i-1];
    }
    array[
pos]=valor;
 
    
size_array++;
    return 
size_array;
}
 
int main(int argccharargv[])
{
    
int a[]={50,2,2,100,5,3,1,7,9};
    
int b[]={4,2,6,10,8};
    
//int *c;
    
int c[50];
    
int pos,i,j;
    
int nElements=0,size_array1,size_array2;
 
    
//Solicito la memoria necesaria para colocar la lista combinada ordenada
    //c= calloc((sizeof(a)+sizeof(b))/sizeof(int),sizeof(int));
    
size_array1=sizeof(a)/sizeof(int);
    
size_array2=sizeof(b)/sizeof(int);
 
    for(
i=0,j=0;nElements size_array1+size_array2;){
        if(
i<size_array1){
            
//Obtengo la posicion que tomará dicho elemento en la lista en orden ascendente
            
pos buscarPos(a[i],c,nElements);
            
nElements insertarElemento(a[i],c,nElements,pos);
            
i++;
        }
        if(
j<size_array2){
            
pos buscarPos(b[j],c,nElements);
            
nElements insertarElemento(b[j],c,nElements,pos);
            
j++;
        }
    }
 
    for(
pos=0;pos<nElements;pos++)
        
printf("%i\n",c[pos]);
    
//free(c);
    
getchar();
    return 
0;

Gracias por adelantado.
Responder Con Cita
  #2  
Antiguo 01-12-2016
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola.

Revisa este modo:
Código PHP:
#include <stdio.h>
#include <stdlib.h>

void insertSort(int *, int);

int main()
{
  
int a[] = { 50,2,2,100,5,3,1,7,};
  
int b[] = { 4,2,6,10,};
  
int i;
  
int asz sizeof) / sizeofa[0] );
  
int bsz sizeof) / sizeofb[0] );

  
// pasar: a y b -> c
  
int *= ( int* ) mallocsizeof(int) * ( asz bsz ) );

  for ( 
0aszi++ ) c[i] = a[i];
  for ( 
0bszi++ ) c[asz+i] = b[i];

  
// mostrar original
  
for ( 0asz bszi++ ) printf"%d ",c[i] ); printf"\n\n" );

  
// ordenar
  
insertSort(c, (asz+bsz) );

  
// mostrar ordenado
  
for ( 0asz bszi++ ) printf"%d ",c[i] );

  
free);

  
getchar();
  return 
0;
}

// ordenamiento por inserción
void insertSortint *array, int size )
{
  
int i,jtmp;

  for( 
1size; ++) {
    
tmp = array[i];
    
i;
    while ( 
&& tmp < array[1] ) {
      array[
j] = array[1];
      
j--;
    }
    array[
j] = tmp;
  }

Salida:


Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #3  
Antiguo 01-12-2016
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Ese método ya lo estuve viendo pero no puedo usarlo porque ahí tu metes todos los elementos dentro y luego los ordenas y yo quiero ir metiendo los de uno en uno y a la vez colocando ya ordenado.
Responder Con Cita
  #4  
Antiguo 01-12-2016
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola.

Entiendo... no deseas ordenar un arreglo por el método de inserción, sino ir insertando en órden los ítems a medida que se van agregando al arreglo.

Entonces podes tratarlo así:
Código PHP:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

void insertInOrderint *, intint );

int main( )
{
  
int a[] = { 50,2,2,100,5,3,1,7,};
  
int b[] = { 4,2,6,10,};
  
int i;
  
int asz sizeof) / sizeofa[0] );
  
int bsz sizeof) / sizeofb[0] );
  
int tot asz bsz;

  
// inicializar c
  
int *= ( int* ) mallocsizeof(int) * tot );
  for ( 
0toti++ ) c[i] = INT_MAX;
  
  
// insertar elementos de a en c
  
for ( 0aszi++ ) insertInOrderctota[i] );
  
// insertar elementos de b en c
  
for ( 0bszi++ ) insertInOrderctotb[i] );
  
  
// mostrar
  
for ( 0toti++ ) printf"%d "c[i] );

  
free);
  
getchar();

  return 
0;
}

// Insertar en órden
void insertInOrder(int *array, int sizeint value)
{
  
int i size 1;
  while( 
value < array[i] && >= ) {
    array[
i+1] = array[i];
    
i--;
  }
  array[
i+1] = value;

Salida:


Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #5  
Antiguo 01-12-2016
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Sí, eso ya lo hice y funciona pero la idea era hacerlo de otra forma como sigue. Imagina un arreglo con 1 millón de elementos a insertar en orden, con tu método tienes que leer todo cada vez hasta encontrar su posición y eso cuantos más elementos más tardará.
Mi idea es esta
Si tengo ya los elementos:
1,2,5,6,7,10,15,20
Quiero insertar 9.
La posición inicial será la última con lo que en primer lugar lo comparo con el 20.
Como es menor divido el índice entre 2 para comparar con el del medio que en este caso sería el 6.
Como 9 es mayor que 6 la idea es coger el rango entre la posición actual y la última y comparar con el del centro. En este caso sería con el valor 10 y como 9 es menor coger el rango entre el valor 6 y el 10 y divido entre 2 y esta vez comparará con el 7 y como es mayor cojo el rango de los valores del 7 al 10 y lo divido entre 2 y ya obtendría la posición correcta.
Parece un lio pero pienso que cuando se trabaje con arrais muy grandes puede mejorar los tiempos con respecto a lo que indicas pero no doy con la tecla. He estado dándole muchas vueltas y ahora mismo la tengo así la función que obtiene la posicion pero no funciona a como quiero:
Código PHP:
int buscarPos(int valorint array[], int size_array

    
int pos=size_array,aux_pos
    if (
size_array 0){
        do{ 
            
aux_pos=pos
            if (
valor > array[pos-1]){
                if (
aux_pos == pos || valor < array[pos]){ 
                    break;
                }else {
                    
pos size_array - (size_array -pos)/2;
                }
            }else if (
valor < array [pos-1]){
                
size_array pos;
                
pos size_array 2;
                if(
aux_pos==pos){
                    break;
                }
            }else {
                break;
            }
        }while(
aux_pos != pos); 
    }
    return 
pos

Responder Con Cita
  #6  
Antiguo 01-12-2016
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola.

Si buscas velocidad de ordenamiento sobre un arreglo, por sencillez, pensaría en el algorítmo QuickSort.

Usando inserción, por mas que optimices la búsqueda del índice donde el elemento deberá ser insertado, no podrás evitar tener que hacer : N - posición desplazamientos. Imagina que en algún punto ya existen 1000000 elementos ordenados en el arreglo, vg:
Código:
[1,3,3,4,5,6,6,7,7, ... ,979827,992799,993256]
Entonces aparece el número 2... la búsqueda determina que corresponde insertar el próximo elemento en la segunda posición del arreglo. ¡ Ahora tendrá que efectuar 1000000-2 desplazamientos para hacerle lugar !
Y dado que desplazar posiciones de memoria es una taréa bastante lenta, no veo al método como el candidato mas veloz.

Otras opciones que te podrían resultar interesantes:Por último, si no necesitas tener los datos físicamente ordenados, podría servirte: Tabla hash

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #7  
Antiguo 01-12-2016
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Lo siento pero no pude contestar antes porque no he estado con internet hasta ahora. Al final lo he conseguido asi:
Código PHP:
#include <stdio.h>
#include <stdlib.h>

#define NARRAYS 4

int buscarPos(int valorint array[], int nElementos);
int insertarElemento(int valorint array[], int nElementosint pos);
int obtenerIndice(int indexint valIniint valFin);

int main(int argccharargv[])
{
    
//Esta es usada como contador para los bucles FOR
    
int i;

    
//Estas son los arrays que queremos pasar ordenados a un solo array
    //Tiene que ser intercalandolos, o sea primero uno del a, luego uno del b,
    //luego otro del c...
    
int a[]={50,2,11,55,3,1,7,9};
    
int b[]={4,2,6,10,8};
    
int c[]={9,8,7,15};
    
int d[]={56,44,22,33,88,66,77,99};

    
//Puntero para el array dinamico que contendrá todos los elementos ordenados
    
int *ordenados;

    
//Usada para guardar en el la posicion en la que hay que insertar el elemento
    
int pos;

    
//Contador del numero de elementos insertados
    
int nElements=0;

    
//Esta variable es necesaria para saber a que array le tocará insertar
    
int balanceo=0;

    
//Arrays usados para almacenar los valores o punteros a las variables
    //necesarias para el balanceo entre los arrays
    
int contador[NARRAYS],*parray[NARRAYS],size[NARRAYS],sizeTotal=0;

    
//Las inicializo con los valores y direcciones iniciales
    
parray[0]=a;
    
parray[1]=b;
    
parray[2]=c;
    
parray[3]=d;

    
size[0]=sizeof(a)/sizeof(int);
    
size[1]=sizeof(b)/sizeof(int);
    
size[2]=sizeof(c)/sizeof(int);
    
size[3]=sizeof(d)/sizeof(int);

    
//Obtengo el total de elementos que debe contener el array dinamico
    
for(i=0i<NARRAYSsizeTotal += size[i++]);

    
//Inicializo los contadores
    
for(i=0i<NARRAYScontador[i++]=0);

    
//Solicito la memoria necesaria para colocar la lista combinada ordenada
    
ordenados calloc(sizeTotal ,sizeof(int));

    while(
nElements sizeTotal){
        if(
contador[balanceo] < size[balanceo]){
            
//Obtengo la posicion que tomará dicho elemento en la lista en orden ascendente
            
pos buscarPos(parray[balanceo][contador[balanceo]],ordenados,nElements);
            
//Inserto el elemento en dicha posicion
            
nElements insertarElemento(parray[balanceo][contador[balanceo]],ordenados,nElements,pos);
            
contador[balanceo]++;
        }
        
balanceo=obtenerIndice(balanceo,0,3);
    }

    for(
pos=0;pos<nElements;pos++)
        
printf("%i\n",ordenados[pos]);
    
free(ordenados);
    
getchar();
    return 
0;
}
//---------------------------------------------------------------------------

int buscarPos(int valorint array[], int nElementos)
{
    
//Esta la uso como indice para posicionarme en el elemento del array
    //Empiezo comparando con el ultimo elemento por lo que lo inicializo para ello
    
int pos=nElementos-1;


    
int aux_pos//La uso para saber si al dividir me da el mismo indice
    
int pos_ini=0//Contendra el indice inicial desde el que buscar
    
int pos_fin=pos//Contendra el indice final hasta donde buscar

    //En este condicional solo entro si el numero de elementos es mayor que 0
    //ya que si vale 0 solo tengo que colocarlo en la primera posicion
    
if(nElementos 0)
    {
        do{
            
aux_pos=pos;
            if(
valor > array[pos]){
                
//Si entro aqui quiere decir que todos los elementos del array
                //hasta la posicion indicada en el indice son menores con lo que
                //la posicion inicial pasa a ser la posicion indicada por pos
                
pos_ini pos;

                
//Obtengo el indice del centro entre la posicion inicial y la final
                
pos pos_ini + (pos_fin pos_ini) / 2;

                
//Si el valor es mayor que el de la posicion del array y se
                //cumple el siguiente condicional hay que incrementar en 1 la
                //posicion ya que solo hay que pasar esa posicion para que quede
                //en el sitio correcto
                
if(aux_pos == pos){
                    
pos++;
                    break;
                }
            }else if(
valor < array[pos]){
                
//Si entro aqui es porque todos los elementos del array desde la
                //posicion indicada hasta el final del array son mayores que el
                //valor buscado con lo que la posicion final pasa a ser la
                //posicion indicada por pos
                
pos_fin pos;

                
//Obtengo el indice del centro entre la posicion inicial y la final
                
pos pos_ini + (pos_fin pos_ini) / 2;
            }
        }while(
aux_pos != pos);
    }else{
        
pos=0;
    }
    return 
pos;
}
//---------------------------------------------------------------------------

int insertarElemento(int valorint array[], int nElementosint pos)
{
    
int i;

    
//Si hay que intercalar un elemento desplazo todos los que esten a partir de
    //esa posicion hacia el siguiente elemento a la derecha
    
for (i=nElementosposi--) {
        array[
i]=array[i-1];
    }
    
//Coloco el elemento en el lugar que le corresponde
    
array[pos]=valor;

    
nElementos++;
    return 
nElementos;
}
//---------------------------------------------------------------------------

//Obtengo el indice usando el balanceo deseado en este caso
int obtenerIndice(int indexint valIniint valFin)
{
    
index++;
    if(
index valFin)
        
index=valIni;
    return 
index;
}
//--------------------------------------------------------------------------- 
Realmente no es algo estrictamente de eficiencia sino que estaba experimentando a ver si podia hacerlo o era muy complejo para mi y digamos que esta a medio camino jajaja.
Tengo algunas dudas:
1-Esta parte:
Código PHP:
    //Las inicializo con los valores y direcciones iniciales
    
parray[0]=a;
    
parray[1]=b;
    
parray[2]=c;
    
parray[3]=d
¿Hay alguna manera de inicializarlo usando un bucle de forma sencilla como hago por ejemplo con los contadores?
2-Misma duda pero con esta parte:
Código PHP:
    size[0]=sizeof(a)/sizeof(int);
    
size[1]=sizeof(b)/sizeof(int);
    
size[2]=sizeof(c)/sizeof(int);
    
size[3]=sizeof(d)/sizeof(int); 
La cosa es que si añado mas arrays se me puede olvidar inicializar uno de estos dos para ese array por eso pregunto si hay alguna manera de desentenderme de ello haciendo que se inicialicen todos en un bucle.
Si todos los arrays no fueran cada uno por su lado, fueran todos en un array de arrays y todos con el mismo tamaño no habria problema pero quiero saber como hacerlo en este caso en que cada array va por su lado y pueden tener tamaños diferentes.

Última edición por aguml fecha: 01-12-2016 a las 13:36:29.
Responder Con Cita
  #8  
Antiguo 01-12-2016
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Por otro lado con 2 arrays de 1000000 bastaria con unas 20 iteraciones maximo por numero en el peor de los casos ya que truncando los decimales como hago tengo esto:
Código:
1000000/2=500000; 500000/2=250000; 250000/2=125000; 125000/2=75000; 75000/2=37500; 37500/2=18750; 18750/2=9375; 9375/2=4687; 4687/2=2343; 2343/2=1171; 1171/2=585; 585/2=292; 292/2=146; 146/2=73; 73/2=36; 36/2=18; 18/2=9; 9/2=4; 4/2=2; 2/2=1; 1/2=0
Responder Con Cita
  #9  
Antiguo 01-12-2016
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.911
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Para este tipo de tareas es bueno este recurso:

https://rosettacode.org/wiki/Categor...ing_Algorithms

(Cada ejemplo esta implementado en decenas de diferentes lenguajes, no solo mostrando como seria en el tuyo sino dejandote ver otras formas de hacerlo!)

Y si estas buscando como hacer el sort mas eficiente, tienes que leer los diversos algoritmos a ver cual da la talla para el caso especifico:

https://stackoverflow.com/questions/...ly-sorted-data
__________________
El malabarista.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
funciona bien en windows 7 64b pero en XP no funciona ASAPLTDA Varios 5 06-05-2011 16:24:50
funcion RANDOM ... funciona bien ?!!!!! ingel Varios 5 07-04-2010 15:22:08
No funciona bien el QrImage en el QReport AGAG4 Impresión 11 29-10-2008 16:16:56
QRImage no funciona bien eljinete Impresión 4 16-12-2005 01:02:05
La insercion de registros funciona pero..... ilichhernandez Conexión con bases de datos 1 22-10-2005 11:24:33


La franja horaria es GMT +2. Ahora son las 13:05:59.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi