<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>el blog de giltesa</title>
	
	<link>http://giltesa.com</link>
	<description />
	<lastBuildDate>Fri, 10 Feb 2012 00:44:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/BlogDeGiltesa" /><feedburner:info uri="blogdegiltesa" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>BlogDeGiltesa</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>6×06: Bicolas en lenguaje C</title>
		<link>http://feedproxy.google.com/~r/BlogDeGiltesa/~3/e6G3dZM90Jc/</link>
		<comments>http://giltesa.com/2012/02/10/6x06-bicolas-en-lenguaje-c/#comments</comments>
		<pubDate>Fri, 10 Feb 2012 00:44:42 +0000</pubDate>
		<dc:creator>giltesa</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Programación]]></category>

		<guid isPermaLink="false">http://giltesa.com/?p=8928</guid>
		<description />
			<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://giltesa.com/wp-content/uploads/2012/02/bicolas.png"><img class="alignnone size-medium wp-image-8930" title="bicolas" src="http://giltesa.com/wp-content/uploads/2012/02/bicolas-323x270.png" alt="" width="323" height="270" /></a></p>
<p><span id="more-8928"></span></p>
<pre class="brush: cpp; title: ; notranslate">
/*
6x06-Uso_de_bicolas
09/02/2012

Una bicola es una estructura de datos dinámica, similar a una cola, pero en la que cada elemento apunta además de al siguiente,también al anterior. Es decir, está doblemente encadenada. Implementa una bicola con las siguientes operaciones:

	a. creaVacia: Crea una bicola vacía.
	b. agnadeIzq: Añade un elemento a la bicola por la izquierda.
	c. agnadeDer: Añade un elemento a la bicola por la derecha.
	d. eliminaIzq: Elimina un elemento de la bicola por la izquierda.
	e. eliminaDer: Elimina un elemento de la bicola por la derecha.
	f. observaIzq: Devuelve el elemento que hay más a la izquierda.
	g. observaDer: Devuelve el elemento que hay más a la derecha.
	h. esVacia: Indica si la bicola está o no vacía.
	i. long: Devuelve la longitud de la bicola.
	j. asigna: copia una bicola en otra.
	k. libera: Destruye una bicola liberando toda la memoria que ocupaba.
	l. iguales: Indica si dos bicolas son iguales o no, en cuanto a los elementos que contienen ambas exactamente en el mismo orden.
*/

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

struct INFO
{
	int num;
};

struct NODO
{
	struct INFO elemento;
	struct NODO *p_anterior;
	struct NODO *p_siguiente;
};

struct BICOLA
{
	int nodos;
	struct NODO *primero;
	struct NODO *ultimo;
};

/* FUNCIONES ******************************************************************/

// Pone los punteros de una bicola a NULL
void inicializarBicola( struct BICOLA **bicola )
{
	/*
	Precondición:
					Se recibe un doble puntero de tipo struct BICOLA a una Bicola sin inicializar..
	Poscondición:
					Se inicializa la Bicola poniéndola a NULL o 0 según el parámetro a inicializar.
	*/

	// Se solicita memoria al sistema para la nueva Bicola:
	struct BICOLA *temp = (struct BICOLA *) malloc(sizeof(struct BICOLA));

	temp-&gt;nodos		= 0;
	temp-&gt;primero	= NULL;
	temp-&gt;ultimo	= NULL;

	(*bicola) 		= temp;

};

// Inserta nodos por la izquierda:
void insertIzqBicola( struct BICOLA **bicola, int dato )
{
	/*
	Precondición:
					Se recibe un doble puntero de tipo struct BICOLA a una Bicola y un parámetro de tipo entero con el dato a introducir.
	Poscondición:
					Se inserta al principio un nuevo Nodo en la Bicola.
	*/

	// Se solicita memoria al sistema para el nuevo Nodo:
	struct NODO *temp = (struct NODO *) malloc(sizeof(struct NODO));

	// Si la Bicola no tiene Nodos se inserta sin mas
	if( (*bicola)-&gt;primero == NULL )
	{
		temp-&gt;elemento.num	= dato;					// Se guarda el nuevo dato en el nuevo Nodo.
		temp-&gt;p_anterior	= NULL;					// Como es el primer Nodo de la Bicola, tanto el puntero anterior como el siguiente apuntan a NULL.
		temp-&gt;p_siguiente	= NULL;

		(*bicola)-&gt;primero	= temp;					// Como es el primer Nodo de la Bicola, se hace que primero y ultimo apunten ambos al mismo Nodo.
		(*bicola)-&gt;ultimo	= temp;
	}
	else
	{
		temp-&gt;elemento.num	= dato;					// Se guarda el dato nuevo en el nuevo Nodo.
		temp-&gt;p_anterior	= NULL;					// Como el nuevo Nodo va a ser el primero de la Bicola no apuntara a ningún Nodo anterior.
		temp-&gt;p_siguiente	= (*bicola)-&gt;primero;	// El nuevo Nodo apuntara al siguiente Nodo (donde ahora apunta &quot;primero&quot;.

		(*bicola)-&gt;primero-&gt;p_anterior	= temp;		// El puntero anterior del primer Nodo se hace que apunte al nuevo Nodo.
		(*bicola)-&gt;primero				= temp;		// El puntero del primero se hace que apunte al nuevo Nodo que ahora es el primero.
	};

	(*bicola)-&gt;nodos += 1;							// Se suma 1 a la variable que guarda el numero de Nodos de la Bicola.

};

// Inserta nodos por la derecha:
void insertDerBicola( struct BICOLA **bicola, int dato )
{
	/*
	Precondición:
					Se recibe un doble puntero de tipo struct BICOLA a una Bicola y un parámetro de tipo entero con el dato a introducir.
	Poscondición:
					Se inserta al final un nuevo Nodo en la Bicola.
	*/

	struct NODO *temp = (struct NODO *) malloc(sizeof(struct NODO));

	// Si la bicola esta vacía se introduce sin mas:
	if( (*bicola)-&gt;primero == NULL )
	{
		temp-&gt;elemento.num	= dato;
		temp-&gt;p_anterior	= NULL;
		temp-&gt;p_siguiente	= NULL;

		(*bicola)-&gt;primero	= temp;
		(*bicola)-&gt;ultimo	= temp;
	}
	  // Si contiene nodos, se introduce al final de todos ellos:
	else
	{
		temp-&gt;elemento.num	= dato;
		temp-&gt;p_anterior	= (*bicola)-&gt;ultimo;
		temp-&gt;p_siguiente	= NULL;

		(*bicola)-&gt;ultimo-&gt;p_siguiente	= temp;
		(*bicola)-&gt;ultimo				= temp;
	};

	(*bicola)-&gt;nodos += 1;

};

// Elimina el primer Nodo:
void eliminaIzqBicola( struct BICOLA **bicola )
{
	/*
	Precondición:
					Se recibe un doble puntero de tipo struct BICOLA a una Bicola.
	Poscondición:
					Se elimina el primer Nodo de la Bicola.
	*/

	struct NODO *aBorrar;

	// Si la Bicola esta vacía...
	if( (*bicola)-&gt;primero == NULL )
	{
		printf( &quot;No puede eliminar Nodos de una Bicola vacía.&quot; );
	}
	  // Si solo hay un Nodo en la Bicola, al liberar la RAM del Nodo se inicializa la Bicola a los valores por defecto:
	else if( (*bicola)-&gt;nodos == 1 )
	{
		free(*bicola);
		inicializarBicola( bicola );
	}
	  // En caso contrario se elimina solo el primer Nodo:
	else if( (*bicola)-&gt;nodos &gt; 1 )
	{
		aBorrar = (*bicola)-&gt;primero;

		(*bicola)-&gt;primero-&gt;p_siguiente-&gt;p_anterior	= NULL;
		(*bicola)-&gt;primero							= (*bicola)-&gt;primero-&gt;p_siguiente;
		free(aBorrar);

		(*bicola)-&gt;nodos -= 1;
	};

};

// Elimina el ultimo Nodo:
void eliminaDerBicola( struct BICOLA **bicola )
{
	/*
	Precondición:
					Se recibe un doble puntero de tipo struct BICOLA a una Bicola.
	Poscondición:
					Se elimina el ultimo Nodo de la Bicola.
	*/

	struct NODO *aBorrar;

	// Si la Bicola esta vacia...
	if( (*bicola)-&gt;primero == NULL )
	{
		printf( &quot;No puede eliminar Nodos de una Bicola vacía.&quot; );
	}
	  // Si solo hay un Nodo en la Bicola, al liberar la RAM del Nodo se inicializa la Bicola a los valores por defecto:
	else if( (*bicola)-&gt;nodos == 1 )
	{
		free(*bicola);
		inicializarBicola( bicola );
	}
	else if( (*bicola)-&gt;nodos &gt; 1 )
	{
		aBorrar = (*bicola)-&gt;ultimo;

		(*bicola)-&gt;ultimo-&gt;p_anterior-&gt;p_siguiente	= NULL;
		(*bicola)-&gt;ultimo							= (*bicola)-&gt;ultimo-&gt;p_anterior;
		free(aBorrar);

		(*bicola)-&gt;nodos -= 1;
	};

};

// Devuelve un true o un false si la Bicola contiene o no Nodos:
int tieneNodosLaBicola( struct BICOLA **bicola )
{
	/*
	Precondición:
					Se recibe un doble puntero de tipo struct BICOLA a una Bicola.
	Poscondición:
					Se devuelve un parámetro de tipo entero con valores true 1 o false 0 dependiendo de si la Bicola contiene Nodos o no.
	*/

	int resp = 0;

	if( (*bicola)-&gt;nodos != 0 )
		resp = 1;

	return resp;
};

// Libera la memoria RAM usada por la Bicola:
void borraLaBicola( struct BICOLA **bicola )
{
	/*
	Precondición:
					Se recibe un doble puntero de tipo struct BICOLA a una Bicola.
	Poscondición:
					Se libera la RAM usada por los Nodos contenidos en la Bicola.
	*/

	struct NODO *actual, *siguiente;
	actual = (*bicola)-&gt;primero;

	while( actual != NULL )
	{
		siguiente = actual-&gt;p_siguiente;
		free(actual);
		actual = siguiente;
	};

	*bicola = NULL;
};

// Devuelve el número de Nodos que contiene la Bicola:
int cuantosNodosTieneLaBicola( struct BICOLA **bicola )
{
	/*
	Precondición:
					Se recibe un doble puntero de tipo struct BICOLA a una Bicola.
	Poscondición:
					Se devuelve un parámetro de tipo entero que indica el número de Nodos que contiene la Bicola.
	*/

	return (*bicola)-&gt;nodos;
};

// Copia la bicola original a la bicola copia:
void copiarLaBicola( struct BICOLA **bicolaA, struct BICOLA **bicolaB )
{
	/*
	Precondición:
					Se han de recibir dos dobles punteros de tipo struct BICOLA a dos Bicolas.
	Poscondición:
					Se copia íntegramente la BicolaA en la BicolaB
	*/

	struct NODO *temp = (struct NODO *) malloc(sizeof(struct NODO));
	temp = (*bicolaA)-&gt;primero;

	// Si la BicolaB no esta vacia, se libera la RAM antes de copiar la BicolaA en BicolaB.
	if( (*bicolaB)-&gt;primero != NULL )
	{
		borraLaBicola( bicolaB );		// Se borra y se inicializa.
		inicializarBicola( bicolaB );
	};

	if( temp == NULL )
		printf( &quot;La Bicola A no contiene Nodos, no se puede copiar nada.&quot; );
	else
	{
		while( temp != NULL )
		{
			// Se inserta al final:
			insertDerBicola( bicolaB, temp-&gt;elemento.num );

			// Se avanza un Nodo hacia delante:
			temp = temp-&gt;p_siguiente;
		};

	};

	free(temp);

};

// Compara dos bicolas, devuelve true o false
int sonIgualesLasBicolas( struct BICOLA **bicolaA, struct BICOLA **bicolaB )
{
	/*
	Precondición:
					Se han de recibir dos dobles punteros de tipo struct BICOLA a dos Bicolas.
	Poscondición:
					Se devuelve un true 1 si las dos Bicolas son idénticas. En caso de que haya alguna diferencia entre ellas, ya sea en el contenido de sus Nodos o en la longitud de las Bicolas se devolverá un false 0.
	*/

	struct NODO *bicA = (struct NODO *) malloc(sizeof(struct NODO));
	struct NODO *bicB = (struct NODO *) malloc(sizeof(struct NODO));
	int salirBucle=0, resp=1;

	bicA = (*bicolaA)-&gt;primero;
	bicB = (*bicolaB)-&gt;primero;

	if( bicA == NULL ||  bicB == NULL )
	{
		resp = 0;

		if( bicA == NULL )
			printf( &quot;Debe de insertar antes algún Nodo en la Bicola A\n&quot; );

		if( bicB == NULL )
			printf( &quot;Debe de insertar antes algún Nodo en la Bicola B\n&quot; );
	}
	else
	{
		while( !salirBucle )
		{
			// Si alguno de los datos (num en este caso) del elemento de cada Nodo de la Bicola es diferente de la copia, devuelve false:
			if( bicA-&gt;elemento.num != bicB-&gt;elemento.num )
			{
				resp = 0;
				salirBucle = 1;
			}
			 // Si todo es igual...
			else
			{
				// Si los dos punteros siguen a puntando a algo diferente de NULL se avanza una posición:
				bicA = bicA-&gt;p_siguiente;
				bicB = bicB-&gt;p_siguiente;

				// Si alguno de los dos punteros ha llegado a NULL antes que el otro, las Bicolas están mal copiadas:
				if( (bicA != NULL  &amp;&amp;  bicB == NULL)  ||  (bicA == NULL  &amp;&amp;  bicB != NULL) )
				{
					resp = 0;
					salirBucle = 1;
				}
				  // Si por el contrario, las dos están a NULL a la vez, se termina la iteración y se devuelve true;
				else if( (bicA == NULL  &amp;&amp;  bicB == NULL) )
				{
					salirBucle = 1;
				};

			};

		};

	};

	return resp;

};

// imprime por pantalla el contenido de todos los Nodos de la Bicola:
void imprimeBicola( struct BICOLA **bicola )
{
	/*
	Precondición:
					Se recibe un doble puntero de tipo struct BICOLA a una Bicola.
	Poscondición:
					Se imprime por pantalla el contenido de todos los Nodos.
	*/

	struct NODO *bic = (*bicola)-&gt;primero;

	if( bic == NULL )
		printf( &quot;La Bicola no contiene Nodos.&quot; );
	else
	{

		printf( &quot;Su Bicola contiene: &quot; );

		while( bic != NULL )
		{
			printf( &quot;%i, &quot;, bic-&gt;elemento.num );
			bic = bic-&gt;p_siguiente;
		};

		printf( &quot;\n\n&quot; );

	};

};

/****************************************************************** FUNCIONES */

/**************************************************************************************************************************/
main()
{
	enum opciones{ salir, insertIzq, insertDer, eliminaIzq, eliminaDer, impIzq, impDer, impTodos, quedanNodos, cuantosNodosHay, copiaBicola, sonBicolasIguales, borraBicola } opc;
	struct BICOLA *bicolaA;
	struct BICOLA *bicolaB;
	int eleccion, nuevoDato;

	// Se inicializan las dos Bicolas poniéndolas a NULL:
	inicializarBicola( &amp;bicolaA );
	inicializarBicola( &amp;bicolaB );

	// Menú de selección:
	do{
		printf( &quot;\n\n&quot; );
		printf( &quot;Indique que desea hacer con los Nodos de la Bicola:\n\n&quot; );
		printf( &quot;   1. Añadir un Nodo por la izquierda\n&quot; );
		printf( &quot;   2. Añadir un Nodo por la derecha\n&quot; );
		printf( &quot;   3. Eliminar el primer Nodo\n&quot; );
		printf( &quot;   4. Eliminar el ultimo Nodo\n&quot; );
		printf( &quot;   5. Mostrar el primer Nodo\n&quot; );
		printf( &quot;   6. Mostrar el ultimo Nodo\n&quot; );
		printf( &quot;   7. Muestra todos los Nodos\n&quot; );
		printf( &quot;   8. Quedan Nodos?\n&quot; );
		printf( &quot;   9. Cuantos Nodos hay?\n&quot; );
		printf( &quot;  10. Copiar BicolaA a una nueva BicolaB\n&quot; );
		printf( &quot;  11. BicolaA es igual que BicolaB?\n&quot; );
		printf( &quot;  12. Borrar la BicolaA\n\n&quot; );
		printf( &quot;   0. Salir del programa.\n&quot; );

		do{
			scanf( &quot;%i&quot;, &amp;eleccion );
		} while( eleccion &lt; 0  &amp;&amp;  eleccion &gt; 12 );
		opc = (enum opciones)(eleccion);

		printf( &quot;\n\n&quot; );

		switch( opc )
		{

			case insertIzq:
				printf( &quot;Introduzca el número entero que contendrá el nuevo Nodo de la Bicola: &quot; );
				scanf( &quot;%i&quot;, &amp;nuevoDato );
				insertIzqBicola( &amp;bicolaA, nuevoDato );
			break;

			case insertDer:
				printf( &quot;Introduzca el número entero que contendrá el nuevo Nodo de la Bicola: &quot; );
				scanf( &quot;%i&quot;, &amp;nuevoDato );
				insertDerBicola( &amp;bicolaA, nuevoDato);
			break;

			case eliminaIzq:
				eliminaIzqBicola( &amp;bicolaA );
			break;

			case eliminaDer:
				eliminaDerBicola( &amp;bicolaA );
			break;

			case impIzq:
				if( tieneNodosLaBicola( &amp;bicolaA ) )
					printf( &quot;El primer Nodo contiene un: %i\n&quot;, bicolaA-&gt;primero-&gt;elemento.num );
				else
					printf(&quot;La Bicola no contiene Nodos&quot;);
			break;

			case impDer:
				if( tieneNodosLaBicola( &amp;bicolaA ) )
					printf( &quot;El ultimo Nodo contiene un: %i\n&quot;, bicolaA-&gt;ultimo-&gt;elemento.num );
				else
					printf(&quot;La Bicola no contiene Nodos&quot;);
			break;

			case impTodos:
				imprimeBicola( &amp;bicolaA );
			break;

			case quedanNodos:
				if( tieneNodosLaBicola( &amp;bicolaA ) )
					printf( &quot;La Bicola contiene Nodos.&quot; );
				else
					printf( &quot;La Bicola esta vacía.&quot; );

			break;

			case cuantosNodosHay:
				printf( &quot;La Bicola contiene %i Nodos.&quot;,  cuantosNodosTieneLaBicola( &amp;bicolaA ) );
			break;

			case copiaBicola:
				copiarLaBicola( &amp;bicolaA, &amp;bicolaB );
			break;

			case sonBicolasIguales:
				if( sonIgualesLasBicolas( &amp;bicolaA, &amp;bicolaB ) )
					printf( &quot;Las Bicolas son idénticas&quot; );
				else
					printf( &quot;Las Bicolas son diferentes&quot; );
			break;

			case borraBicola:
				borraLaBicola( &amp;bicolaA );		// Se borran todos los nodos...
				inicializarBicola( &amp;bicolaA );	// ... y después se inicializa.
			break;

			case salir:
				system(&quot;clear&quot;);
			break;

		};

	} while( opc != salir );

	// Libera la RAM que pudiera quedar sin liberar:
	borraLaBicola( &amp;bicolaA );
	borraLaBicola( &amp;bicolaB );

};
</pre>
<img src="http://feeds.feedburner.com/~r/BlogDeGiltesa/~4/e6G3dZM90Jc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://giltesa.com/2012/02/10/6x06-bicolas-en-lenguaje-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://giltesa.com/2012/02/10/6x06-bicolas-en-lenguaje-c/</feedburner:origLink></item>
		<item>
		<title>6×05: Torres de Hanoi con pilas</title>
		<link>http://feedproxy.google.com/~r/BlogDeGiltesa/~3/RoaJHcwB08A/</link>
		<comments>http://giltesa.com/2012/02/09/6%c3%9705-torres-de-hanoi-con-pilas/#comments</comments>
		<pubDate>Thu, 09 Feb 2012 00:12:51 +0000</pubDate>
		<dc:creator>giltesa</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Programación]]></category>

		<guid isPermaLink="false">http://giltesa.com/?p=8919</guid>
		<description />
			<content:encoded><![CDATA[<div id="attachment_8808" class="wp-caption aligncenter" style="width: 480px"><a href="http://giltesa.com/?p=8807"><img class="size-medium wp-image-8808 " title="hanoi2" src="http://giltesa.com/wp-content/uploads/2012/01/hanoi2-470x89.png" alt="Hanoi con pilas C" width="470" height="89" /></a><p class="wp-caption-text">Mismo ejercicio que el 5×07 pero con pilas.</p></div>
<p><span id="more-8919"></span></p>
<pre class="brush: cpp; title: ; notranslate">
/*
6x05-Hanoi_con_pilas
08/02/2012

Implementa el ejercicio de las torres de Hanoi, utilizando pilas para representar las torres.
*/

#include
#include

struct DISCO
{
	int ancho;	// Contendrá el ancho, en intervalos impares, del disco.
	int altura;	// Contiene el nivel en el que se encuentra ese disco.
};

struct NODO
{
	struct DISCO disc;
	struct NODO *puntero;
};

// FUNCIÓN QUE INTRODUCE UN NUMERO EN UNA PILA:
void insertaDatoEnLaPila( struct NODO **pila, int disco )
{
	/*
	Precondición:
					Se ha de recibir un doble puntero de tipo struct NODO para una pila, y un parámetro de tipo entero.
	Poscondición:
					Se introduce el número recibido en la pila.
	*/

	// Se crea un puntero y se le asigna la dirección a la memoria necesaria para un nodo:
	struct NODO *temp = (struct NODO *) malloc(sizeof(struct NODO));

	// Si la pila no tiene nodos (NULL) la altura del disco que se va a introducir sera siempre de 1. Sin embargo si ya tiene nodos, la altura sera igual a la del nodo inferior +1.
	if( *pila == NULL )
		temp-&gt;disc.altura = 1;
	else
		temp-&gt;disc.altura = (*pila)-&gt;disc.altura + 1;

	temp-&gt;disc.ancho = disco;
	temp-&gt;puntero	 = *pila;
	*pila			 = temp;

};

// FUNCIÓN QUE EXTRAE EL PRIMER ELEMENTO DE LA PILA Y BORRA EL NODO VACIO:
int extraeDatoDeLaPila( struct NODO **pila, int *numNivel )
{
	/*
	Precondición:
					Se ha de recibir un doble puntero de tipo struct NODO para una pila.
					También un parámetro por referencia de tipo entero en el cual se guardara la altura en el que se encuentra el disco.
						Ese dato en el caso de la función mueveDisco() no sirve para nada, sin embargo es necesario desde la función imprimeTablero();
						Si la pila resultase NULL se devolverá, o mejor dicho, no se modificara el valor original que debería de ser 0.
	Poscondición:
					Se devuelve el primer parámetro de tipo entero almacenado en la pila, si esta vacía devuelve un 0.
					Devuelve por referencia la altura del disco.
	*/

	struct NODO *siguiente;
	int resp;

	if( *pila == NULL )
		resp = 0;
	else
	{
		// Se copia el ancho a la variable que va a ser retornada por la función:
		*numNivel	= (*pila)-&gt;disc.altura;
		resp		= (*pila)-&gt;disc.ancho;

		// Se elimina el primer Nodo (el vaciado):
		siguiente = (*pila)-&gt;puntero;
		free(*pila);
		*pila = siguiente;
	};

	return resp;
};

// FUNCIÓN QUE CREA UNA COPIA IDENTICA DE UNA PILA:
void creaUnaCopiaDePila( struct NODO **pila, struct NODO **pilaCopia )
{
	/*
	Precondición:
					Se reciben dos dobles punteros a dos pilas de tipo struct NODO, la primera ha de tener nodos y la segunda ha de estar vacía.
	Poscondición:
					Se realiza una copia exacta de toda la pila de la original a la copia.
	*/

	struct NODO *siguiente = *pila;
	struct NODO *antBusq;
	struct NODO *sigBusq;
	struct NODO *temp;

	// Mientras el puntero siguiente siga apuntando a otro Nodo...
	while( siguiente != NULL )
	{

		temp = (struct NODO *) malloc(sizeof(struct NODO));

		// Si la pila nueva no tiene ningún Nodo se introduce al principio:
		if( *pilaCopia == NULL )
		{
			temp-&gt;disc 		= siguiente-&gt;disc;
			temp-&gt;puntero	= NULL;
			*pilaCopia		= temp;
		}
		  // En caso contrario se introducen los siguientes Nodos siempre al final de la pila (que se esta tratando como una cola).
		else
		{
			sigBusq = *pilaCopia;

			// Se busca el ultimo Nodo:
			while( sigBusq != NULL )
			{
				antBusq = sigBusq;
				sigBusq = sigBusq-&gt;puntero;
			};

			temp-&gt;disc 		 = siguiente-&gt;disc;
			temp-&gt;puntero	 = NULL;
			antBusq-&gt;puntero = temp;
		};

		// Se avanza una posición en el puntero de la lista original:
		siguiente = siguiente-&gt;puntero;
	};

};

// FUNCIÓN QUE BORRA UNA LISTA ENTERA:
void borrarLista( struct NODO **lista )
{
	/*
	Precondición:
					Se ha de recibir un puntero de tipo struct NODO al primer nodo de la lista.
	Poscondición:
					Se borran todos los nodos de esa lista hasta llegar a NULL.
	*/

	struct NODO *actual, *siguiente;
	actual = *lista;

	while(actual != NULL)
	{
		siguiente = actual-&gt;puntero;
		free(actual);
		actual = siguiente;
	};

	*lista = NULL;

};

// FUNCIÓN QUE IMPRIME EL TABLERO DE HANOI:
void imprimeTablero( struct NODO **pilaO, struct NODO **pilaA, struct NODO **pilaD, int totDiscos, int tamDiscGrande )
{
	/*
	Precondición:
					pilaO, pilaA, pilaD			Se reciben tres dobles punteros a tres pilas de tipo struct NODO.
					totDiscos					Parámetro de tipo entero que indica el numero de discos totales para calcular el tiempo de pausa por cada impresión.
					tamDiscGrande				Parámetro de tipo entero que indica el tamaño del disco mas grande, se emplea para calcular los espacios a imprimir a ambos lados del disco.
*/

	// Se crean tres punteros temporales:
	struct NODO *pilaOc=NULL, *pilaAc=NULL, *pilaDc=NULL;

	int discoO, discoA, discoD, nivelO=0, nivelA=0, nivelD=0;
	int espO, espA, espD;
	int numNivel;
	int i;

	// Se usan los punteros temporales para que apunten a unas nuevas pilas idénticas a las originales:
	creaUnaCopiaDePila( pilaO, &amp;pilaOc );
	creaUnaCopiaDePila( pilaA, &amp;pilaAc );
	creaUnaCopiaDePila( pilaD, &amp;pilaDc );

	// Se obtiene el numero de disco por return y la altura del disco por referencia...
	discoO = extraeDatoDeLaPila(&amp;pilaOc, &amp;nivelO);
	discoA = extraeDatoDeLaPila(&amp;pilaAc, &amp;nivelA);
	discoD = extraeDatoDeLaPila(&amp;pilaDc, &amp;nivelD);

	// Se recorren todos los niveles de las pilas aunque estén vacíos:
	for( numNivel=totDiscos; numNivel &gt; 0; numNivel-- )
	{

		// Se calculan los espacios necesarios para el disco a imprimir en la altura correspondiente:
		espO = ( tamDiscGrande - discoO )/2;
		espA = ( tamDiscGrande - discoA )/2;
		espD = ( tamDiscGrande - discoD )/2;

		// Si la altura en la que se esta, la marca el for, es la misma que la altura del disco que se ha leído... se imprime, en caso contrario se imprimen tantos espacios como ancho tenga el disco mas grande.
		// Torre 1 o Origen:
		if( nivelO == numNivel )
		{
			// Espacios a la izquierda
			for( i=0; i &lt; espO; i++ )
				printf( &quot; &quot; );
			// Imprime los comodines
			for( i=0; i &lt; discoO; i++ )
				printf( &quot;*&quot; );
			// Espacios a la derecha
			for( i=0; i &lt; espO; i++ )
				printf( &quot; &quot; );

			// Se recoge el siguiente disco:
			discoO = extraeDatoDeLaPila(&amp;pilaOc, &amp;nivelO);
		}
		else
		{
			// Se rellena todo de espacios ya que no hay disco en ese altura:
			for( i=0; i &lt; tamDiscGrande; i++ )
				printf( &quot; &quot; );
		};

		printf( &quot;  &quot; );

		// Torre 1 o Auxiliar:
		if( nivelA == numNivel )
		{
			// Espacios a la izquierda
			for( i=0; i &lt; espA; i++ )
				printf( &quot; &quot; );
			// Imprime los comodines
			for( i=0; i &lt; discoA; i++ )
				printf( &quot;*&quot; );
			// Espacios a la derecha
			for( i=0; i &lt; espA; i++ )
				printf( &quot; &quot; );

			discoA = extraeDatoDeLaPila(&amp;pilaAc, &amp;nivelA);
		}
		else
		{
			// Se rellena todo de espacios ya que no hay disco en ese altura:
			for( i=0; i &lt; tamDiscGrande; i++ )
				printf( &quot; &quot; );
		};

		printf( &quot;  &quot; );

		// Torre 1 o Destino:
		if( nivelD == numNivel )
		{
			// Espacios a la izquierda
			for( i=0; i &lt; espD; i++ )
				printf( &quot; &quot; );
			// Imprime los comodines
			for( i=0; i &lt; discoD; i++ )
				printf( &quot;*&quot; );
			// Espacios a la derecha
			for( i=0; i &lt; espD; i++ )
				printf( &quot; &quot; );

			discoD = extraeDatoDeLaPila(&amp;pilaDc, &amp;nivelD);
		}
		else
		{
			// Se rellena todo de espacios ya que no hay disco en ese altura:
			for( i=0; i &lt; tamDiscGrande; i++ )
				printf( &quot; &quot; );
		};

		// Se hace un salto de linea para representar la próxima altura:
		printf( &quot;\n&quot; );

	};

};

// FUNCIÓN QUE MUEVE UN DISCO DE UNA PILA A OTRA:
void mueveDisco( struct NODO **pilaO, struct NODO **pilaA, struct NODO **pilaD, int totDiscos, int tamDiscGrande, char listOrigen, char listDestino )
{
	/*
	Precondición:
					pilaO, pilaA, pilaD			Se reciben tres dobles punteros a tres pilas de tipo struct NODO.
					totDiscos					Parámetro de tipo entero que indica el numero de discos totales para calcular el tiempo de pausa por cada impresión.
					tamDiscGrande				Parámetro de tipo entero que indica el tamaño del disco mas grande, se emplea para calcular los espacios a imprimir a ambos lados del disco.
					listOrigen, listDestino		Dos enteros que indican el origen del disco y su destino.
	Poscondición:
					Se mueve el disco de Origen a Destino y se llama a la función que imprime el tablero.
	*/

	int paraNada=0;

	if( listOrigen == 'O' )
	{
		if( listDestino == 'A' )
			insertaDatoEnLaPila( pilaA, extraeDatoDeLaPila(pilaO, &amp;paraNada) );

		else if( listDestino == 'D' )
			insertaDatoEnLaPila( pilaD, extraeDatoDeLaPila(pilaO, &amp;paraNada) );
	}
	else if( listOrigen == 'A' )
	{
		if( listDestino == 'O' )
			insertaDatoEnLaPila( pilaO, extraeDatoDeLaPila(pilaA, &amp;paraNada) );

		else if( listDestino == 'D' )
			insertaDatoEnLaPila( pilaD, extraeDatoDeLaPila(pilaA, &amp;paraNada) );
	}
	else if( listOrigen == 'D' )
	{
		if( listDestino == 'O' )
			insertaDatoEnLaPila( pilaO, extraeDatoDeLaPila(pilaD, &amp;paraNada) );

		else if( listDestino == 'A' )
			insertaDatoEnLaPila( pilaA, extraeDatoDeLaPila(pilaD, &amp;paraNada) );
	};

	// Se imprime el tablero:
	imprimeTablero( pilaO, pilaA, pilaD, totDiscos, tamDiscGrande );
};

// FUNCIÓN DE HANOI MEDIANTE RECURSIVIDAD:
void hanoi( struct NODO **pilaO, struct NODO **pilaA, struct NODO **pilaD, int nDiscos, int totDiscos, int tamDiscGrande, char O, char A, char D )
{
/*
Precondición:
				pilaO, pilaA, pilaD		Se reciben tres dobles punteros a tres pilas de tipo struct NODO.
				nDiscos					Parámetro de tipo entero que indica el numero de discos usados en cada recursividad.
				totDiscos				Parámetro de tipo entero que indica el numero de discos totales para calcular el tiempo de pausa por cada impresión.
				tamDiscGrande			Parámetro de tipo entero que indica el tamaño del disco mas grande, se emplea para calcular los espacios a imprimir a ambos lados del disco.
				O, A, D					Tres enteros que indican la fila desde donde se ha de coger el disco y a donde se ha de traspasar. La primera vez que se llama a hanoi tienen los valores de: 0 ,1 y 2 respectivamente.
Poscondición:
				Se llama recursivamente a hanoi hasta resolver el tablero.
*/

	if( nDiscos == 1 )
	{
		// Se borra la pantalla, se mueve el disco/imprime y se hace una pausa que varia dependiendo del numero de discos:
		system(&quot;clear&quot;);
		mueveDisco( pilaO, pilaA, pilaD, totDiscos, tamDiscGrande, O, D );
		if(totDiscos15) system(&quot;sleep 0.02&quot;);
	}
	else
	{
		hanoi( pilaO, pilaA, pilaD, nDiscos-1, totDiscos, tamDiscGrande, O, D, A );

		system(&quot;clear&quot;);
		mueveDisco( pilaO, pilaA, pilaD, totDiscos, tamDiscGrande, O, D );
		if(totDiscos15) system(&quot;sleep 0.02&quot;);

		hanoi( pilaO, pilaA, pilaD, nDiscos-1, totDiscos, tamDiscGrande, A, O, D );
	};

};

main()
{

	struct NODO *pilaO=NULL, *pilaA=NULL, *pilaD=NULL;
	int nDiscos, disco, tamDiscGrande, i;

	printf( &quot;Indique el número de discos: &quot; );
	scanf( &quot;%i&quot;, &amp;nDiscos );

	// Se halla el disco más grande (de tamaño impar) que se usara:
	disco = 1 + 2*(nDiscos - 1);
	tamDiscGrande = disco; // Se hace una copia para poder conservar el numero.

	for( i=0; i &lt; nDiscos; i++ )
	{
		// Se introduce el disco que corresponda y se resta 2 para la siguiente iteración:
		insertaDatoEnLaPila( &amp;pilaO, disco );
		disco -= 2;
	};

	// Se imprime el tablero:
	system(&quot;clear&quot;);
	imprimeTablero( &amp;pilaO, &amp;pilaA, &amp;pilaD, nDiscos, tamDiscGrande );
	system(&quot;sleep 1&quot;);

	// Se llama a hanoi para comenzar &quot;la partida&quot;:
	hanoi( &amp;pilaO, &amp;pilaA, &amp;pilaD, nDiscos, nDiscos, tamDiscGrande, 'O', 'A', 'D' );

	// Se borran la pila de destino que es la única que tiene nodos:
	borrarLista( &amp;pilaD );

};
</pre>
<img src="http://feeds.feedburner.com/~r/BlogDeGiltesa/~4/RoaJHcwB08A" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://giltesa.com/2012/02/09/6%c3%9705-torres-de-hanoi-con-pilas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://giltesa.com/2012/02/09/6%c3%9705-torres-de-hanoi-con-pilas/</feedburner:origLink></item>
		<item>
		<title>6×04: Notación polaca inversa con pilas</title>
		<link>http://feedproxy.google.com/~r/BlogDeGiltesa/~3/yeki9CFo2L4/</link>
		<comments>http://giltesa.com/2012/02/07/6x04-notacion-polaca-inversa-con-pilas/#comments</comments>
		<pubDate>Tue, 07 Feb 2012 22:13:40 +0000</pubDate>
		<dc:creator>giltesa</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Programación]]></category>

		<guid isPermaLink="false">http://giltesa.com/?p=8911</guid>
		<description />
			<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://giltesa.com/wp-content/uploads/2012/02/Notacion-polaca-inversa.png"><img class="alignnone size-medium wp-image-8912" title="Notacion polaca inversa" src="http://giltesa.com/wp-content/uploads/2012/02/Notacion-polaca-inversa-470x251.png" alt="Notación polaca inversa en C con Pilas" width="470" height="251" /></a></p>
<p><span id="more-8911"></span></p>
<pre class="brush: cpp; title: ; notranslate">
/*
6x04-Notacion_postfija_con_pilas
07/02/2012

Escribe un programa que lea de teclado una expresión en notación postfija y la evalúe, mostrando su resultado por pantalla. Para ello implementa y utiliza una pila.
*/
/*
NOTAS:

Infija		a+b		(((5+9)*2)+(6*5))	= 58
Prefija 	+ab
Postfija	ab+		5 9+2*6 5*+			= 58

Si el termino es un valor, introducirlo en una pila
Sí el término es un operador:

Sacar dos operandos de la pila
Aplicar el operador
Meter el resultado en la pila

	Paso a paso:
	5
	9 5
	14
	2 14
	28
	6 28
	5 6 28
	30 28
	58
*/

#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#include &lt;stdlib.h&gt;

struct NODO
{
	int valor;
	struct NODO *puntero;
};

// FUNCIÓN QUE PASA UNA CADENA CON NUMEROS A ENTERO:
int pasaCadenaAEntero( char cadena[20] )
{
	/*
	Precondición:
					Se ha de recibir una cadena de caracteres terminada en fin de linea que contenga solo un numero entero de máximo 20 dígitos.
	Poscondición:
					Se pasa esa cadena al tipo entero y se devuelve el valor.
	*/

	int longCadena=strlen(cadena), numero=0, i;

	for( i=0; i&lt;longCadena; i++ )
	{
		numero *= 10;
		numero += cadena[i]-48;
	};

	return numero;
};

// FUNCIÓN QUE INTRODUCE UN NUMERO EN UNA PILA:
void insertaDatoEnLaPila( struct NODO **pila, int num )
{
	/*
	Precondición:
					Se ha de recibir un doble puntero de tipo struct NODO para una pila, y un parámetro de tipo entero.
	Poscondición:
					Se introduce el numero recibido en la pila.
	*/

	struct NODO *temp = (struct NODO *) malloc(sizeof(struct NODO));

	temp-&gt;valor		= num;
	temp-&gt;puntero	= *pila;
	*pila			= temp;

};

// FUNCIÓN QUE EXTRAE EL PRIMER ELEMENTO DE LA PILA Y BORRA EL NODO VACIO:
int extraeDatoDeLaPila( struct NODO **pila )
{
	/*
	Precondición:
					Se ha de recibir un doble puntero de tipo struct NODO para una pila.
	Poscondición:
					Se devuelve el primer parámetro de tipo entero almacenado en la pila.
	*/

	struct NODO *siguiente;
	int resp;

	// Se copia el valor a la variable que va a ser retornada por la función:
	resp = (*pila)-&gt;valor;

	// Se elimina el primer Nodo (el vaciado):
	siguiente = (*pila)-&gt;puntero;
	free(*pila);
	*pila = siguiente;

	return resp;
};

// FUNCIÓN QUE LIBERA LA MEMORIA USADA POR UNA LISTA:
void listaLiberaRam( struct NODO **lista )
{
	/*
	Precondición:
					Se ha de recibir un puntero de tipo struct NODO al primer nodo de la lista.
	Poscondición:
					Se borran todos los nodos de esa lista hasta llegar a NULL.
	*/

	struct NODO *actual, *siguiente;
	actual = *lista;

	while(actual != NULL)
	{
		siguiente = actual-&gt;puntero;
		free(actual);
		actual = siguiente;
	};

	*lista = NULL;

};

main()
{

	struct NODO *pila;
	char cad[20];
	int val1, val2;

	printf( &quot;Introduce una expresión en notación postfija para hallar el resultado.\n&quot; );
	printf( &quot;Introduzca un valor o operador y pulse intro para introducir el siguiente, escriba = para calcular el resultado\n&quot; );
	printf( &quot;  Ejemplo:\n\n   5\n   9\n   +\n   2\n   *\n   6\n   5\n   *\n   +\n\n&quot; );
	printf( &quot;Indique la expresion:\n\n&quot; );

	do{

		// Se lee un valor o operador:
		scanf( &quot;%s&quot;, cad );

		// Dependiendo de lo leido se hace una operacion u otra:
		switch( cad[0] )
		{
			case '+':
				// En el caso de la: '+', '-', '*' y '/', se sacan dos valores de la pila, se opera con ellos según el operador elegido y se guarda el resultado en la pila.

				val1 = extraeDatoDeLaPila( &amp;pila );
				val2 = extraeDatoDeLaPila( &amp;pila );
				insertaDatoEnLaPila( &amp;pila, val1 + val2 );
			break;

			case '-':
				val1 = extraeDatoDeLaPila( &amp;pila );
				val2 = extraeDatoDeLaPila( &amp;pila );
				insertaDatoEnLaPila( &amp;pila, val1 - val2 );
			break;

			case '*':
				val1 = extraeDatoDeLaPila( &amp;pila );
				val2 = extraeDatoDeLaPila( &amp;pila );
				insertaDatoEnLaPila( &amp;pila, val1 * val2 );
			break;

			case '/':
				val1 = extraeDatoDeLaPila( &amp;pila );
				val2 = extraeDatoDeLaPila( &amp;pila );
				insertaDatoEnLaPila( &amp;pila, val1 / val2 );
			break;

			case '=':
				// Se imprime por pantalla el ultimo y único elemento de la pila.
				printf( &quot;\nEl resultado es: %i\n\n&quot;, extraeDatoDeLaPila( &amp;pila ) /*pila-&gt;valor*/ );
			break;

			default:
				// Se introduce un nuevo dato en la pila:
				insertaDatoEnLaPila( &amp;pila, pasaCadenaAEntero(cad) );
			break;
		};

	} while( cad[0] != '=' );

};
</pre>
<img src="http://feeds.feedburner.com/~r/BlogDeGiltesa/~4/yeki9CFo2L4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://giltesa.com/2012/02/07/6x04-notacion-polaca-inversa-con-pilas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://giltesa.com/2012/02/07/6x04-notacion-polaca-inversa-con-pilas/</feedburner:origLink></item>
		<item>
		<title>6×02: Lista desordenada</title>
		<link>http://feedproxy.google.com/~r/BlogDeGiltesa/~3/Ctlf9fjYQSA/</link>
		<comments>http://giltesa.com/2012/02/05/6x02-lista-desordenadas/#comments</comments>
		<pubDate>Sun, 05 Feb 2012 17:14:44 +0000</pubDate>
		<dc:creator>giltesa</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Programación]]></category>

		<guid isPermaLink="false">http://giltesa.com/?p=8893</guid>
		<description />
			<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://giltesa.com/wp-content/uploads/2012/02/6x02-Lista_enlazadas_desordenadass.jpg"><img class="alignnone size-medium wp-image-8894" title="6x02-Lista_enlazadas_desordenadass" src="http://giltesa.com/wp-content/uploads/2012/02/6x02-Lista_enlazadas_desordenadass-223x270.jpg" alt="" width="223" height="270" /></a></p>
<p><span id="more-8893"></span></p>
<pre class="brush: cpp; title: ; notranslate">
/*
6x02-Lista_enlazadas_desordenadas
01/02/2012

Repite el ejercicio anterior usando una lista (no ordenada), que implemente una operación de ordenarLista.
Se almacenarán los números desordenados en la lista y luego se aplicará la operación implementada.
*/

// Estructuras de datos:
struct SORTEO
{
	int numero;		// Numero de boleto
	int cuantia;	// Importe del premio
};
struct NODO
{
	struct SORTEO elemento;	// Información contenida en cada nodo de la lista.
	struct NODO *puntero;	// Puntero al siguiente nodo de la lista.
};

// Constantes:
#define NUMEROS 10

// Librerias:
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;time.h&gt;
//#include &quot;listas.h&quot;

// FUNCION QUE INSERTA NODOS AL FINAL DE LA LISTA:
void listaInsertAlFinal( struct NODO **lista, struct SORTEO *cupon )
{
	/*
	Precondición:
					Se ha de recibir un puntero de tipo struct NODO al primer nodo de la lista. Este podrá valer NULL la primera vez o la dirección de memoria que corresponda.
					  El puntero además es un &quot;doble puntero&quot; ya que es necesario poder modificarlo.
					También se ha de recibir un puntero a una estructura de tipo SORTEO con la información a insertar en la lista.
	Poscondición:
					Se inserta la información contenida en &quot;cupon&quot; en un Nodo nuevo perteneciente a &quot;lista&quot;, la inserción se realiza siempre al final de la lista.
	*/

	struct NODO *temp 		= (struct NODO *)malloc(sizeof(struct NODO));	// Se define un puntero temporal de tipo NODO que apunta a la memoria solicitada al sistema.
	struct NODO *anterior 	= NULL;											// Se crea otro puntero de tipo NODO, este apuntando a NULL
	struct NODO *siguiente 	= *lista;										// Y un tercer puntero de tipo NODO que apunta al primer nodo de la lista.

	// En la primera inserción &quot;lista&quot; no apuntara a nada, por lo que se inserta el primer nodo y se hace que &quot;lista&quot; apunte a él.
	if( *lista == NULL )
	{
		temp-&gt;elemento	= *cupon;
		temp-&gt;puntero	= NULL;

		*lista = temp;
	}
	  // Cuando la lista ya tenga un elemento...
	else
	{

		// Se recorren todos los Nodos de la lista hasta llegar al final.
		while( siguiente != NULL )
		{
			anterior = siguiente;
			siguiente = siguiente-&gt;puntero;
		};

		// Se agrega el nuevo Nodo al final de la lista.
		if( siguiente == NULL )
		{
			temp-&gt;elemento	= *cupon;	// Se guarda la estructura de datos (cupon) en la estructura del nuevo Nodo.
			temp-&gt;puntero	= NULL;		// Como la inserción es al final de la lista el puntero del Nodo no a puntara a ningún otro Nodo.

			anterior-&gt;puntero = temp;	// Se modifica el puntero del Nodo anterior para que apunte al nuevo Nodo.
		};

	};

};

// FUNCION QUE ORDENA LOS NODOS DE UNA LISTA DE FORMA ASCENDENTE:
void listaOrdenarAscendente( struct NODO **lista )
{
	/*
	Precondición:
					Se ha de recibir un puntero de tipo struct NODO al primer nodo de la lista. Este podrá valer NULL la primera vez o la dirección de memoria que corresponda.
	Poscondición:
					La función se encarga de ordenar de forma ascendente cada Nodo de la lista según el numero de cupón que contengan dichos nodos.
					El método usado para ordenar los nodos es mediante el método de la burbuja, de modo que se necesitan dos bucles,
					  el segundo se encarga de ordenar el nodoA y el nodoB en la primera iteración, después el nodoB y el nodoC en la segunda iteración, luego el nodoC y el nodoD, etc.
					  de modo que se van arrastrando los números pequeños hacia el principio de la lista, una vez recorrida entera el segundo bucle se encarga de recorrerla de nuevo, así tantas veces como nodos tiene la lista.
					Finalmente la lista queda ordenada completamente.
					Esquema gráfico: http://goo.gl/I54uV
	*/

	struct NODO *p_nodoAnt2_nodoAnt1	= NULL;							// Es(sera) el puntero del puntero que apunta al nodoA (es necesario para modificar el puntero que apunta a A)
	struct NODO *p_nodoAnt1_nodoA		= *lista;						// Es el puntero que apunta al nodoA
	struct NODO *p_nodoA_nodoB			= p_nodoAnt1_nodoA-&gt;puntero;	// Es el puntero del nodoA y apunta al nodoB
	struct NODO *p_nodoB_sig			= p_nodoA_nodoB-&gt;puntero;		// Es el puntero del nodoB que apunta al siguiente nodo.

	struct NODO *temporal				= NULL;							// Puntero temporal de intercambio.
	struct NODO *iteracion				= *lista;						// Es el puntero que va avanzando en la lista en cada iteración del primer bucle, es necesario para saber cuando detener el bucle.

	int salirBucle1; // Variables &quot;booleanas&quot; para indicar cuando se ha de salir de los bucles.
	int salirBucle2;

	// Si la lista contiene Nodos se ordenan:
	if( *lista != NULL )
	{

		salirBucle1 = 0;

		// La lista se ha de recorrer tantas veces como Nodos tenga:
		while( !salirBucle1 )
		{

			// Si &quot;iteracion&quot; es NULL se cambia el estado de &quot;salirBucle1&quot; para salir del primer bucle una vez se haya hecho una ultima vez el bucle 2.
			// En caso contrario iteración avanza un nodo de la lista.
			if( iteracion == NULL )
				salirBucle1 = 1;
			else
				iteracion = iteracion-&gt;puntero;

			salirBucle2 = 0;

			// Cada vez que se recorre la lista se ordenan dos Nodos:
			while( !salirBucle2 )
			{

				// Si se va a ordenar el primer Nodo con el segundo...
				if( p_nodoAnt1_nodoA == *lista )
				{
					// Si el NodoA es mayor que el nodoB, se cambian de orden:
					if( p_nodoAnt1_nodoA-&gt;elemento.numero   &gt;   p_nodoA_nodoB-&gt;elemento.numero )
					{
						// Se intercambia el NodoA con el NodoB:
						*lista						= p_nodoA_nodoB;
						temporal					= p_nodoB_sig;
						p_nodoA_nodoB-&gt;puntero		= p_nodoAnt1_nodoA;
						p_nodoAnt1_nodoA-&gt;puntero	= temporal;

						// Se actualizan los punteros para que cada uno apunte segun su nombre correspondiente:
						p_nodoAnt1_nodoA			= *lista;
						p_nodoA_nodoB				= p_nodoAnt1_nodoA-&gt;puntero;
						p_nodoB_sig					= p_nodoA_nodoB-&gt;puntero;
					};

				}
				  // Si se van a ordenar nodos intermedios de la lista...
				else if( p_nodoB_sig != NULL )
				{

					if( p_nodoAnt1_nodoA-&gt;elemento.numero   &gt;   p_nodoA_nodoB-&gt;elemento.numero )
					{
						// Se intercambian los punteros:
						p_nodoAnt2_nodoAnt1-&gt;puntero	= p_nodoA_nodoB;
						temporal						= p_nodoB_sig;
						p_nodoA_nodoB-&gt;puntero			= p_nodoAnt1_nodoA;
						p_nodoAnt1_nodoA-&gt;puntero		= temporal;

						// Se actualizan los punteros para que cada uno apunte segun su nombre correspondiente:
						p_nodoAnt1_nodoA				= p_nodoAnt2_nodoAnt1-&gt;puntero;
						p_nodoA_nodoB					= p_nodoAnt1_nodoA-&gt;puntero;
						p_nodoB_sig						= p_nodoA_nodoB-&gt;puntero;
					};

				}
				  // Si se va a ordenar el penultimo y ultimo nodo...
				else if( p_nodoB_sig == NULL )
				{

					if( p_nodoAnt1_nodoA-&gt;elemento.numero   &gt;   p_nodoA_nodoB-&gt;elemento.numero )
					{
						// Se intercambian los punteros:
						p_nodoAnt2_nodoAnt1-&gt;puntero	= p_nodoA_nodoB;
						p_nodoA_nodoB-&gt;puntero			= p_nodoAnt1_nodoA;
						p_nodoAnt1_nodoA-&gt;puntero		= NULL;

						// Se actualizan los punteros para que cada uno apunte segun su nombre correspondiente:
						p_nodoAnt1_nodoA				= p_nodoAnt2_nodoAnt1-&gt;puntero;
						p_nodoA_nodoB					= p_nodoAnt1_nodoA-&gt;puntero;
						p_nodoB_sig						= NULL;
					}

					// Ya se han ordenado los dos últimos Nodos y ahora se para el bucle2:
					salirBucle2 = 1;

				};

				// Mientras el nodoB siga apuntando a otro nodo, se modifican todos los punteros para que apunten al siguiente nodo:
				if( p_nodoB_sig != NULL )
				{
					p_nodoAnt2_nodoAnt1	= p_nodoAnt1_nodoA;
					p_nodoAnt1_nodoA	= p_nodoAnt1_nodoA-&gt;puntero;
					p_nodoA_nodoB		= p_nodoA_nodoB-&gt;puntero;
					p_nodoB_sig			= p_nodoB_sig-&gt;puntero;
				};

			}; // Fin primer bucle

			// Al parar el segundo bucle hay que resetear los punteros al valor original.
			p_nodoAnt2_nodoAnt1		= NULL;
			p_nodoAnt1_nodoA		= *lista;
			p_nodoA_nodoB			= p_nodoAnt1_nodoA-&gt;puntero;
			p_nodoB_sig				= p_nodoA_nodoB-&gt;puntero;

		}; // Fin segundo bucle

	};// Fin del if

}; // fin de la funcion

// FUNCION QUE LIBERA LA MEMORIA USADA POR UNA LISTA:
void listaLiberaRam( struct NODO **lista )
{
	/*
	Precondición:
					Se ha de recibir un puntero de tipo struct NODO al primer nodo de la lista.
	Poscondición:
					Se borran todos los nodos de esa lista hasta llegar a NULL.
	*/

	struct NODO *actual, *siguiente;
	actual = *lista;

	while(actual != NULL)
	{
		siguiente = actual-&gt;puntero;
		free(actual);
		actual = siguiente;
	};

	*lista = NULL;

};

// Función que genera números aleatorios con sus premios aleatorios respectivos y los guarda en &quot;fichero.dat&quot;:
void generaDat()
{
	/*
	Poscondición:
					La función se encarga de generar estructuras con números aleatorios que son guardados en un fichero secuencial.
					  El numero de estructuras a guardar viene dado por la constante NUMEROS.
	*/

	FILE *ficheroBin = fopen( &quot;sorteo.dat&quot;, &quot;w&quot; );
	struct SORTEO cupon;
	int i;

	srand((unsigned int)time(NULL));

	for( i=0; i &lt; NUMEROS; i++ )
	{
		cupon.numero  = rand()%100000;
		cupon.cuantia = rand()%1000;

		fwrite( &amp;cupon, sizeof(struct SORTEO), 1, ficheroBin );
	};

	fclose( ficheroBin );
};

// Funciona que pasa el contenido de &quot;fichero.dat&quot; a &quot;fichero.txt&quot;:
void mostrarDat()
{
	/*
	Poscondición:
					Se pasa todo el contenido del fichero secuencial a un fichero de texto.
	*/

	FILE *ficheroBin = fopen( &quot;sorteo.dat&quot;, &quot;r&quot; );
	FILE *ficheroText;
	struct SORTEO cupon;

	if( ficheroBin == NULL )
		printf( &quot;Genere rimero el fichero \&quot;sorteo.dat\&quot;\n&quot; );
	else
	{
		ficheroText = fopen( &quot;sorteo.txt&quot;, &quot;w&quot; );

		fread( &amp;cupon, sizeof(struct SORTEO), 1, ficheroBin );

		while( !feof(ficheroBin) )
		{
			fprintf( ficheroText, &quot;%i\t%i\n&quot;, cupon.numero, cupon.cuantia );
			fread( &amp;cupon, sizeof(struct SORTEO), 1, ficheroBin );
		};

		fclose( ficheroBin );
		fclose( ficheroText );

	};

};

main()
{
	struct NODO *lista = NULL;
	struct NODO *temp;
	struct SORTEO cupon;
	FILE *fichOriginal, *fichOrdenDat, *fichOrdenTxt;
	char opcion;

	printf( &quot;Eliga una opcion:\n&quot; );
	printf( &quot;1. Ordenar el fichero \&quot;sorteo.dat\&quot; mediante listas\n&quot; );
	printf( &quot;2. Generar \&quot;sorteo.dat\&quot;\n&quot; );
	printf( &quot;3. Pasar fichero \&quot;sorteo.dat\&quot; a \&quot;sorteo.txt\&quot;\n&quot; );
	do{
		scanf( &quot;%c&quot;, &amp;opcion );
	} while( opcion &lt; '1'  ||  opcion &gt; '3' );

	if( opcion == '2' )
		generaDat();
	else if( opcion == '3' )
		mostrarDat();
	else if( opcion == '1' )
	{

		fichOriginal = fopen(&quot;sorteo.dat&quot;, &quot;r&quot;);

		// Se comprueba que el fichero secuencial con el que se ha de trabajar exista:
		if( fichOriginal == NULL )
			printf( &quot;Necesita el fichero \&quot;sorteo.dat\&quot;, generelo primero\n&quot; );
		else
		{

			// Se recorre cada estructura del fichero secuencial y se inserta en una estructura de datos dinamica de tipo lista:
			fread( &amp;cupon, sizeof(struct SORTEO), 1, fichOriginal );

			while( !feof(fichOriginal) )
			{
				listaInsertAlFinal( &amp;lista, &amp;cupon );						// Se crea un nuevo nodo para el estruct leido y se inserta en la lista.
				fread( &amp;cupon, sizeof(struct SORTEO), 1, fichOriginal );	// Se lee la siguiente estructura de datos a guardar en la lista.
			};
			fclose(fichOriginal);

			// Se ordena la lista:
			listaOrdenarAscendente( &amp;lista );

			// Se imprime el contenido de la lista en unos ficheros:
			fichOrdenDat = fopen(&quot;sorteoOrdenado.dat&quot;, &quot;w&quot;);
			fichOrdenTxt = fopen(&quot;sorteoOrdenado.txt&quot;, &quot;w&quot;);
			temp = lista;

			while( temp != NULL )
			{
				fwrite( &amp;temp, sizeof(struct SORTEO), 1, fichOrdenDat );
				fprintf( fichOrdenTxt, &quot;%i\t%i\n&quot;, temp-&gt;elemento.numero, temp-&gt;elemento.cuantia );
				temp = temp-&gt;puntero;
			};
			fclose(fichOrdenDat);
			fclose(fichOrdenTxt);

			// Ya se ha finalizado el programa, pero antes de terminar del todo hay que liberar toda la memoria RAM usada:
			listaLiberaRam( &amp;lista );

		};

	};

	printf( &quot;  Operación finalizada.\n&quot; );

};
</pre>
<img src="http://feeds.feedburner.com/~r/BlogDeGiltesa/~4/Ctlf9fjYQSA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://giltesa.com/2012/02/05/6x02-lista-desordenadas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://giltesa.com/2012/02/05/6x02-lista-desordenadas/</feedburner:origLink></item>
		<item>
		<title>Obtén 5 GiB de almacenamiento extra en Dropbox</title>
		<link>http://feedproxy.google.com/~r/BlogDeGiltesa/~3/KpSi6iW4QEY/</link>
		<comments>http://giltesa.com/2012/02/03/obtener-5gib-de-almacenamiento-extra-en-dropbox/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 22:38:31 +0000</pubDate>
		<dc:creator>giltesa</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Almacenamiento]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://giltesa.com/?p=8850</guid>
		<description><![CDATA[Ya hable una vez sobre este fantástico servicio en una entrada sobre aplicaciones interesantes para Android. En resumen es un servicio que te permite almacenar información de todo tipo en la nube, y no solo eso, si no que además todo ese contenido se sincroniza con una carpeta del ordenador, de forma que todo lo [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><img class="wp-image-8854 aligncenter" title="dropbox-logo-256x" src="http://giltesa.com/wp-content/uploads/2012/02/dropbox-logo-256x.jpg" alt="" width="150" height="150" /></p>
<p>Ya hable una vez sobre este fantástico servicio en una entrada sobre aplicaciones <a title="Aplicaciones interesantes para Android" href="http://giltesa.com/2010/09/03/aplicaciones-interesantes-para-android/">interesantes para Android</a>.</p>
<p>En resumen es un servicio que te permite almacenar información de todo tipo en la nube, y no solo eso, si no que además todo ese contenido se sincroniza con una carpeta del ordenador, de forma que todo lo que tengas en esa carpeta este también en el servidor de Dropbox. Y si eso no fuera poco, también se puede tener esa carpeta en varios ordenadores o móviles, de forma que todos ellos tengan el mismo contenido.</p>
<p>Ejemplo practico: Haces unas fotos con el móvil y quieres pasarlas al pc. Solo hay que copiarlas al directorio de Dropbox y se sincronizan en todos los ordenadores.<br />
O, tienes una carpeta compartida con un amigo y quieres pasarle las fotografías del ultimo fin de semana esquiando en la montaña&#8230; solo hay que copiarlas a la carpeta y automáticamente se le descargan a él.</p>
<p>Pues bien, por defecto te dan 2GiB de espacio de almacenamiento, y adicionalmente 250MiB por cada amigo que se registra desde tu <a title="Dropbox" href="http://url.giltesa.com/dropbox" target="_blank">referido</a> (250MiB para ambos) pudiendo llegar hasta un total de 10GiB.</p>
<p>Sin embargo, cada cierto tiempo reparten más espacio mediante juegos o &#8220;pruebas&#8221;. En este caso dan <strong>5GiB extra</strong> por utilizar la nueva versión beta del programa y la nueva funcionalidad de <strong>sincronización de fotos</strong> y vídeos de cámaras/móviles.</p>
<p><span id="more-8850"></span></p>
<p>Para conseguirlo es bien sencillo:</p>
<ul>
<li>Primero <a title="Experimental Forum Build - 1.3.12" href="http://forums.dropbox.com/topic.php?id=52900" target="_blank">descargamos la versión Beta</a> y la instalamos.</li>
<li>Después conectamos un móvil o cámara o cualquier otro dispositivo que tenga en su raíz el directorio DCIM y dentro de él fotos y/o videos.</li>
<li>Al conectarlo se abrira, en windows, la ventana de <a href="http://giltesa.com/wp-content/uploads/2012/02/dropbox-importar.png">reproducción automática</a> <span style="color: #ff0000;">*</span>, tendremos que seleccionar la primera opcion: Sincronizar con Dropbox.</li>
<li>De este modo se copiara todo el contenido del directorio DCIM a Dropbox y por cada 500MiB subidos nos darán 500MiB de espacio extra hasta un máximo de 5GiB.</li>
</ul>
<p style="padding-left: 30px;"><span style="color: #ff0000;">*</span> Si por algún motivo no funcionase la reproducción automática, típico, tendremos que editar una clave del registro para arreglarlo, en concreto la llamada:  <em>NoDriveTypeAutoRun</em> que se encuentra en: <em>hkey_local_machine/software/microsoft/windows/currentversion/policies/explorer</em>. Deberemos de cambiar el valor que aparezca por: <em>5B </em>(en hexadecimal o 91 en decimal)<em><br />
</em>Para abrir el editor del registro tendremos que pulsar las teclas <em>windows+r</em> y escribir <em>regedit</em></p>
<p style="padding-left: 30px;">Es decir:  <em>windows+r</em>  -&gt;  <em>regedit</em>  -&gt;   <em>hkey_local_machine/software/microsoft/windows/currentversion/policies/explorer</em>  -&gt;   <em>NoDriveTypeAutoRun</em>  -&gt;   <em>5B</em></p>
<p>Y eso es todo, en una media hora podremos aumentar el espacio de almacenamiento para guardar todos nuestros documentos de clase, fotos, vídeos, etc. Pero hay que darse prisa, ya que esto es una promoción y en unos días lo quitaran!!</p>
<img src="http://feeds.feedburner.com/~r/BlogDeGiltesa/~4/KpSi6iW4QEY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://giltesa.com/2012/02/03/obtener-5gib-de-almacenamiento-extra-en-dropbox/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://giltesa.com/2012/02/03/obtener-5gib-de-almacenamiento-extra-en-dropbox/</feedburner:origLink></item>
		<item>
		<title>6×01: Lista ordenada</title>
		<link>http://feedproxy.google.com/~r/BlogDeGiltesa/~3/HhYym6Eplc0/</link>
		<comments>http://giltesa.com/2012/02/01/6x01-lista-ordenada/#comments</comments>
		<pubDate>Wed, 01 Feb 2012 14:44:12 +0000</pubDate>
		<dc:creator>giltesa</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Programación]]></category>

		<guid isPermaLink="false">http://giltesa.com/?p=8835</guid>
		<description />
			<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://giltesa.com/wp-content/uploads/2012/01/listas-1.jpg"><img class="alignnone size-medium wp-image-8839" title="listas-1" src="http://giltesa.com/wp-content/uploads/2012/01/listas-1-247x270.jpg" alt="" width="247" height="270" /></a></p>
<p><span id="more-8835"></span></p>
<pre class="brush: cpp; title: ; notranslate">
/*
6x01-Listas_ordenadas_al_instante
25/01/2012

Implementa una lista ordenada con las operaciones vistas en clase. Utilízala para almacenar en ella todos los datos que hay en un fichero (por ejemplo, uno de resultados de un sorteo de lotería de Navidad, que tenga números premiados y premio que corresponde, que esté desordenado, y usando como criterio de orden los números), y posteriormente guarda la lista ordenada
en otro fichero.
*/

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;time.h&gt;

#define NUMEROS 10

struct SORTEO
{
	int numero;		// Numero de boleto
	int cuantia;	// Importe del premio
};

struct NODO
{
	struct SORTEO elemento;	// Información contenida en cada nodo de la lista.
	struct NODO *puntero;	// Puntero al siguiente nodo de la lista.
};

void insertarEnListaOrdenada( struct NODO **lista, struct SORTEO *cupon )
{
	/*
	Precondición:
					Se ha de recibir un puntero de tipo struct NODO al primer nodo de la lista. Este podrá valer NULL la primera vez o la dirección de memoria que corresponda.
					  El puntero además es un &quot;doble puntero&quot; ya que es necesario poder modificarlo.
					También se ha de recibir un puntero a una estructura de tipo SORTEO con la información a insertar en la lista.
	Poscondición:
					Se inserta la información contenida en &quot;cupon&quot; en un Nodo nuevo perteneciente a &quot;lista&quot;, la inserción se realiza con orden ascendente según el &quot;numero&quot; de la estructura &quot;cupon&quot;
	*/

	struct NODO *temp 		= (struct NODO *)malloc(sizeof(struct NODO));	// Se define un puntero temporal de tipo NODO que apunta a la memoria solicitada al sistema.
	struct NODO *anterior 	= NULL;											// Se crea otro puntero de tipo NODO, este apuntando a NULL
	struct NODO *siguiente 	= *lista;										// Y un tercer puntero de tipo NODO que apunta al primer nodo de la lista.

	// En la primera inserción &quot;lista&quot; no apuntara a nada, por lo que se inserta el primer nodo y se hace que &quot;lista&quot; apunte a él.
	if( *lista == NULL )
	{
		temp-&gt;elemento	= *cupon;
		temp-&gt;puntero	= NULL;

		*lista = temp;
	}
	  // Cuando la lista ya tenga al un elemento...
	else
	{

		// Se han de recorrer todos los nodos para comprobar que el orden es correcto, es decir, con orden ascendente:
		//  De modo que se compara el numero del nodo al cual apunta &quot;siguiente&quot; con el numero del cupón que se quiere insertar.
		//  Si se cumple la condición, se guarda en &quot;anterior&quot; el puntero actual, y en &quot;siguiente&quot; se guarda el puntero del nodo siguiente de la lista
		//  En caso de que termine la lista &quot;siguiente&quot; valdrá NULL y &quot;anterior&quot; valdrá N-1 (el ultimo puntero valido)
		while(  siguiente != NULL   &amp;&amp;   siguiente-&gt;elemento.numero &lt; cupon-&gt;numero )
		{
			anterior = siguiente;
			siguiente = siguiente-&gt;puntero;
		};

		// Si durante la lectura de la lista se llega al final sin encontrar un numero mayor, entonces se inserta el nuevo nodo al final de la lista.
		if( siguiente == NULL )
		{
			temp-&gt;elemento	= *cupon;	// Se guarda la estructura de datos (cupón) en la estructura del nuevo Nodo.
			temp-&gt;puntero	= NULL;		// Como la inserción es al final de la lista el puntero del Nodo no a puntara a ningún otro Nodo.

			anterior-&gt;puntero = temp;	// Se modifica el puntero del Nodo anterior para que apunte al nuevo Nodo.
		}
		  // En cambio, si recorriendo la lista se encuentra un numero mayor, se deberá insertar el nuevo nodo antes.
		else
		{
			// Ahora pueden darse dos casos:

			// Que el nodo a insertar sea el primero de todos, por lo tanto hay que modificar el puntero de &quot;lista&quot; para que apunte al nuevo Nodo:
			if( *lista == siguiente )
			{
				temp-&gt;elemento	= *cupon;
				temp-&gt;puntero	= siguiente;

				*lista = temp;
			}
			  // O que este entre dos nodos, por lo que se modificara el puntero del anterior Nodo para que apunte al nuevo Nodo:
			else
			{
				temp-&gt;elemento = *cupon;
				temp-&gt;puntero = siguiente;

				anterior-&gt;puntero = temp;
			};

		};

	};

};

void borrarLista( struct NODO **lista )
{
	/*
	Precondición:
					Se ha de recibir un puntero de tipo struct NODO al primer nodo de la lista.
	Poscondición:
					Se borran todos los nodos de esa lista hasta llegar a NULL.
	*/

	struct NODO *actual, *siguiente;
	actual = *lista;

	while(actual != NULL)
	{
		siguiente = actual-&gt;puntero;
		free(actual);
		actual = siguiente;
	};

	*lista = NULL;

};

// Función que genera números aleatorios con sus premios aleatorios respectivos y los guarda en &quot;fichero.dat&quot;:
void generaDat()
{
	/*
	Poscondición:
					La función se encarga de generar estructuras con números aleatorios que son guardados en un fichero secuencial.
					  El número de estructuras a guardar viene dado por la constante NUMEROS.
	*/

	FILE *ficheroBin = fopen( &quot;sorteo.dat&quot;, &quot;w&quot; );
	struct SORTEO cupon;
	int i;

	srand((unsigned int)time(NULL));

	for( i=0; i &lt; NUMEROS; i++ )
	{
		cupon.numero  = rand()%100000;
		cupon.cuantia = rand()%1000;

		fwrite( &amp;cupon, sizeof(struct SORTEO), 1, ficheroBin );
	};

	fclose( ficheroBin );
};

// Funcion que pasa el contenido de &quot;fichero.dat&quot; a &quot;fichero.txt&quot;:
void mostrarDat()
{
	/*
	Poscondición:
					Se pasa todo el contenido del fichero secuencial a un fichero de texto.
	*/

	FILE *ficheroBin = fopen( &quot;sorteo.dat&quot;, &quot;r&quot; );
	FILE *ficheroText;
	struct SORTEO cupon;

	if( ficheroBin == NULL )
		printf( &quot;Genere rimero el fichero \&quot;sorteo.dat\&quot;\n&quot; );
	else
	{
		ficheroText = fopen( &quot;sorteo.txt&quot;, &quot;w&quot; );

		fread( &amp;cupon, sizeof(struct SORTEO), 1, ficheroBin );

		while( !feof(ficheroBin) )
		{
			fprintf( ficheroText, &quot;%i\t%i\n&quot;, cupon.numero, cupon.cuantia );
			fread( &amp;cupon, sizeof(struct SORTEO), 1, ficheroBin );
		};

		fclose( ficheroBin );
		fclose( ficheroText );

	};

};

main()
{
	struct NODO *lista = NULL;
	struct NODO *temp;
	struct SORTEO cupon;
	FILE *fichOriginal, *fichOrdenDat, *fichOrdenTxt;
	char opcion;

	printf( &quot;Elija una opción:\n&quot; );
	printf( &quot;1. Ordenar el fichero \&quot;sorteo.dat\&quot; mediante listas\n&quot; );
	printf( &quot;2. Generar \&quot;sorteo.dat\&quot;\n&quot; );
	printf( &quot;3. Pasar fichero \&quot;sorteo.dat\&quot; a \&quot;sorteo.txt\&quot;\n&quot; );
	do{
		scanf( &quot;%c&quot;, &amp;opcion );
	} while( opcion &lt; '1'  ||  opcion &gt; '3' );

	if( opcion == '2' )
		generaDat();
	else if( opcion == '3' )
		mostrarDat();
	else if( opcion == '1' )
	{

		fichOriginal = fopen(&quot;sorteo.dat&quot;, &quot;r&quot;);

		// Se comprueba que el fichero secuencial con el que se ha de trabajar exista:
		if( fichOriginal == NULL )
			printf( &quot;Necesita el fichero \&quot;sorteo.dat\&quot;, genérelo primero\n&quot; );
		else
		{

			// Se recorre todo el fichero, en cada iteración se lee una estructura y se pasa a la función que la guarda en un nuevo Nodo de la lista.
			  // Se lee la primera estructura del fichero y se guarda en la estructura &quot;temporal&quot; de tipo &quot;SORTEO&quot;
			  fread( &amp;cupon, sizeof(struct SORTEO), 1, fichOriginal );

			while( !feof(fichOriginal) )
			{
				insertarEnListaOrdenada( &amp;lista, &amp;cupon );					// Se crea un nuevo nodo para el estruct leido y se inserta en la lista.
				fread( &amp;cupon, sizeof(struct SORTEO), 1, fichOriginal );	// Se lee la siguiente estructura de datos a guardar en la lista.
			};
			fclose(fichOriginal);

			// Hasta aquí ya se ha leído todo el fichero y se han introducido sus estructuras en cada Nodo de la lista de forma ordenada, ahora hay que pasarlos al fichero de destino.

			fichOrdenDat = fopen(&quot;sorteoOrdenado.dat&quot;, &quot;w&quot;);
			fichOrdenTxt = fopen(&quot;sorteoOrdenado.txt&quot;, &quot;w&quot;);
			temp = lista;

			while( temp != NULL )
			{
				fwrite( &amp;temp, sizeof(struct SORTEO), 1, fichOrdenDat );
				fprintf( fichOrdenTxt, &quot;%i\t%i\n&quot;, temp-&gt;elemento.numero, temp-&gt;elemento.cuantia );
				temp = temp-&gt;puntero;
			};
			fclose(fichOrdenDat);

			// Ya se ha finalizado el programa, pero antes de terminar del todo hay que liberar toda la memoria RAM usada:
			borrarLista( &amp;lista );

		};

	};

	printf( &quot;  Operación finalizada.\n&quot; );

};</pre>
<img src="http://feeds.feedburner.com/~r/BlogDeGiltesa/~4/HhYym6Eplc0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://giltesa.com/2012/02/01/6x01-lista-ordenada/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://giltesa.com/2012/02/01/6x01-lista-ordenada/</feedburner:origLink></item>
	</channel>
</rss>

