Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Duda con punteros

Estas en el tema de Duda con punteros en el foro de C/C++ en Foros del Web. Hola, estoy haciendo unos programas relacionados con estructuras, en este caso concreto estoy mirando los arboles binarios de búsqueda. Hay una cosa que no sé ...
  #1 (permalink)  
Antiguo 28/07/2011, 16:24
 
Fecha de Ingreso: marzo-2011
Mensajes: 94
Antigüedad: 13 años, 1 mes
Puntos: 3
Duda con punteros

Hola, estoy haciendo unos programas relacionados con estructuras, en este caso concreto estoy mirando los arboles binarios de búsqueda. Hay una cosa que no sé por qué pasa.

Tomo la siguiente estructura:

Código C:
Ver original
  1. typedef struct arbol_binario{
  2.    
  3.     int nodo; //valor del nodo padre
  4.    
  5.     struct arbol_binario *ptrIzq; //puntero al nodo izquierdo
  6.    
  7.     struct arbol_binario *ptrDrcho; //puntero al nodo derecho
  8.    
  9. } nuevoArbol, *ptrNuevoArbol;

Para añadir un nuevo elemento, lo hago con malloc.

Veamos, una vez que tengo un arbol binario construido, si quiero modificar un elemento, por ejemplo el hijo derecho de *arbol podría hacer:

Código C:
Ver original
  1. ptrNuevoArbol ptrDir = &(arbol->ptrDrcho);
  2.  
  3. (*ptrDir) = *arbol2;

y ya donde estaba arbol ahora esta arbol2.

Veamos, lo que no entiendo muy bien es que dirección de memoria hay en arbol, cuando *arbol es el puntero que devuelve malloc al bloque de memoria. Qué hay en expresiones del tipo (&(arbol->ptrDrcho)), osea, donde las declaro y eso. Y además, si esas expresiones son punteros a los punteros a los bloques de memoria, por qué al modificar los bloques a los que apuntan se modifica el arbol? yo creía que ptrDrcho y ptrIzq apuntaban los propios bloques de memoria, con lo cual para eliminar un nodo tendría que hacer apuntar a estos a otro bloque de memoria, pero si cojo y cambio el puntero a dicho bloque a otro bloque diferente, ya se cambia.

No sé si se me entenderá algo, me temo que poco... jej

Un slaudo!
  #2 (permalink)  
Antiguo 28/07/2011, 16:31
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años
Puntos: 228
Respuesta: Duda con punteros

Para empezar esto esta mal:

Código C++:
Ver original
  1. ptrNuevoArbol ptrDir = arbol;
  2.  
  3. (*ptrDir)->nodo = n;

Deberia ser:
ptrDir->nodo = n;

o

(*ptrDir).nodo = n;

La primera es una abreviacion de la segunda.

ptrDir es del tipo puntero a struct arbol_binario. En ella contiene un numero que representa una direccion de memoria.

Al usar el operador * estamos accediendo a la memoria que apunta y podemos tratarla como si fuese una variable de ese tipo.

Sobre la otra duda que comentaste en ese extenso parrafo no termine de entenderla. Lo unico que te digo *arbol no es un puntero es la estructura.
  #3 (permalink)  
Antiguo 28/07/2011, 16:36
 
Fecha de Ingreso: marzo-2011
Mensajes: 94
Antigüedad: 13 años, 1 mes
Puntos: 3
Respuesta: Duda con punteros

Perdona sam90, me confundí a la hora de escribir el mensaje y lo modifiqué antes de que contestaras, no me imaginé que serías tan rápido jeje

Si *arbol no es un puntero a la estructura, entonces por qué hay que hacer **arbol.nodo para acceder al nodo?
  #4 (permalink)  
Antiguo 28/07/2011, 19:43
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años
Puntos: 228
Respuesta: Duda con punteros

En el codigo que muetras cual es la definicion de arbol??

lo que te puedo decir es que ptrDir es un puntero a la structura arbol_binario.

ptrNuevoArbol ptrDir = struct arbol_binario *

Y al usar puntero ten en cuenta que solo cambias direcciones. cuando dices "y ya donde estaba arbol ahora esta arbol2. " no es asi..simplemente estas señalando a otro lado. pero arbol sigue estando en su lugar.

Igualemnte me gustaria ver mas codigo de lo que estas haciendo. Porque hay tipos que no concuerdan.

Con esta linea: ptrNuevoArbol ptrDir = &(arbol->ptrDrcho);
el compilador dice
warning: initialization from incompatible pointer type

Ya que uno es un puntero y el otro es un puntero de puntero.
  #5 (permalink)  
Antiguo 29/07/2011, 03:07
 
Fecha de Ingreso: marzo-2011
Mensajes: 94
Antigüedad: 13 años, 1 mes
Puntos: 3
Respuesta: Duda con punteros

Perdon joder valla día.... me cagoen to lo escribo mal 10 veces igual... mira te copio el código de lo que hice y ya esta:

Código C:
Ver original
  1. /*Esta funcion sirve para eliminar un nodo de un ABB de forma recursiva:
  2.  
  3.  
  4. int eliminar_nodo ( ptrNuevoArbol * ptrRaiz, int elemento ){
  5.    
  6.     if ( *ptrRaiz == NULL ){
  7.          
  8.          return 0;
  9.          
  10.     }
  11.    
  12.     else if ( (*ptrRaiz)->nodo > elemento ){
  13.          
  14.          return ( eliminar_nodo ( &((*ptrRaiz)->ptrIzq), elemento ) );
  15.          
  16.     }
  17.    
  18.     else if ( (*ptrRaiz)->nodo < elemento ){
  19.          
  20.          return ( eliminar_nodo ( &((*ptrRaiz)->ptrDrcho), elemento ) );
  21.          
  22.     }
  23.    
  24.     else if ( (*ptrRaiz)->nodo == elemento ){
  25.          
  26.          if ( (*ptrRaiz)->ptrIzq == NULL ){
  27.              
  28.               ptrNuevoArbol temp = *ptrRaiz;
  29.              
  30.               *ptrRaiz = (*ptrRaiz)->ptrDrcho;
  31.              
  32.               free(temp);
  33.              
  34.               return 1;
  35.              
  36.          }
  37.          
  38.          else if ( (*ptrRaiz)->ptrDrcho == NULL ){
  39.              
  40.               ptrNuevoArbol temp = *ptrRaiz;
  41.              
  42.               *ptrRaiz = (*ptrRaiz)->ptrIzq;
  43.              
  44.               free(temp);
  45.              
  46.               return 1;
  47.              
  48.          }
  49.          
  50.          else{
  51.              
  52.               ptrNuevoArbol aux = *ptrRaiz;
  53.              
  54.               intercambiar ( ptrRaiz, &aux );
  55.              
  56.               return 1;
  57.              
  58.          }
  59.          
  60.     }
  61.    
  62. }*/
  63.  
  64. /*void intercambiar ( ptrNuevoArbol *ptrRaiz, ptrNuevoArbol *aux ){
  65.      
  66.      if ( (*ptrRaiz)->ptrIzq != NULL ){
  67.          
  68.           intercambiar ( &((*ptrRaiz)->ptrIzq), aux );
  69.          
  70.      }
  71.      
  72.      else{
  73.          
  74.           (*aux)->nodo = (*ptrRaiz)->nodo;
  75.          
  76.           ptrNuevoArbol temp = *ptrRaiz;
  77.          
  78.           *ptrRaiz = (*ptrRaiz)->ptrDrcho;
  79.          
  80.           free (temp);
  81.          
  82.      }
  83.      
  84. }*/
  85.  
  86. //Esta funcion elimina un nodo de un ABB  
  87.  
  88. int eliminar_nodo ( ptrNuevoArbol * ptrRaiz, int elemento ){
  89.    
  90.     ptrNuevoArbol *ptrDir = ptrRaiz;
  91.    
  92.     while ( (*ptrDir)->nodo != elemento ){
  93.          
  94.           if ( *ptrDir == NULL ){
  95.                
  96.                return 0;
  97.                
  98.           }
  99.          
  100.           else if ( (*ptrDir)->nodo > elemento ){
  101.                
  102.                ptrDir = &((*ptrDir)->ptrIzq);
  103.                
  104.           }
  105.          
  106.           else if ( (*ptrDir)->nodo < elemento ){
  107.                
  108.                ptrDir = &((*ptrDir)->ptrDrcho);
  109.                
  110.           }
  111.          
  112.     }
  113.  
  114.     if ( (*ptrDir)->ptrIzq == NULL ){
  115.              
  116.               ptrNuevoArbol temp = *ptrDir;
  117.              
  118.               *ptrDir = (*ptrDir)->ptrDrcho;
  119.              
  120.               free(temp);
  121.              
  122.               return 1;
  123.              
  124.     }
  125.          
  126.     else if ( (*ptrDir)->ptrDrcho == NULL ){
  127.              
  128.               ptrNuevoArbol temp = *ptrDir;
  129.              
  130.               *ptrDir = (*ptrDir)->ptrIzq;
  131.              
  132.               free(temp);
  133.              
  134.               return 1;
  135.              
  136.     }
  137.          
  138.     else{
  139.              
  140.               ptrNuevoArbol aux = *ptrDir;
  141.              
  142.               intercambiar ( ptrDir, &aux );
  143.              
  144.               return 1;
  145.              
  146.     }
  147.          
  148. }
  149.  
  150. /*Esta funcion intercambia el nodo de aux por el mayor del subarbol izquierdo*/
  151.  
  152. void intercambiar ( ptrNuevoArbol *ptrDir, ptrNuevoArbol *aux ){
  153.      
  154.      ptrDir = &((*ptrDir)->ptrDrcho);
  155.      
  156.      while ( (*ptrDir)->ptrIzq != NULL ){
  157.            
  158.            ptrDir = &((*ptrDir)->ptrIzq);
  159.            
  160.      }
  161.          
  162.      (*aux)->nodo = (*ptrDir)->nodo;
  163.          
  164.      ptrNuevoArbol temp = *ptrDir;
  165.          
  166.      *ptrDir = (*ptrDir)->ptrDrcho;
  167.          
  168.      free (temp);
  169.          
  170. }

Y no era ptrNuevoArbol ptrDir, era ptrNuevoArbol *ptrDir.

Aver si soy capaz de explicarme. Yo tengo un nodo, el cual tiene un puntero derecho y un puntero izquierdo (por definicion de la estructura ABB). Esos dos punteros (me refiero al izquierdo y al derecho) lo que almacenan es una direccion de memoria en la que se encuentra una estructura. Hasta ahí todo tiene sentido para mi. Lo que no entiendo es, al hacer &((*arbol)->ptrDrcho), que dirección hay ahí y por qué al modificar la dirección a la que apunta se modifica también la dirección a la que apunta (*arbol)->ptrDrcho

Un saludo!
  #6 (permalink)  
Antiguo 29/07/2011, 10:47
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años
Puntos: 228
Respuesta: Duda con punteros

&((*arbol)->ptrDrcho) aca esta la direccion de memoria donde esta almacenado el puntero que apunta a un nodo, el derecho.

Esta trabajando con doble puntero porque si te fijas ptrDir se le asigna la raiz. Lo que busca es poder modificar donde esta la riaz en el caso de que la tengas que eliminar.

Si recien estas empezando con punteros, me parece un ejercicio bastante complicado. Saludos
  #7 (permalink)  
Antiguo 31/07/2011, 08:24
 
Fecha de Ingreso: marzo-2011
Mensajes: 94
Antigüedad: 13 años, 1 mes
Puntos: 3
Respuesta: Duda con punteros

Una pregunta sobre el tema. Cuando haces malloc ( sizeof ( struct arbol_binario ) ), se reserva una dirección de memoria para el entero y dos para punteros (hijo izquierdo e hijo derecho)? Es decir que si creo un nuevo nodo tendré una dirección de memoria para un dato tipo int y dos direcciones donde almacenaré apuntadores a otras estructuras tipo arbol_binario. En ese caso, al hacer &((*ptrDir)->ptrDrcho) estaré pasando la dirección del hijo derecho, una dirección que se creo al hacer malloc.

Un saludo!
  #8 (permalink)  
Antiguo 31/07/2011, 08:50
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años
Puntos: 228
Respuesta: Duda con punteros

Cuando una usa malloc no reserva una direccion de memoria. Lo que reserva es la memoria. y malloc devuelve un puntero a esa mamoria para que vos la utilizes y la interprete como quieras.

En tu caso estas pidiendo memoria para un entero y dos punteros.

Luego seguramente pides memoria para dos nodos mas y el resultado de cada malloc (oseala direccion a la memorai reservada) la asignas a cada uno de esos punteros. Asi puedes ir moviendote entre cada nodo reservado por malloc.

Saludos
  #9 (permalink)  
Antiguo 31/07/2011, 13:28
 
Fecha de Ingreso: marzo-2011
Mensajes: 94
Antigüedad: 13 años, 1 mes
Puntos: 3
Respuesta: Duda con punteros

Gracias por la ayuda

Etiquetas: binario, programa, punteros
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 01:00.