单链表实现通讯录

main.c

#include 
#include "AddressList.h"

int main()
{
	menu();
	
	return 0;
}

AddressList.c

#include 
#include "AddressList.h"
#include 

int g_id = 10000;

List *CreateList()
{
	List *ls = (List*)malloc(sizeof(List)/sizeof(char));
	if (NULL == ls)
		return NULL;
	
	//创建头结点
	ls->head = (Node*)malloc(sizeof(Node)/sizeof(char));
	if (NULL == ls->head)
	{
		free(ls);
		return NULL;
	}

	ls->head->next = NULL;//空链表
	
	return ls;
}

BOOL Insert_Last(List *ls, Data data)
{
	if (NULL == ls)
		return ERROR;
	
	Node *node = (Node*)malloc(sizeof(Node)/sizeof(char));
	if (NULL == node)
		return ERROR;
	
	node->data = data;
	node->next = NULL;//node指向NULL,表示node做最后一个结点
	
	Node *tmp = ls->head;
	while (tmp->next)//tmp遍历到最后一个结点
	{
		tmp = tmp->next;//tmp指向下一个结点
	}
	
	tmp->next = node;//原来的最后一个结点指向node
	
	return TRUE;
}

BOOL Delete_Data(List* ls, char *name)
{
	if (NULL == ls)
		return ERROR;
	
	int count = 0;
	Node *tmp = ls->head;
	while (tmp->next)
	{
		
		if (strcmp(tmp->next->data.name, name) == 0)
		{
			count++;
		}
		tmp = tmp->next;
	}

	if (0 >= count)
	{
		printf("找不到该用户\n");
		return FALSE;
	}
	else if (1 ==count)
	{
		tmp = ls->head;
		while (tmp->next)
		{
			if (strcmp(tmp->next->data.name, name) == 0)
			{
				Node *p = tmp->next;//保存要删除的结点的地址
				tmp->next =tmp->next->next;//将前一个结点的指针指向后一个结点
				free(p);//释放删除结点的空间
				
				printf("\t\t删除完成\n");
				return TRUE;
			}
			tmp = tmp->next;
		}
		
		return FALSE;
	}
	else
	{
		printf("\t\t有多个同名好友:\n");
		
		printf("\t\tID");
		printf("\t\t姓名");
		printf("\t\t手机号");
		printf("\t\t家庭地址");
		printf("\t电话\n");
		
		tmp = ls->head;
		while (tmp->next)
		{
			if (strcmp(tmp->next->data.name, name) == 0)
			{
				printf("\t\t%-8d", tmp->next->data.id);
				printf("\t%-8s", tmp->next->data.name);
				printf("\t%-11lld", tmp->next->data.phone);
				printf("\t%-8s", tmp->next->data.addr);
				printf("\t%-8d\n", tmp->next->data.tel);
			}
			tmp = tmp->next;
		}
		
		printf("\t\t请输入id删除:");
		int id;
		scanf("%d", &id);
		getchar();
		
		tmp = ls->head;
		while (tmp->next)
		{
			if (tmp->next->data.id == id)
			{
				Node *p = tmp->next;
				tmp->next =tmp->next->next;
				free(p);

				printf("\t\t删除完成\n");
				return TRUE;
			}
			tmp = tmp->next;
		}
		
		return FALSE;
	}
}

BOOL Find_Data(List* ls, char *name)
{
	if (NULL == ls)
		return ERROR;
	
	printf("\t\tID");
	printf("\t\t姓名");
	printf("\t\t手机号");
	printf("\t\t家庭地址");
	printf("\t电话\n");
	
	int count;
	Data data;
	Node *tmp = ls->head;
	while (tmp->next)
	{
		if (strcmp(tmp->next->data.name, name) == 0)
		{
			data = tmp->next->data;
			count++;
			
			printf("\t\t%-8d", data.id);
			printf("\t%-8s", data.name);
			printf("\t%-11lld", data.phone);
			printf("\t%-8s", data.addr);
			printf("\t%-8d\n", data.tel);
		}
		tmp = tmp->next;
	}
	
	if (count)
	{
		return TRUE;
	}
	else
	{
		printf("\t\t未找到该联系人\n");
		
		return FALSE;
	}
	
}

void display()
{
	printf ("\t\t0、退出程序\n");
	printf ("\t\t1、添加用户\n");
	printf ("\t\t2、删除用户\n");
	printf ("\t\t3、查找用户\n");
	printf ("\t\t4、显示用户\n");
	printf ("\t\t请输入操作指令:\n\t\t");
}

void add(List *ls)
{
	if (NULL == ls)
		return;
	
	Data data;
	data.id = g_id++;
	
	printf ("\t\t请输入用户名: ");
	scanf ("%s", data.name);
	
	printf ("\t\t请输入手机号: ");
	scanf ("%lld", &data.phone);	
	
	printf ("\t\t请输入地址: ");
	scanf ("%s", data.addr);
		
	printf ("\t\t请输入电话: ");
	scanf ("%d", &data.tel);
	
	if (TRUE == Insert_Last(ls, data))
		printf ("\t\t输入完成\n");
	else
		printf ("\t\t输入失败\n");
}

void del(List *ls)
{
	if (NULL == ls)
		return;
	
	char name[10];
	printf ("\t\t请输入用户名: ");
	scanf ("%s", name);
	getchar();
	
	Delete_Data(ls, name);
}

void find(List *ls)
{
	if (NULL == ls)
		return;

	char name[10];
	printf ("\t\t请输入用户名: ");
	scanf ("%s", name);
	getchar();
	
	Find_Data(ls, name);
}

void print(List *ls)
{
	if (NULL == ls)
		return;
	
	Node *tmp =ls->head->next;//tmp初始化,指向第一个结点
	
	printf("\t\tID");
	printf("\t\t姓名");
	printf("\t\t手机号");
	printf("\t\t家庭地址");
	printf("\t电话\n");
	
	while (tmp)//当tmp为NULL,循环结束
	{
		printf("\t\t%-8d", tmp->data.id);
		printf("\t%-8s", tmp->data.name);
		printf("\t%-11lld", tmp->data.phone);
		printf("\t%-8s", tmp->data.addr);
		printf("\t%-8d\n", tmp->data.tel);//打印结点数据
		
		tmp = tmp->next;//指向下个结点
	}
	printf("\n");
}

void Array_By_Phone(List *ls)
{
	// NULL ==ls || NULL == ls->head    链表不存在
	// NULL == ls->head->next           空链表
	// NULL == ls->head->next->next     只有一个结点的链表
	if (NULL ==ls || NULL == ls->head || NULL == ls->head->next || NULL == ls->head->next->next)
		return;
	
	Node *cur = ls->head;
	Node *tail = ls->head;
	Node *p = ls->head;

	Data data;
	int length = 0;
	int flag = 0;

	//尾结点,tail指向空
	while (tail != NULL)
	{
		tail = tail->next;
	}
	//外循环,循环链表长度-1次
	while (p->next!=tail)
	{
		flag = 0;
		cur = ls->head;
		while (cur->next != tail)
		{
			if (cur->data.phone > cur->next->data.phone)
			{
				//前后交换
				data = cur->data;
				cur->data = cur->next->data;
				cur->next->data = data;
				flag = 1;
			}
			cur = cur->next;
		}
		//尾指针向前移动
		tail = cur;
		//若为1,则证明链表已经有序
		if (flag == 0)
		{
			return;
		}
	}
}

void Array_By_ID(List *ls)
{
	// NULL ==ls || NULL == ls->head    链表不存在
	// NULL == ls->head->next           空链表
	// NULL == ls->head->next->next     只有一个结点的链表
	if (NULL ==ls || NULL == ls->head || NULL == ls->head->next || NULL == ls->head->next->next)
		return;
	
	Node *cur = ls->head;
	Node *tail = ls->head;
	Node *p = ls->head;

	Data data;
	int length = 0;
	int flag = 0;

	//尾结点,tail指向空
	while (tail != NULL)
	{
		tail = tail->next;
	}
	//外循环,循环链表长度-1次
	while (p->next!=tail)
	{
		flag = 0;
		cur = ls->head;
		while (cur->next != tail)
		{
			if (cur->data.id > cur->next->data.id)
			{
				//前后交换
				data = cur->data;
				cur->data = cur->next->data;
				cur->next->data = data;
				flag = 1;
			}
			cur = cur->next;
		}
		//尾指针向前移动
		tail = cur;
		//若为1,则证明链表已经有序
		if (flag == 0)
		{
			return;
		}
	}
}

void Show_ID(List *ls)
{
	if (NULL == ls)
		return;
	
	system("clear");
	printf("\t\t按ID排序:\n");
	Array_By_ID(ls);
	print(ls);
	
	printf("\t\t按手机号排序请按1\n");
	printf("\t\t按其他键退出\n");

	int array;
	array = getchar();
	
	if ('1' == array)
	{
		getchar();
		Show_Phone(ls);		
	}
}

void Show_Phone(List *ls)
{
	if (NULL == ls)
		return;
	
	system("clear");
	printf("\t\t按手机号排序:\n");
	Array_By_Phone(ls);
	print(ls);
	
	printf("\t\t按ID排序请按1\n");
	printf("\t\t按其他键退出\n");
	
	int array;
	array = getchar();
	
	if ('1' == array)
	{
		getchar();
		Show_ID(ls);
	}		
}



void menu()
{
	char buf[10];
	List *addrbook = CreateList();//给通讯录分配空间
	
	while(1)
	{
		system("clear");
		display();//显示菜单
		
		fgets(buf, 10, stdin);//获取指令
		system("clear");
		
		switch (buf[0])
		{
			case QUIT://退出程序
				return;
			case ADD://添加联系人
				add(addrbook);
				break;
			case DEL://删除联系人
				del(addrbook);
				break;
			case FIND://查找联系人
				find(addrbook);
				break;
			case SHOW://显示联系人
				Show_ID(addrbook);
				break;
			default://错误信息
				printf("\t\t指令错误\n");
				break;
		}
		
		printf("\t\t按ENTER键返回\n");
		getchar();
	}	
}

AddressList.h

#ifndef _ADDRESSLIST_H_
#define _ADDRESSLIST_H_

typedef enum {TRUE, FALSE, ERROR} BOOL;

typedef struct _Data
{
	int id;
	char name[10];
	long long phone;
	char addr[10];
	int tel;
}Data;

typedef struct  _node
{
	Data data;//数据域
	struct _node *next;//指针域,指向链表的下个结点
}Node;

typedef struct  _list
{
	Node* head;//头结点指针
}List;

enum MenuOption{QUIT = '0', ADD, DEL, FIND, SHOW};

List *CreateList();//创建链表

void add(List *ls);//添加联系人

void del(List *ls);//删除联系人

void find(List *ls);//查找联系人

void Show_ID(List *ls);//显示联系人(按ID排序)

void Show_Phone(List *ls);//显示联系人(按手机号排序)

void Array_By_ID(List *ls);//链表排序(按ID)

void Array_By_Phone(List *ls);//链表排序(按手机号)

void print(List *ls);//打印链表

BOOL Delete_Data(List* ls, char *name);//删除数据

BOOL Insert_Last(List *ls, Data data);//尾插

BOOL Find_Data(List* ls, char *name);//查找数据

void menu();

#endif //_ADDRESSLIST_H_

 

你可能感兴趣的:(c语言程序)