ahora te respondo bien:
¿Para qué en la función Insertar y Borrar se usa un puntero a puntero(**)?
tanto en insertar como en borrar veo un solo *, y esta bien asi
¿Por qué al llamar a las funciones Insertar y Borrar se pasa &lista (por qué se tiene que pasar de esa manera y no como lista solo)?
xq las estas pasando por referencia, entonces tenes q pasarle la direccion de memoria.
&lista te devuelve la direccion de memoria de lista cuando llamas a la funcion y pasas eso
Insertar(&lista, 20); estas diciendole cual es la posicion de memoria donde esta lista
si te fijas tu funcion es
void Insertar(Lista *lista, int v)
donde *lista indica q eso es un puntero a un objeto de tipo Lista, como habias pasado la direccion de memoria cuando la llamas desde el programa principal haciendo Insertar(&lista,20), esto entra al dato q esta en esa posicion de memoria y q es de tipo Lista
supone q tu lista esta en la posicion de memoria esta en la posicion 0000:1234 de memoria
Insertar (&lista, 20) esta pasando como parametros
en int v, 20
y en &lista, 0000:1234
cuando la funcion toma estos parametros los lee asi:
a v como 20
y a *lista, lee 0000:1234 y ve q hay un objeto de tipo lista en esa posicion
¿Cuándo uno pasa un puntero a una función y cambia hacia donde apunta una vez que sale de esa función conserva el cambio (pasado por referencia)?
si esta pasado por referencia si, xq cuando pasas por referencia pasas una direccion de memoria, como te explique en la anterrior, si vos en la funcion cambiarias &lista=0000:2345, y te fijas q hay en *lista, ves q contiene lo q este almacenado en esa direccion de memoria.
espero haber explicado. cualquier cosa volve a explicar
PD: trata de la proxima vez subir el codigo de forma legible
Código:
#include <stdlib.h>
#include <stdio.h>
typedef struct _nodo
{
int valor; struct _nodo *siguiente;
}tipoNodo;
typedef tipoNodo *pNodo;
typedef tipoNodo *Lista;
/* Funciones con listas: */
void Insertar(Lista *l, int v);
void Borrar(Lista *l, int v);
int ListaVacia(Lista l);
void BorrarLista(Lista *);
void MostrarLista(Lista l);
int main()
{
Lista lista = NULL;
pNodo p;
Insertar(&lista, 20);
Insertar(&lista, 10);
Insertar(&lista, 40);
Insertar(&lista, 30);
MostrarLista(lista);
Borrar(&lista, 10);
Borrar(&lista, 15);
Borrar(&lista, 45);
Borrar(&lista, 30);
Borrar(&lista, 40);
MostrarLista(lista);
BorrarLista(&lista);
getchar();
return 0;
}
void Insertar(Lista *lista, int v)
{
pNodo nuevo, anterior; /* Crear un nodo nuevo */
nuevo = (pNodo)malloc(sizeof(tipoNodo));
nuevo->valor = v; /* Si la lista está vacía */
if(ListaVacia(*lista) || (*lista)->valor > v)
{ /* Añadimos la lista a continuación del nuevo nodo */
nuevo->siguiente = *lista;
/* Ahora, el comienzo de nuestra lista es en nuevo nodo */
*lista = nuevo;
}
else
{ /* Buscar el nodo de valor menor a v */
anterior = *lista; /* Avanzamos hasta el último elemento o hasta que el siguiente tenga un valor mayor que v */
while(anterior->siguiente && anterior->siguiente->valor <= v)
{
anterior = anterior->siguiente; /* Insertamos el nuevo nodo después del nodo anterior */
}
nuevo->siguiente = anterior->siguiente;
anterior->siguiente = nuevo;
}
}
void Borrar(Lista *lista, int v)
{
pNodo anterior, nodo;
nodo = *lista;
anterior = NULL;
while(nodo && nodo->valor < v)
{
anterior = nodo;
nodo = nodo->siguiente;
}
if(!nodo || nodo->valor != v)
return;
else
{ /* Borrar el nodo */
if(!anterior) /* Primer elemento */
*lista = nodo->siguiente;
else /* un elemento cualquiera */
anterior->siguiente = nodo->siguiente;
free(nodo);
}
}
int ListaVacia(Lista lista)
{
return (lista == NULL);
}
void BorrarLista(Lista *lista)
{
pNodo nodo;
while(*lista)
{ nodo = *lista;
*lista = nodo->siguiente;
free(nodo);
}
}
void MostrarLista(Lista lista)
{
pNodo nodo = lista;
if(ListaVacia(lista))
printf("Lista vacía\n");
else
{
while(nodo)
{
printf("%d -> ", nodo->valor);
nodo = nodo->siguiente;
}
printf("\n");
}
}
SaluT