<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>el blog de giltesa &#187; Informatica</title>
	<atom:link href="http://giltesa.com/category/informatica/feed/" rel="self" type="application/rss+xml" />
	<link>http://giltesa.com</link>
	<description></description>
	<lastBuildDate>Mon, 06 Feb 2012 22:38:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>6&#215;02: Lista desordenada</title>
		<link>http://giltesa.com/2012/02/05/6x02-lista-desordenadas/</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><![CDATA[]]></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>
]]></content:encoded>
			<wfw:commentRss>http://giltesa.com/2012/02/05/6x02-lista-desordenadas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>6&#215;01: Lista ordenada</title>
		<link>http://giltesa.com/2012/02/01/6x01-lista-ordenada/</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><![CDATA[]]></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>
]]></content:encoded>
			<wfw:commentRss>http://giltesa.com/2012/02/01/6x01-lista-ordenada/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>5&#215;07: Torres de Hanoi parte2</title>
		<link>http://giltesa.com/2012/01/25/5x07-torres-de-hanoi-parte2/</link>
		<comments>http://giltesa.com/2012/01/25/5x07-torres-de-hanoi-parte2/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 23:02:57 +0000</pubDate>
		<dc:creator>giltesa</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://giltesa.com/?p=8807</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://giltesa.com/wp-content/uploads/2012/01/hanoi2.png"><img class="alignnone size-medium wp-image-8808" title="hanoi2" src="http://giltesa.com/wp-content/uploads/2012/01/hanoi2-470x89.png" alt="" width="470" height="89" /></a></p>
<p style="text-align: center;"><iframe width="560" height="315" src="http://www.youtube.com/embed/xXTle8JYhys" frameborder="0" allowfullscreen></iframe></p>
<p><span id="more-8807"></span></p>
<pre class="brush: cpp; title: ; notranslate">
/*
5x07-Torres_de_Hanoi_parte_2
24/01/2012

Escribe un programa (se recomienda que sea recursivo) que dé solución al problema de las torres de Hanoi.
El enunciado es el siguiente: Se dispone de una torre formada por varios discos de diferentes diámetros denominada torre O (origen), donde cada disco es de diámetro inferior a todos los que están por debajo. Se dispone de otras dos torres para dejar discos, una denominada torre A (auxiliar) y otra torre D (destino).
El problema consiste en pasar todos los discos de la torre O a la torre D respetando dos normas muy simples:

Los discos se pasan de una torre a otra de uno en uno.
Nunca un disco de mayor diámetro puede estar sobre otro de menor diámetro.
Se preguntará al inicio del programa por el tamaño de la torre O (entendiendo que tendrá el número de discos indicados, con algún límite preestablecido).
Las torres A y D estarán inicialmente vacías.
Se debe ofrecer la solución que da el programa a este problema paso a paso, mostrando el resultado de una forma gráfica. El inicio podría ser algo así:

			*
		   ***
		  *****
		 *******
		*********
	   ===========		==========		==========
			O				A				D
*/
/*
	Formula para calcular movimientos mínimos necesarios:
	m = 2^n -1

http://www.rodoval.com/heureka/hanoi/

*/

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

void imprime( int *tab, int fil, int col, int ultNum )
{
	/*
	Precondición:
					*tab	Puntero a una matriz de tipo entero.
					fil		Entero que indica el numero de filas de la matriz.
					col		Entero que indica el numero de columnas de la matriz.
					disc	Parámetro de tipo entero que indica el numero de discos usados.
					ultNum	Entero que indica el numero que esta usando el disco mas grande.
*/

	int f, c;
	int i, esp;

	for( c=col-1; c &gt;= 0; c-- )
	{
		for( f=0; f &lt; fil; f++ )
		{
			esp = ( ultNum - tab[col*f+c] )/2;

			// Espacios a la izquierda
			for( i=0; i &lt; esp; i++ )
				printf( &quot; &quot; );

			// Imprime los comodines
			for( i=0; i &lt; tab[col*f+c]; i++ )
				printf( &quot;*&quot; );

			// Espacios a la derecha
			for( i=0; i &lt; esp; i++ )
				printf( &quot; &quot; );

			printf( &quot;\t&quot; );
		};

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

};

void mueveDisco( int *tab, int fil, int col, int ultNum, int filOrig, int filDest )
{
	/*
	Precondición:
					*tab	Puntero a una matriz de tipo entero.
					fil		Entero que indica el numero de filas de la matriz.
					col		Entero que indica el numero de columnas de la matriz.
					disc	Parámetro de tipo entero que indica el numero de discos usados.
					ultNum	Entero que indica el numero que esta usando el disco mas grande.
					filOrig	Entero que indica el numero de fila de la matriz en la cual hay que coger el numero/disco
					filDest	Entero que indica el numero de fila de la matriz en la cual hay que dejar el numero/disco.
	Poscondición:
					Se mueve el disco y se llama a la función que imprime el tablero.
	*/

	int cO=col-1, cD=col-1;

	// Se busca el disco que se encuentre mas arriba y por lo tanto el mas pequeño de la fila de origen.
	while( cO &gt;= 0  &amp;&amp;  tab[col*filOrig+cO] == 0 )
	{
		cO--;
	};
	if( cO &lt; 0 )
		cO = 0;

	// Ahora se calcula cual es la posición libre mas arriba de la fila de destino
	while( cD &gt;= 0  &amp;&amp;  tab[col*filDest+cD] == 0 )
	{
		cD--;
	};

	// Se mueve el disco de la fila de origen a la de destino:
	tab[col*filDest+cD+1] = tab[col*filOrig+cO];
	tab[col*filOrig+cO] = 0;

	// Se imprime el tablero:
	imprime( tab, fil, col, ultNum );
};

void hanoi( int *tab, int fil, int col, int disc, int ultNum, int O, int A, int D )
{
/*
Precondición:
				*tab	Puntero a una matriz de tipo entero.
				fil		Entero que indica el numero de filas de la matriz.
				col		Entero que indica el numero de columnas de la matriz.
				disc	Parámetro de tipo entero que indica el numero de discos usados.
				ultNum	Entero que indica el numero que esta usando el disco mas grande.
				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( disc==1 )
	{
		// Se borra la pantalla, se imprime la tabla y se hace una pausa que varia dependiendo del numero de discos:
		system(&quot;clear&quot;);
		mueveDisco( tab, fil, col, ultNum, O, D );
		if(col&lt;=5) system(&quot;sleep 0.8&quot;); else if(col&lt;=10) system(&quot;sleep 0.3&quot;); else if(col&lt;=15) system(&quot;sleep 0.06&quot;); else if(col&gt;15) system(&quot;sleep 0.02&quot;);
	}
	else
	{
		hanoi( tab, fil, col, disc-1, ultNum, O, D, A );

		system(&quot;clear&quot;);
		mueveDisco( tab, fil, col, ultNum, O, D );
		if(col&lt;=5) system(&quot;sleep 0.8&quot;); else if(col&lt;=10) system(&quot;sleep 0.3&quot;); else if(col&lt;=15) system(&quot;sleep 0.06&quot;); else if(col&gt;15) system(&quot;sleep 0.02&quot;);

		hanoi( tab, fil, col, disc-1, ultNum, A, O, D );
	};

};

main()
{
	int fil=3, col, *tablero = NULL;
	int f, c, disc=1, ultNum;

	printf( &quot;Indique el numero de discos: &quot; );
	scanf( &quot;%i&quot;, &amp;col );

	tablero = (int *)malloc( sizeof(int)*fil*col );

	// Resetea las torres poniendo &quot;los discos&quot; en una de ellas y 0 en el resto.
	for( f=0; f &lt; fil; f++ )
		for( c=col-1; c &gt;= 0; c-- )
			if( f==0 )
			{
				tablero[col*f+c] = disc;
				disc+=2;
			}
			else
				tablero[col*f+c] = 0;

	ultNum = disc;

	// Se imprime el tablero antes de iniciar ningún movimiento:
	system(&quot;clear&quot;);
	imprime( tablero, fil, col, ultNum );
	system(&quot;sleep 1&quot;);

	// Se llama a hanoi para comenzar &quot;la partida&quot;:
	hanoi( tablero, fil, col, col, ultNum, 0, 1, 2 );
};
</pre>
]]></content:encoded>
			<wfw:commentRss>http://giltesa.com/2012/01/25/5x07-torres-de-hanoi-parte2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>5&#215;06: Torres de Hanoi parte1</title>
		<link>http://giltesa.com/2012/01/24/5x06-torres-de-hanoi-parte1/</link>
		<comments>http://giltesa.com/2012/01/24/5x06-torres-de-hanoi-parte1/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 22:19:53 +0000</pubDate>
		<dc:creator>giltesa</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Programación]]></category>

		<guid isPermaLink="false">http://giltesa.com/?p=8800</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://giltesa.com/wp-content/uploads/2012/01/hanoi1.png"><img class="alignnone size-medium wp-image-8804" title="hanoi1" src="http://giltesa.com/wp-content/uploads/2012/01/hanoi1-245x270.png" alt="" width="245" height="270" /></a></p>
<p><span id="more-8800"></span></p>
<pre class="brush: cpp; title: ; notranslate">
/*
5x06-Torres_de_Hanoi_parte_1
18/01/2012

Haz una versión del ejercicio siguiente (también recursiva) que simplemente vaya dando por pantalla las instrucciones necesarias para dar solución al problema de tamaño n.
Es decir, se trata de una versión del ejercicio siguiente que no muestra nada gráficamente, sino que implemente dice qué disco mover de qué torre a qué torre, para que un manipulador pueda ir haciendo esos movimientos sobre una maqueta y solucione correctamente el problema.
*/

#include &lt;stdio.h&gt;

void hanoi( int disc, int *cont, char O, char A, char D )
{
	/*
	Precondición:
					Se ha de recibir un parámetro de tipo entero que indica el numero de discos que se están usando.
					Un puntero a un parámetro de tipo entero que almacena el numero de movimientos.
					Y tres parámetros de tipo carácter cuyo valor va cambiando de orden por cada recursividad.
	*/

	if( disc == 1 )
	{
		if( *cont &lt; 10 ) printf(&quot;  &quot;); else if( *cont &lt; 100 ) printf(&quot; &quot;); printf(&quot;%i:  %c -&gt; %c\n&quot;, *cont, O, D );
		(*cont)++;
	}
	else
	{
		hanoi( disc-1, cont, O, D, A );

		if( *cont &lt; 10 ) printf(&quot;  &quot;); else if( *cont &lt; 100 ) printf(&quot; &quot;); printf(&quot;%i:  %c -&gt; %c\n&quot;, *cont, O, D );
		(*cont)++;

		hanoi( disc-1, cont, A, O, D );
	};

};

main()
{
	int disc, cont=1;;

	printf( &quot;Indique el numero de discos: &quot; );
	scanf( &quot;%i&quot;, &amp;disc );

	hanoi( disc, &amp;cont, 'O', 'A', 'D' );
};
</pre>
]]></content:encoded>
			<wfw:commentRss>http://giltesa.com/2012/01/24/5x06-torres-de-hanoi-parte1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>5&#215;05: Fibonacci</title>
		<link>http://giltesa.com/2012/01/18/5x05-fibonacci/</link>
		<comments>http://giltesa.com/2012/01/18/5x05-fibonacci/#comments</comments>
		<pubDate>Wed, 18 Jan 2012 19:23:40 +0000</pubDate>
		<dc:creator>giltesa</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Programación]]></category>

		<guid isPermaLink="false">http://giltesa.com/?p=8674</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://giltesa.com/wp-content/uploads/2012/01/5x05-Fibonacci.png"><img class="alignnone size-full wp-image-8675" title="5x05-Fibonacci" src="http://giltesa.com/wp-content/uploads/2012/01/5x05-Fibonacci.png" alt="" width="264" height="51" /></a></p>
<p><span id="more-8674"></span></p>
<pre class="brush: cpp; title: ; notranslate">
/*
5x05-Fibonacci
18/01/2012

Escribe un programa recursivo que calcule la función de Fibonacci de un número introducido por teclado. El valor de la función de Fibonacci se obtiene de la siguiente manera:

	1. Fibonacci(0)=1
	2. Fibonacci(1)=1
	3. Fibonacci(n)=Fibonacci(n-1)+Fibonacci(n-2)
*/

#include &lt;stdio.h&gt;

unsigned long long int fibonacci(unsigned long long int num)
{
	/*
	Precondición:
					Se ha de recibir un parámetro de tipo &quot;unsigned long long int&quot;
	Poscondición:
					Se devuelve otro &quot;unsigned long long int&quot;
	*/

	if( num == 1  || num == 0 )
		return num;
	else
		return fibonacci(num-1) + fibonacci(num-2);
};

main()
{
	unsigned long long int num;

	printf( &quot;Introduzca un numero: &quot; );
	scanf( &quot;%lld&quot;, &amp;num );

	printf( &quot;\n   El Fibonacci de %lld es: %lld\n&quot;, num, fibonacci(num) );
};
</pre>
]]></content:encoded>
			<wfw:commentRss>http://giltesa.com/2012/01/18/5x05-fibonacci/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>5&#215;04: Indica si el vector esta ordenado mediante recursividad</title>
		<link>http://giltesa.com/2012/01/18/5x04-indica-si-el-vector-esta-ordenado-mediante-recursividad/</link>
		<comments>http://giltesa.com/2012/01/18/5x04-indica-si-el-vector-esta-ordenado-mediante-recursividad/#comments</comments>
		<pubDate>Wed, 18 Jan 2012 18:39:22 +0000</pubDate>
		<dc:creator>giltesa</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Programación]]></category>

		<guid isPermaLink="false">http://giltesa.com/?p=8670</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://giltesa.com/wp-content/uploads/2012/01/5x04-El_vector_esta_ordenado_o_no_con_recursividad.png"><img class="alignnone size-full wp-image-8671" title="5x04-El_vector_esta_ordenado_o_no_con_recursividad" src="http://giltesa.com/wp-content/uploads/2012/01/5x04-El_vector_esta_ordenado_o_no_con_recursividad.png" alt="" width="399" height="216" /></a></p>
<p><span id="more-8670"></span></p>
<pre class="brush: cpp; title: ; notranslate">
/*
5x04-El_vector_esta_ordenado_o_no_con_recursividad
18/01/2012

Escribe un programa recursivo que determine si un vector de enteros está ordenado de menor a mayor o no.
*/

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

int ordenadoONo( int *numeros, int tam, int pos )
{
	/*
	Precondición:
					Se ha de recibir el puntero de un vector de enteros de tamaño &quot;tam&quot;
					Cambien otro parámetro de tipo entero que indica el tamaño del vector.
					Y otro entero que indica la posición hasta la que se ha leído en el vector.
	Poscondición:
					Se devuelve true si numeros[pos] es menor que numeros[pos+1], false en caso contrario.
	*/

	int respuesta = 1;

	if( pos &lt; tam )
	{
		if( numeros[pos] &lt;= numeros[pos+1] )
			return ordenadoONo(numeros, tam, pos+1);
		else
		{
			printf( &quot;\n   El numero %i no es menor que %i&quot;, numeros[pos], numeros[pos+1] );
			return 0;
		};

	}
	else
		return respuesta;

};

main()
{

	int *numeros = NULL;
	int tam, i;

	printf( &quot;Indique el numero de enteros a introducir: &quot; );
	scanf( &quot;%i&quot;, &amp;tam );

	numeros = malloc(sizeof(int)*tam);

	printf( &quot; Introduzca los números enteros:\n&quot; );
	for( i=0; i &lt; tam; i++ )
	{
		printf( &quot;  %i: &quot;, i+1 );
		scanf( &quot;%i&quot;, &amp;numeros[i] );
	};

	if( ordenadoONo( numeros, tam-1, 0) )
		printf( &quot;\n   Los números estaban ordenados\n&quot; );
	else
		printf( &quot;\n   Los números no siguen un orden\n&quot; );

};
</pre>
]]></content:encoded>
			<wfw:commentRss>http://giltesa.com/2012/01/18/5x04-indica-si-el-vector-esta-ordenado-mediante-recursividad/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

