单链表通讯录 —— 通讯录2.0

  单链表通讯录 —— 通讯录2.0

// 头文件
#ifndef _ADDRESS_H
#define _ADDRESS_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SUCCESS 10000
#define FAILURE 10001
#define TRUE    10002
#define FALSE   10003

struct address
{
    char name[20];  // 名字
    char sex[10];   // 性别
    int age;        // 年龄
    char tel[11];   // 电话
    char addre[20]; // 地址

    struct address *next;  // 指针域
};
typedef struct address L;

void menu();           // 显示界面
int Init(L **l);       // 初始化链表
int namesort(L *l);    // 以名字排序
int agesort(L *l);     // 以年龄排序
int Insert(L *l);      // 1、添加联系人
int show(L *l);        // 2、显示所有联系人信息
int delet(L *l);       // 3、删除联系人信息
int mod(L *l);         // 4、修改联系人信息
int find(L *l);	       // 5、查找联系人

#endif

// 主函数文件
#include "address.h"

int main()
{
	int ret,n = 0;
	char ch;
	L *l;
	ret = Init(&l);
	if(FAILURE == ret)
	{
		printf("Init Failure!");
		exit(1);
	}	
	while(1)
	{
		menu();
		printf("请输入选择的操作:");
		scanf(" %c",&ch);
		printf("\n");
		
		switch(ch)
		{
			case '1':
				ret = Insert(l);
				if(FAILURE == ret)
				{
					printf("添加联系人失败\n");
				}
				else
				{
					printf("添加联系人成功\n");
				}
				break;
			case '2':
				ret  = show(l);   // 显示所有联系人信息
				if(FAILURE == ret)
				{
					printf("查看联系人失败\n");
				}
				else if(FALSE == ret)
				{
					printf("通讯录为空,没有可以显示的联系人\n");
				}
				break;
			case '3':
				ret = delet(l);
				if(FAILURE == ret)
				{
					printf("删除失败\n");
				}
				else if(TRUE == ret)  // 找不到
				{
					printf("通讯录中没有你要删除的联系人\n");
				}
				else if(ret == FALSE)  // 没有
				{
					printf("通讯录为空,没有可以删除的联系人\n");
				}
				else
				{
					printf("删除成功\n");
				}
				break;			
			case '4':
				ret = mod(l);
				if(FAILURE == ret)
				{
					printf("修改失败\n");
				}
				else if(ret == FALSE)  // 空的时候
				{
					printf("通讯录为空,没有可以修改的联系人\n");
				}
				else if(ret == TRUE)  // 找不到
				{
					printf("通讯录中没有要修改的联系人\n");
				}
				else // 找到
				{
					printf("修改成功\n");
				}
				break;
			case '5':
				ret = find(l);
				if(FAILURE == ret)
				{
					printf("查找失败\n");
				}
				else if(ret == FALSE)  // 没有 
				{
					printf("通讯录为空,没有可以查询的联系人\n");
				}
				else if(TRUE == ret)  // 找不到
				{
					printf("通讯录中没有要查询的联系人\n");
				}
				else
				{
					printf("查找成功\n");
				}
				break;	
			case '6':
				break;
			default :
				printf("输入有误,请重新输入!\n");
				break;
		}
		if(ch == '6')
		{
			printf("是否确定退出?1/0\n");
			scanf("%d",&n);
			if(1 == n)
			{
			  printf("欢迎下次使用\n");
			  break;
			}
		}
	}
	return 0;
}

// 功能函数文件
#include "address.h"

void menu()     //显示通讯录界面,方便进行功能选择
{
	//system("color f4");// 控制背景色和字体颜色   红色字体,亮白色背景
	printf("================================================\n");
	printf("===                通讯录2.0                 ===\n");
	printf("================================================\n");
	printf("===                                          ===\n");
	printf("===              1、添加联系人               ===\n");   
	printf("===              2、显示联系人               ===\n");
	printf("===              3、删除联系人               ===\n");    
	printf("===              4、修改联系人               ===\n");
	printf("===              5、查找联系人               ===\n");  
	printf("===              6、退出通讯录               ===\n");
	printf("===                                          ===\n");
	printf("================================================\n");
 }
 
int Init( L **l)            	 // 初始化链表
{
	*l = (L *)malloc(sizeof(L)*1);
	if(NULL == (*l))
	{
		return FAILURE;
	}
	(*l)->next = NULL;
	return SUCCESS;
}

int namesort(L *l)          	 // 以名字排序
{
	L *h,*p,*p1,*q,*q1,*t;
	int flag;
	if(NULL == l || l->next == NULL || l->next->next == NULL)
	{
		return FAILURE;
	}
	h = l;
	p = h->next;
	p1 = p->next;
	while(p1 != NULL)
	{
		flag = 1;
		t = p1;
		for(q = h,q1 = q->next;q1 != p1;q = q->next,q1 = q1->next)
		{
			if(strcmp(q1->name,p1->name) > 0)
			{
				p1 = p1->next;
				p->next = p1;
				q->next = t;
				t->next = q1;
				flag = 0;
				break;
			}
		}
		if(flag)
		{
			p = p->next;
			p1 = p->next;
		}
	}		
	return SUCCESS;
}
int agesort(L *l)           	 // 以年龄排序
{
	L *h,*p,*p1,*q,*q1,*t;
	int flag;
	if(NULL == l || l->next == NULL || l->next->next == NULL)
	{
		return FAILURE;
	}
	h = l;
	p = h->next;
	p1 = p->next;
	while(p1 != NULL)
	{
		flag = 1;
		t = p1;
		for(q = h,q1 = q->next;q1 != p1;q = q->next,q1 = q1->next)
		{
			if(q1->age < p1->age)
			{
				p1 = p1->next;
				p->next = p1;
				q->next = t;
				t->next = q1;
				flag = 0;
				break;
			}
		}
		if(flag)
		{
			p = p->next;
			p1 = p->next;
		}
	}		
	return SUCCESS;
}	
int Insert(L *l)                 // 1、添加联系人信息
{
	L *p = l;
	char nam[20],ch;
	if (NULL == l)
	{
		return FAILURE;
	}

	while (p->next != NULL)  // 移动到最后
	{
		p = p->next;
	}
	L *q;
	printf("添加联系人,输入'bye'时,结束添加联系人\n");
	printf("请输入姓名:");
	scanf(" %s",nam);
	while(strcmp(nam,"bye") != 0)
	{
		q = (L *)malloc(sizeof(L) * 1);
		if (NULL == q)
		{
			return FAILURE;
		}
		strcpy(q->name,nam);
		//printf("\n");
		printf("请输入性别:");
		scanf(" %s",q->sex);
		//printf("\n");
		printf("请输入年龄:");
		scanf(" %d",&q->age);
		//printf("\n");
		printf("请输入电话:");
		scanf(" %s",q->tel);
		//printf("\n");
		printf("请输入地址:");
		scanf(" %s",q->addre);
		printf("\n");
	    q->next = p->next;
	    p->next = q;
		p = q;
		while(1)
		{
			printf("是否继续输入?y/n\n");
			scanf(" %c",&ch);
			printf("\n");
			if(ch == 'y')
			{
				printf("请输入姓名:");
				while(1)
				{
					scanf("%s",nam);
					//printf("\n");
					if(strcmp(nam,"bye") != 0)
					{
						break;
					}	
				}
				
				break;
			}
			else if(ch == 'n')
			{
				strcpy(nam,"bye");
				break;
			}
			else
			{
				printf("请输入'y/n'!\n");
			}	
		}
	}
	return SUCCESS;
}

int show(L *l)                   // 2、显示所有联系人信息
{
	int ret,n;
	L *p = l;
	if(NULL == l)  // 入参判断
	{
		return FAILURE;
	} 
	if(l->next == NULL)  // 空链表
	{
		return FALSE;
	}
	if(p->next->next == NULL )  // 只有一个联系人的时候
	{
		printf("联系人信息如下:\n");
		printf("姓名\t性别\t  年龄\t\t电话\t地址\n");
		printf("%s\t %s\t %d\t %s\t %s\t\n",p->next->name,p->next->sex,p->next->age,p->next->tel,p->next->addre);
		return SUCCESS;
	}
	while(1)  
	{	
		printf("请输入选择方式:1、以姓名显示 2、以年龄显示 其它、直接显示\n");
		scanf("%d",&n);
		if(1 == n)
		{
			ret = namesort(l);
			if(FAILURE == ret)
			{
				printf("namesort Failure!\n");
			}	
			break;
		}
		else if(2 == n)
		{
			ret = agesort(l);
			if(FAILURE == ret)
			{
				printf("agesort Failure!\n");
			}	
			break;
		}
		else   // 默认
		{
			break;
		}
	}
	p = p->next;
	printf("联系人信息如下:\n");
	printf("姓名    性别  年龄  电话  地址\n");
	while(p != NULL)
	{
		printf("%s\t %s\t %d\t %s\t %s\t\n",p->name,p->sex,p->age,p->tel,p->addre);
		p = p->next;
	}
	return SUCCESS;		
}		

int delet(L *l)                  // 3、删除联系人信息
{
	char nam[20],ch;
	int k = 1;
	L *p,*q;
	if(NULL == l) // 入参判断
	{
		return FAILURE;
	}
	if(NULL == l->next) // 空链表
	{
		return FALSE;
	}
	p = l;
	printf("请输入要删除联系人的姓名:");
	scanf("%s",nam);
	printf("\n");
	while(p->next != NULL)
	{
		if(strcmp(p->next->name,nam) == 0)
		{
			q = p->next;
			printf("要删除联系人信息如下:\n");
			printf("%s\t %s\t %d\t %s\t %s\t\n",q->name,q->sex,q->age,q->tel,q->addre);
			printf("是否确定删除 y/n : ");
			scanf(" %s",&ch);
			if('y' == ch)
			{
				p->next = q->next;
				if(p->next == NULL)   
				{
					k = 0;
				}
				free(q);
			}
			break;
		}
		p = p->next;
	}
	if(p->next == NULL && k == 1)  // 没有找到
	{
		return TRUE;
	}	
	return SUCCESS;
}

int mod(L *l)                    // 4、修改联系人信息
{
	L *p = l->next;
	char nam[20],ch;
	int k = 0;
	if(NULL == l) // 入参判断
	{
		return FAILURE;
	}
	if(NULL == l->next) // 空链表
	{
		return FALSE;
	}
	printf("请输入要修改联系人的姓名:");
	scanf("%s",nam);
	printf("\n");
	while(p != NULL)
	{
		if(strcmp(p->name,nam) == 0)
		{
			printf("要修改联系人信息如下:\n");
			printf("姓名:%s\t性别:%s\t年龄:%d\t电话:%s\t地址:%s\t\n",p->name,p->sex,p->age,p->tel,p->addre);
			printf("是否确定修改 y/n :");
			scanf(" %c",&ch);
			if('y' == ch)
			{
				printf("请输入姓名:");
				scanf(" %s",p->name);
				//printf("\n");
				printf("请输入性别:");
				scanf(" %s",p->sex);
				//printf("\n");
				printf("请输入年龄:");
				scanf(" %d",&p->age);
				//printf("\n");
				printf("请输入电话:");
				scanf(" %s",p->tel);
				//printf("\n");
				printf("请输入地址:");
				scanf(" %s",p->addre);
				printf("\n");
			}
			break;
		}
		p = p->next;
	}
	if(p == NULL)
	{
		return TRUE;
	}
	return SUCCESS;
}

int find(L *l)					 // 5、查找联系人
{
	L *p = l->next;
	char nam[20];
	if(NULL == l) // 入参判断
	{
		return FAILURE;
	}
	if(NULL == l->next) // 空链表
	{
		return FALSE;
	}
	printf("请输入要查找的联系人姓名:");
	scanf("%s",nam);
	printf("\n");
	while(p != NULL)
	{
		if(strcmp(p->name,nam) == 0)
		{
			printf("要修改联系人信息如下:\n");
			printf("姓名:%s\t性别:%s\t年龄:%d\t电话:%s\t地址:%s\t\n",p->name,p->sex,p->age,p->tel,p->addre);
			break;
		}
		p = p->next;
	}
	if(p == NULL)
	{
		return TRUE;
	}
	return SUCCESS;
}

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,下面是一个简单的单链表通讯录的数据结构: ``` struct Contact { char name[50]; char phone[20]; char email[50]; struct Contact* next; }; typedef struct Contact* ContactPtr; ``` 上面的结构体定义了一个通讯录中联系人的信息,包括姓名、电话和电子邮件地址。每个联系人都有一个指向下一个联系人的指针。使用这个结构体,我们可以定义一个单链表通讯录。 下面是一个简单的实现示例,包括添加联系人、查找联系人和删除联系人等基本操作: ``` #include <stdio.h> #include <stdlib.h> #include <string.h> struct Contact { char name[50]; char phone[20]; char email[50]; struct Contact* next; }; typedef struct Contact* ContactPtr; // 初始化通讯录 ContactPtr initContact() { ContactPtr head = (ContactPtr)malloc(sizeof(struct Contact)); head->next = NULL; return head; } // 添加联系人 void addContact(ContactPtr head, char name[], char phone[], char email[]) { ContactPtr newContact = (ContactPtr)malloc(sizeof(struct Contact)); strcpy(newContact->name, name); strcpy(newContact->phone, phone); strcpy(newContact->email, email); newContact->next = NULL; ContactPtr current = head; while (current->next != NULL) { current = current->next; } current->next = newContact; printf("联系人 %s 添加成功!\n", name); } // 查找联系人 void findContact(ContactPtr head, char name[]) { ContactPtr current = head->next; while (current != NULL) { if (strcmp(current->name, name) == 0) { printf("%s 的电话号码是:%s,电子邮件地址是:%s\n", current->name, current->phone, current->email); return; } current = current->next; } printf("未找到联系人 %s!\n", name); } // 删除联系人 void deleteContact(ContactPtr head, char name[]) { ContactPtr current = head; while (current->next != NULL) { if (strcmp(current->next->name, name) == 0) { ContactPtr temp = current->next; current->next = temp->next; free(temp); printf("联系人 %s 删除成功!\n", name); return; } current = current->next; } printf("未找到联系人 %s!\n", name); } // 打印所有联系人 void printContacts(ContactPtr head) { if (head->next == NULL) { printf("通讯录为空!\n"); return; } ContactPtr current = head->next; while (current != NULL) { printf("%s 的电话号码是:%s,电子邮件地址是:%s\n", current->name, current->phone, current->email); current = current->next; } } int main() { ContactPtr head = initContact(); addContact(head, "张三", "123456789", "zhangsan@example.com"); addContact(head, "李四", "987654321", "lisi@example.com"); addContact(head, "王五", "234567890", "wangwu@example.com"); printContacts(head); findContact(head, "张三"); findContact(head, "赵六"); deleteContact(head, "李四"); printContacts(head); return 0; } ``` 上面的代码实现了一个简单的单链表通讯录,包括添加联系人、查找联系人和删除联系人等基本操作。 ### 回答2: 单链表通讯录是一种基于数据结构的通讯录实现方式。通讯录中的每个联系人都被封装为一个节点,节点内包含联系人的信息和一个指向下一个节点的指针。该链表的头节点指向第一个联系人,最后一个联系人的节点指针为空。 单链表通讯录的优点是插入和删除联系人的操作高效。当需要插入一个新的联系人时,只需要修改指针的指向即可,无需移动其他节点。同样,删除联系人时也只需修改指针指向,不需要进行大量的数据迁移。这样可以大大提高操作的效率。 然而,单链表通讯录的缺点是查找联系人的效率相对较低。由于只能按顺序查找,当查找的联系人位于链表的末尾时,需要遍历整个链表寻找,时间复杂度较高。为了解决这个问题,可以使用更高效的数据结构,如哈希表来实现通讯录。 除了基本的插入、删除和查找操作,单链表通讯录还可以进行其他一些常见的操作,如修改联系人信息、排序联系人。修改联系人信息时,可以根据给定的姓名或其他关键字,遍历链表找到指定联系人并修改其信息。排序联系人时,可以使用冒泡排序等算法进行排序,将链表中的联系人按照一定的规则排序。 总的来说,单链表通讯录是一种简单而高效的通讯录实现方式。它具有插入、删除操作高效的优点,但查找效率相对较低。可以根据实际需求选择合适的数据结构来实现通讯录。 ### 回答3: 单链表通讯录是一种常见的数据结构,用于存储和管理联系人信息。通讯录中的每个联系人被表示为一个节点,节点包含姓名、电话号码等信息,并且有一个指向下一个节点的指针。 单链表通讯录的优点是插入、删除和查找操作都很高效。在插入操作时,只需将新的联系人节点插入到链表中,并更新相应的指针,即可完成插入操作。在删除操作时,只需修改相应节点的指针,即可将该联系人节点从链表中删除。在查找操作时,只需从头节点开始,依次遍历每个节点,直到找到目标联系人节点为止。 另一个优点是单链表通讯录能够动态地存储联系人信息。链表的长度可以根据需要进行动态调整,不需要预先分配固定的内存空间。这使得单链表通讯录更加灵活和节省内存空间。 然而,单链表通讯录也有一些缺点。首先,查询某个特定联系人节点的效率较低,需要遍历整个链表,尤其在链表较长时,效率较低。其次,在内存分配上可能存在空间浪费的问题,因为每个节点的指针需要占用额外的内存空间。 综上所述,单链表通讯录是一种高效、灵活的数据结构,适合用于存储和管理通讯录信息。但在应用中需要根据具体需求权衡其优缺点,选择合适的数据结构来实现通讯录功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值