Double Linked List based in C++

CK1820 
Created at Sep 08, 2007 09:06:34 
62   0   0   0  

Below is the double linked list example that based on console.

Specially this application use macro by define function provided by ANSI C.
It's just like inline function that C++ provides.

#include <stdio.h>
#include <stdlib.h>
/* Constants */
#define EXIT_OK
/* Macros */
#define CHOICE(answer)
printf("Choice: ");
scanf("%i", &answer);
struct nodo
{
	int 	nclient; 	/* primary key of the "record" */
	char    name[40];       /* name */
	float	total;          /* how much this client owes us */
	struct	nodo * next;    /* pointer to the next struct */
	struct	nodo * prev;	/* pointer to the previous struct */
};
/* Functions */
void AddClient 		(struct nodo ** list);
void Exit       	(struct nodo ** list);
void SeeAll		(struct nodo ** list);
void OneByOne		(struct nodo ** list);
void Search		(struct nodo ** list);
void Delete		(struct nodo ** list);
void FreeAll		(struct nodo ** list);
void Flush2File		(struct nodo ** list);
void ReadFile		(struct nodo ** list);
void Money		(struct nodo ** list);
void CalcTotal		(struct nodo ** list);
void HighestTotal       (struct nodo ** list);
void LowestTotal	(struct nodo ** list);
void Average		(struct nodo ** list);
void AddBegin		(struct nodo ** list, struct nodo * add);
void AddEnd		(struct nodo ** list, struct nodo * add);
void AddBetween		(struct nodo ** list, struct nodo * add);
int NumberExists	(struct nodo ** list, int number);
void ShowData		(struct nodo * data);
int  StrCompare		(char * s1, char * s2);
void ErrorOpeningFile 	(void);
int main (void)
{
	struct nodo * list = NULL; 	/* list will be a pointer to the first
					node of the linked list */
	int	choice;
	do
	{
		clrscr();
		textcolor (4);
		cputs ("\nDouble Linked Lists - Nicolas Raitman");
		textcolor (7);
		puts("\n\n0 - Exit");
		puts("1 - New Item");
		puts("2 - See All Items in the Linked List");
		puts("3 - Show Items One by One");
		puts("4 - Search Item");
		puts("5 - Delete Item");
		puts("6 - Delete Entire List");
		puts("7 - Money");
		puts("8 - Flush Linked List to File");
		puts("9 - Read File and Create Linked List");
		CHOICE (choice);
		switch (choice)
		{
			case 0:	Exit(&list); break;
			case 1: AddClient(&list); break;
			case 2: SeeAll(&list); break;
			case 3: OneByOne(&list); break;
			case 4: Search(&list); break;
			case 5: Delete(&list); break;
			case 6: FreeAll(&list); break;
			case 7: Money (&list); break;
			case 8: Flush2File(&list); break;
			case 9: ReadFile(&list); break;
			default: break;
		}
	} while (choice != 0);
	return EXIT_OK;
}
void ReadFile (struct nodo ** list)
{
	/* creates a new linked list from data in 'dlist.bin'
	deleting all repeated entries, filtering by nodo->nclient */
	struct nodo * aux = NULL;
	FILE	* fp;
	int	sizenodo = sizeof(struct nodo);
	/* first we make sure to free all the memory used by the list
	since we are going to create a new one */
	FreeAll (list);
	*list = NULL;
	if ((fp = fopen("dlist.bin", "rb")) == NULL)
	{
		ErrorOpeningFile();
		return;
	}
	/* we read the first record on the file and we add it to the
	beginning of the list */
	aux = (struct nodo *) malloc (sizenodo);
	fread(aux, sizenodo, 1, fp);
	AddBegin (list, aux);
	/* we do the loop while we are not in the end of file */
	while (!feof(fp))
	{
		aux = (struct nodo *) malloc (sizeof(struct nodo));
		if(fread(aux, sizenodo, 1, fp))
		{
			/* if nclient does not exist in our list then
			we add the node to the list */
			if (!NumberExists(list, aux->nclient))
				AddBetween(list, aux);
			else
				/* since I did not add the item to the list
				I free the memory used by it */
				free (aux);
		}
	}
	free (aux);
	printf("Data was read from 'dlist.bin' and Double Linked List was created.
Press any key to continue...");
	getch();
}
void ErrorOpeningFile (void)
{
	/* it shows a message stating that the file could not be opened*/
	printf("
Error while opening file.");
	getch();
}
int NumberExists (struct nodo ** list, int number)
{
	/* searches for number in all act->nclient, and if it finds
	any match it return 1, else it returns 0 */
	struct nodo * act = NULL;
	act = *list;
	while (act)
	{
		if (act->nclient == number)
			return 1;
		act = act->next;
	}
	/* if we reach this point then no match was found */
	return 0;
}
void Flush2File (struct nodo ** list)
{
	/* flushes all the items in the linked list into a file */
	struct nodo * act = NULL;
	FILE	* fp;
	int	choice;
	if (! *list)
		return;
	act = *list;
	printf("

1 - New File");
	printf("
2 - Append Data");
	CHOICE (choice);
	if (choice == 1)
	{
		/* we delete all the contents of the file and open it to write */
		if ((fp = fopen("dlist.bin", "wb")) == NULL)
		{
			ErrorOpeningFile();
			return;
		}
	}
	else
	{
		/* we open the file to append data */
		if ((fp = fopen("dlist.bin", "ab")) == NULL)
		{
			ErrorOpeningFile();
			return;
		}
	}
	/* while we have a node pointing to a differnt address than NULL... */
	while (act)
	{
		/* now we write into the file each node of the linked list */
		fwrite (act, sizeof (struct nodo), 1, fp);
		act = act->next;
	}
	fclose(fp);
	printf("

Data was flushed into 'dlist.bin'. Press any key to continue...");
	getch();
}
void Money (struct nodo ** list)
{
	/* this function shows a loop and it calls different functions to
	perform several calculation with the field "total" in the struct
	Not a big deal, just to show basic arithmetic calculations. Most
	of the functions that are called are described by its name */
	int choice;
	if (! *list)
	{
		printf("
Empty List. No calculations can be performed.");
		getch();
		return;
	}
	do
	{
		puts("
0 - Exit");
		puts("1 - Calculate Total");
		puts("2 - Highest Total");
		puts("3 - Lowest Total");
		puts("4 - Average Total");
		CHOICE(choice);
		switch (choice)
		{
			case 0: break;
			case 1: CalcTotal(list); break;
			case 2: HighestTotal(list); break;
			case 3: LowestTotal(list); break;
			case 4: Average(list); break;
			default: break;
		}
	} while (choice != 0);
}
void Average (struct nodo ** list)
{
	/* calculates the average of all the act->total for each node in the
	linked list */
	struct nodo * act = NULL;
	int	count = 0;
	float	total = 0, average;
	act = *list;
	while (act)
	{
		total += act->total;
		count++;
		act = act->next;
	}
	average = total / count;
	printf ("
Average = %.2f
", average);
}
void LowestTotal (struct nodo ** list)
{
	struct nodo * act = NULL, * lowest = NULL;
	act = *list;
	lowest = *list;
	while (act)
	{
		if (act->total < lowest->total)
			lowest = act;
		act = act->next;
	}
	ShowData(lowest);
}
void HighestTotal (struct nodo ** list)
{
	struct nodo * act = NULL, * highest = NULL;
	act = *list;
	highest = *list;
	while (act)
	{
		if (act->total > highest->total)
			highest = act;
		act = act->next;
	}
	ShowData(highest);
}
void CalcTotal (struct nodo ** list)
{
	struct nodo * act = NULL;
	float	total = 0;
	act = *list;
	while (act)
	{
		total += act->total;
		act = act->next;
	}
	printf("
Total = %.2f
", total);
}
void Delete (struct nodo ** list)
{
	/* this functions deletes a specific node in the list */
	struct nodo * act = NULL, * prev = NULL;
	int number;
	if (! *list)
		return;
	act = *list;
	prev = *list;
	printf("
Number to Delete: "); scanf("%i", &number);
	while (act)
	{
		/* we search until we find a the same number */
		if (act->nclient == number)
		{
			if (prev == act)
			{
				/* if trying to delete the first node
				then the beginning of the list will be the
				address of the next struct... */
				*list = act->next;
				/* so we assign a NULL address to the prev
				field of the next struct */
				act->next->prev = NULL;
			}
			else
			{
				/* this is easy to understand... just
				reordering the pointers to the next and
				previous structures since we deleted one */
				prev->next = act->next;
				act->next->prev = prev;
			}
			free (act);
			printf("
Item Deleted. Press Any Key.");
			getch();
		}
		prev = act;
		act = act->next;
	}
}
int StrCompare (char * s1, char * s2)
{
	/* if the string are equal return 1, otherwise return 0
	just trying to implement something similar to strcmp */
	int cont, lens1, lens2, different;
	lens1 = strlen(s1);
	lens2 = strlen(s2);
	for (cont = 0, different = 1; (cont < lens1) && (cont < lens2); cont++)
		if ( (*(s1 + cont)) != (*(s2 + cont)) )
			/* if I found one different character they are not equal */
			different = 0;
	return different;
}
void Search (struct nodo ** list)
{
	/* this function searches for either a number of a client or for
	its name. We present a menu until the user exits the loop */
	struct nodo * act = NULL;
	int	choice, number, foundit = 0;
	char	name[40];
	if (! *list)
		return;
	do
	{
		act = *list;
		puts("

0 - Exit");
		puts("1 - Search By Name");
		puts("2 - Search By Number");
		CHOICE(choice);
		switch (choice)
		{
			case 1:
				printf("Name: "); scanf("%s", name);
				while (act)
				{
					if (StrCompare(name, act->name))
					{
						foundit = 1;
						break;
					}
					act = act->next;
				}
				if (foundit)
				{
					printf("
	Found it!");
					ShowData(act);
				}
				break;
			case 2:
				printf("
Search Number: "); scanf("%i", &number);
				while (act)
				{
					if (act->nclient == number)
					{
						foundit = 1;
						break;
					}
					act = act->next;
				}
				if (foundit)
				{
					printf("
	Found it!");
					ShowData(act);
				}
				else
					printf("

	No Data was found");
				break;
			default:
				break;
		}
	} while (choice != 0);
}
void OneByOne (struct nodo ** list)
{
	/* this is my favourite function! When this function is called for the
	first time, the first node of the list is shown. Then the user has the
	possibility to look at the next, the previous, the last and the first
	*/
	struct nodo * act = NULL;
	int choice;
	if (! *list)
	{
		printf("
Empty List.");
		return;
	}
	act = *list;
	ShowData(act);
	do
	{
		printf("

0 - Exit");
		printf("
1 - Next");
		printf("
2 - Previous");
		printf("
3 - First");
		printf("
4 - Last");
		CHOICE(choice);
		switch (choice)
		{
			case 0: break;
			case 1:
				if (!act->next)
					/* if we have a NULL address in
					act->next then we are looking at the
					last one */
					printf ("		No more entries.");
				else
				{
					/* we point to the address of the next
					structure and show it */
					act = act->next;
					ShowData(act);
				}
				break;
			case 2:
				if (!act->prev)
					/* if act->prev == NULL then we are
					showing the first one */
					printf("		No previous entries.");
				else
				{
					/* we point to address of the previous
					structure */
					act = act->prev;
					ShowData(act);
				}
				break;
			case 3:
				/* to show the first item */
				while (act->prev)
					act = act->prev;
				ShowData(act);
				break;
			case 4:
				/* to show the last item */
				while (act->next)
					act = act->next;
				ShowData(act);
				break;
			default:
				printf("Invalid Choice");
				break;
		}
	} while (choice != 0);
}
void ShowData (struct nodo * data)
{
	printf("

	Number:		%i", data->nclient);
	printf("
	Name:		%s", data->name);
	printf("
	Total:		%.2f", data->total);
}
void SeeAll (struct nodo ** list)
{
	struct nodo * act = NULL;
	int	itemshown = 0;
	if (! *list)
	{
		printf("
No Data to Show. Empty List.");
		getch();
		return;
	}
	act = *list;
	while (act)
	{
		if (itemshown == 5)
		{
			/* since no more than 5 items can be shown on screen
			we hold until the user presses a key */
			itemshown = 0;
			printf("
Press any key to continue...");
			getch();
		}
		itemshown++;
		ShowData(act);
		act = act->next;
	}
	printf("

Press any key to continue..."); getch();
}
void AddClient (struct nodo ** list)
{
	/* this functions adds a new node to the linked list. The node can
	be added at the beginning, at the end or ordered by number */
	struct nodo * aux = NULL;
	char	temp[40];
	int	number, choice;
	aux = (struct nodo *) malloc (sizeof (struct nodo));
	if (aux)
	{
		/* we ask for the information about the new client */
		printf("
Number: "); scanf("%i", &(aux->nclient));
		printf("Name: "); scanf("%s", aux->name);
		printf("Total: "); scanf("%f", &(aux->total));
		if (! *list)
		{
			/* we are creating the list. There are neither previous
			nor nexts. So, we have to specify it by assigning NULL
			to those addresses */
			*list = aux;
			aux->next = NULL;
			aux->prev = NULL;
		}
		else
		{
			puts("
0 - Cancel");
			puts("1 - Add at the beginning.");
			puts("2 - Add at the end.");
			puts("3 - Add ordered");
			CHOICE(choice);
			switch (choice)
			{
				case 0: free(aux); break;
				case 1: AddBegin(list, aux); break;
				case 2: AddEnd(list, aux); break;
				case 3: AddBetween(list, aux); break;
				default: break;
			}
		}
	}
	else
	{
		puts ("Memory unavailable.");
		getch();
	}
}
void AddEnd (struct nodo ** list, struct nodo * add)
{
	/* we will be adding "add" to the end of "list" */
	struct nodo * prev = NULL, * act = NULL;
	act = *list;
	/* we serch for the last node in the list */
	while (act)
	{
		prev = act;
		act = act->next;
	}
	/* easy to understand... */
	prev->next = add; /* the previous node addressing to the next will be addressing to add */
	add->next = NULL; /* the one we are adding addressing to next will be addressing NULL, since it's the last one */
	add->prev = prev; /* finally, the one we are adding addressing the previous one will address prev */
}
void AddBegin (struct nodo ** list, struct  nodo * add)
{
	/* Add a new node to the beginning of the list */
	struct nodo * act = NULL;
	act = *list;
	act->prev = add;
	add->prev = NULL; /* since it's the first one then there are not any previous one */
	add->next = act;
	*list = add;
}
void AddBetween (struct nodo ** list, struct nodo * add)
{
	struct nodo * act = NULL, * prev = NULL;
	/* this function will add the item in the linked list
	according to nodo->nclient. This function will never create the
	list, since all the functions that call this one, check if they
	have to create the list. The function can add items at the beginning,
	middle or end of the list. */
	act = *list;
	prev = *list;
	while (act && (act->nclient <= add->nclient))
	{
		prev = act;
		act = act->next;
	}
	if (! act)
		AddEnd (list, add);
	else if (prev == act)
		AddBegin (list, add);
	else
	{
		/* once again we rearrange pointers. Easy to get the idea
		if you look at the names */
		prev->next = add;
		add->next = act;
		add->prev = prev;
		act->prev = add;
	}
}
void Exit (struct nodo ** list)
{
	FreeAll (list);
}
void FreeAll (struct nodo ** list)
{
	/* we free the memory allocated for each struct */
	struct nodo * act = NULL, * next = NULL;
	if (! *list)
		return;
	act = *list;
	while (act)
	{
		next = act->next;
		free (act);
		act = next;
	}
	*list = NULL;
}


Tags: Ansi C Binary Search C++ Double Linked List Linked List Share on Facebook Share on X

◀ PREVIOUS
String Replace Function For C#
▶ NEXT
Binary Search Sample Code
  Comments 0
Login for comment
SIMILAR POSTS

Binary Search Sample Code (created at Sep 08, 2007)

How to run shell command by MFC ? (created at Sep 09, 2007)

Move window (created at Sep 07, 2007)

MFC based World Wide Web HTTP Server Source Code (created at Aug 28, 2007)

Creating and Using a CAsyncSocket Object to use CAsyncSocket (created at Aug 28, 2007)

UDP Send and Receive Using CAsyncSocket (created at Aug 28, 2007)

Using the shell to receive notification of removable media being inserted or removed (created at Aug 28, 2007)

Fast and Good Keyboard/Mouse Test without the message handler (created at Aug 27, 2007)

Simple CGI Programming in C (created at Aug 27, 2007)

C++ CGI Example working on Apache (created at Aug 27, 2007)

How to search file on certain directory ? (created at Jun 15, 2008)

How to call SetTimer function on MFC CDialog class ? (created at Jul 30, 2008)

How to load HTML resource on MFC ? (updated at Dec 17, 2023)

URL Encode, Decode function for MFC (updated at Dec 20, 2023)

KMP String Matching Algorithm (created at Jul 21, 2010)

OTHER POSTS IN THE SAME CATEGORY

Convert System.DateTime to UNIX timestamp (created at Sep 22, 2008)

Retrieve system information (created at Sep 22, 2008)

How to call SetTimer function on MFC CDialog class ? (created at Jul 30, 2008)

How to rename(change file name) in C# ? (created at Mar 12, 2008)

Find Files in certain directory (created at Feb 25, 2008)

Implementing C#'s foreach loop in Delphi 8 (created at Oct 03, 2007)

How to detect resource leaks in a Form (created at Sep 25, 2007)

The best way to enable and disable buttons, menu items and toolbar buttons (created at Sep 25, 2007)

How to exit from a console application (created at Sep 25, 2007)

How to restrict a program to a single instance (created at Sep 25, 2007)

Compress and decompress strings in C# (created at Sep 25, 2007)

Graphics in C# - Irregular Forms (created at Sep 25, 2007)

Extracting the Country from IP Address (created at Sep 25, 2007)

How to run shell command by MFC ? (created at Sep 09, 2007)

Binary Search Sample Code (created at Sep 08, 2007)

String Replace Function For C# (created at Aug 28, 2007)

How to print character in C# by ASCII code (created at Aug 28, 2007)

MFC based World Wide Web HTTP Server Source Code (created at Aug 28, 2007)

Creating and Using a CAsyncSocket Object to use CAsyncSocket (created at Aug 28, 2007)

UDP Send and Receive Using CAsyncSocket (created at Aug 28, 2007)

Using the shell to receive notification of removable media being inserted or removed (created at Aug 28, 2007)

Adding Custom Paper Sizes To Named Printers (created at Aug 27, 2007)

Print HTML In C# With Or Without The Web Browser Control And The Print Dialog (created at Aug 27, 2007)

A Customizable Printing Text Class (created at Aug 27, 2007)

Simplified .NET Printing In C# (created at Aug 27, 2007)

How To Print Text In C# (created at Aug 27, 2007)

C Sharp Lists (created at Aug 27, 2007)

Simple Example Of IF/THEN Using C# (created at Aug 27, 2007)

Fast and Good Keyboard/Mouse Test without the message handler (created at Aug 27, 2007)

Simple CGI Programming in C (created at Aug 27, 2007)

UPDATES

Creating a Pinterest-Style Card Layout with Bootstrap and Masonry (created at Apr 24, 2024)

Mastering Excel Data Importation in PHP (updated at Apr 24, 2024)

JSON format control in PHP (updated at Apr 24, 2024)

Equal Height Blocks in Bootstrap with JavaScript (created at Apr 22, 2024)

How to convert integer to text string ? (updated at Apr 22, 2024)

Checking similarity between two strings in PHP (updated at Apr 21, 2024)

Create Blob Image in HTML based on the given Text, Width and Height in the Center of the Image without saving file (updated at Apr 21, 2024)

How do I determine the client IP type (IPv4/IPv6) in PHP (updated at Apr 16, 2024)

How do I determine the client IP type in Python - IPv4 or IPv6 (updated at Apr 13, 2024)

Getting Started with PyTorch: A Beginner's Guide to Building Your First Neural Network (updated at Apr 09, 2024)

Predicting Buyer Preferences with PyTorch: A Deep Learning Approach (updated at Apr 09, 2024)

Forecasting the Weather with PyTorch: A Beginner's Guide to Temperature Prediction (created at Apr 09, 2024)

PyTorch example to Forcast Stock Price based on 10 days Dataset (created at Apr 09, 2024)

Mastering Model Persistence: Saving and Loading Trained Machine Learning Models in Python (created at Apr 08, 2024)

Harnessing the Power of Random Forest Algorithm in Python (created at Apr 08, 2024)

Understanding and Implementing K-Nearest Neighbors (KNN) Algorithm in Python (created at Apr 08, 2024)

Forecasting with Linear Regression and KNN Regression in Python (updated at Apr 07, 2024)

What is 302 Found Redirection in HTTP 1.1? (created at Apr 04, 2024)

Mastering Random Forest Regression: A Comprehensive Guide with Python Examples (updated at Apr 01, 2024)

Python Implementation of Linear Regression (updated at Apr 01, 2024)

Mastering Supervised Machine Learning with Python: A Comprehensive Guide (created at Apr 01, 2024)

Mastering AI: A Beginner's Guide to Python Programming and Beyond (created at Apr 01, 2024)

How do I create animated background for Google Meet? (updated at Mar 28, 2024)

Building a Simple DNS Server in Delphi with TTL Support (created at Mar 16, 2024)

How to force cookies, disable php sessid in URL ? (updated at Mar 16, 2024)

Implementing a Versatile DNS Server in PHP: Handling A, AAAA, CNAME, and TXT Records (updated at Mar 16, 2024)

Implementing a Versatile DNS Server in Python: Handling A, AAAA, CNAME, and TXT Records (created at Mar 16, 2024)

Building a Basic DNS Server in PHP/Python: A Beginner's Guide (updated at Mar 15, 2024)

Dynamic DNS Made Easy: Building a Python-Based Solution (created at Mar 15, 2024)

Exploring the Depths of Data Transfer: sendfile vs. kTLS (created at Mar 15, 2024)