数据结构——用单链表实现通讯录

1、功能要求
制作一个电子通讯录,通过该通讯录能存入好友 ID 号、姓名(英文)、手机号码、家庭住址、公司电话。
I、 主界面:主要显示软件功能
A) 添加好友信息。
B) 列表好友信息。(包含排序功能)
C) 搜索好友
D) 删除好友
II、添加好友:
用户输入 “1” 命令后,让用户输入好友信息。添加成功或失败都需要提示
用户
III、 列表好友:
用户输入 “2” 命令后,好友信息升序排列。
IV、搜索好友:
用户输入 “3” 命令后,让用户输入将要搜索好友姓名查询。如果未搜索到
请友好提示。如果搜索到,显示出该好友信息。
V、删除好友:
用户输入 “4” 命令后,让用输入将要删除好友姓名删除,如果存在同名的多个好友,则列表出,所有同名的好友信息,让用户通过输入ID 号删除。提示用
户删除成功。

2、程序文件
I、
在电子通讯录/src目录下分别创建main.c、LinkList.c文件

//main.c

#include <stdio.h>
#include "LinkList.h"

int main()
{
	//创建链表
	List *ls = CreateList();
	
	if (NULL == ls)
	{
		printf ("创建失败\n");
	}
	//printf ("创建成功\n");

	//显示主菜单
	Menu(ls);
	
	Destory(ls);
	
	return 0;
}
// LinkList.c

#include <stdio.h>
//包含malloc()、system("clear")
#include <stdlib.h>
//包含strcmp()
#include <string.h>
#include "LinkList.h"

//创建链表
List *CreateList(void)
{
	List *ls = (List*)malloc(sizeof(List)/sizeof(char));
	
	if (NULL == ls)
	{
		//数据类型是指针类型,那我们一般成功的时候返回相应的地址,
		//失败的时候返回NULL/用NULL‘清零’
		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 Menu(List *ls)
{
	if (NULL == ls)
	{
		return ERROR;
	}
	
	system ("clear");
    BYTE_1 buf[10];
	//search_flag = 1时,搜索不成功!
	BYTE_4 search_flag = 1;

	//delete_flag = 1时,删除不成功!
	BYTE_4 delete_flag = 1;
	
    while (1)
    {
        printf ("------------------\n");
		printf ("|     0.退出     |\n");
        printf ("| 1.添加好友信息 |\n");
        printf ("| 2.列表好友信息 |\n");
        printf ("| 3.  搜索好友   |\n");
		printf ("| 4.  删除好友   |\n");
		printf ("------------------\n");
		
        printf("请输入指令:");
		//fgets(buf, 10, stdin); ==>改用这条指令有问题,暂未解决
		scanf ("%s", buf);
		
		//退出、增、显、查、删
        switch (buf[0])
        {
            case ADD:  
				Add_Contact(ls);
                break;
            case DISPLAY:		
				Display_Contact(ls);
                break;
            case SEARCH:
			    //search_flag = 1时,搜索不成功!
				//搜索成功,返回0
				while (1 == search_flag)
				{
					search_flag = Search_Contact(ls);
				}
				search_flag = 1;
				break;
			case DELETE:
				//delete_flag = 1时,不成功!
				//删除成功,返回0
				while (1 == delete_flag)
				{
					delete_flag = Delete_Contact(ls);
				}
				delete_flag = 1;
				break;
			case QUIT:
				// 清屏
				system("clear"); 
				return;
            default:
				system("clear");
				printf ("输入指令有误,请重新输入!\n");
                break;
        }
    }	
}

//添加好友信息、尾插
BOOL Add_Contact(List *ls)
{
	if (NULL == ls)
	{
		return ERROR;
	}
	
	// 清屏
	system("clear"); 
		
	Node *node = (Node *)malloc(sizeof(Node)/sizeof(BYTE_1));
	
	if (NULL == node)
	{
		return ERROR;
	}
	
	//flag = 1 添加成功 flag = 0 添加失败
	BYTE_4 flag = 0;
	
	printf ("请输入好友ID号:");
	scanf ("%d", &node->id);

	printf ("请输入好友姓名:");
	scanf ("%s", node->name);
	
	printf ("请输入好友手机号码:");
	scanf ("%lld", &node->mobilephone);
	
	printf ("请输入好友家庭住址:");
	scanf ("%s", node->homeaddress);
	
	printf ("请输入好友公司电话:");
	scanf ("%lld", &node->businessnumber);
	
	node->next = NULL;
	
	//头结点
	Node *tmp = ls->head;
	
	//作表达式时,取指针变量中存放的地址值
	while (tmp->next)
	{
		tmp = tmp->next;
	}

	tmp->next = node;
	
	flag = 1;

	// 清屏
	system("clear"); 
	
	if (1 == flag)
	{
		printf ("好友信息添加成功!\n");
		// 程序睡眠1秒
		sleep(1);        
		system("clear"); 
	}
	else
	{
		printf ("好友信息添加失败!\n");
	}
	
	return TRUE;
}

//列表好友信息
BOOL Display_Contact(List *ls)
{
	if (NULL == ls)
	{
		return ERROR;
	}
	
	// 清屏
	system("clear"); 

	//冒泡排序:按ID从小到大
	Sort(ls);
	
	printf("ID号\t姓名\t手机号码\t\t家庭住址\t\t公司电话\n"); 

	Node *tmp = ls->head->next;
	
	while (tmp)
	{
		printf ("%-4d\t", tmp->id);
		printf ("%-4s\t", tmp->name);
		printf ("%-13lld\t\t", tmp->mobilephone);
		printf ("%-10s\t\t", tmp->homeaddress);
		printf ("%-13lld\n", tmp->businessnumber);
		
		tmp = tmp->next;
	}
}

//冒泡排序
BOOL Sort(List *ls)
{
    if((ls->head -> next == NULL) || (ls->head->next->next == NULL))
    {
        return ERROR;
    }

    Node *pre, *cur, *next, *end, *temp;
    Node *tmp = ls->head;
    end = NULL;
	
    //从链表头开始将较大值往后沉
    while(tmp->next != end)
    {
        for(pre = tmp, cur = pre->next, next = cur->next; 
			next != end; 
			pre = pre->next, cur = cur->next, next = next->next)
        {
            //相邻的节点,按id进行比较
            if(cur->id > next->id)
            {
                cur->next = next->next;
                pre->next = next;
                next->next = cur;
				
                temp = next;
                next = cur;
                cur = temp;
            }
        }
        end = cur;
    }
}

//搜索好友:按姓名
BYTE_4 Search_Contact(List *ls)
{
	if (NULL == ls)
	{
		return -1;
	}
	
	//若搜索的人不存在,flag = 1
	int flag = 0;
	
	// 清屏
	system("clear"); 
	BYTE_1 Name[10];
	printf ("请输入您想查找的好友的姓名:");
	scanf ("%s", Name);
	
	//tmp相当于头结点
	Node *tmp = ls->head;
	
	while (tmp->next)
	{
		if (0 == strcmp(tmp->next->name, Name))
		{
			system("clear"); 
			
			printf ("您所搜索的好友的信息如下:\n");
			printf ("ID号:%d\n", tmp->next->id);
			printf ("姓名:%s\n", tmp->next->name);
			printf ("手机号码:%lld\n", tmp->next->mobilephone);
			printf ("家庭住址:%s\n", tmp->next->homeaddress);
			printf ("公司电话:%lld\n", tmp->next->businessnumber);	
			
			return 0;
		}

		tmp = tmp->next;
	}
	
	system("clear"); 
			
	printf ("您所搜索的姓名为 %s 的好友不存在!\n", Name);
	printf ("请再次输入您想查找的好友的姓名!\n");
	// 程序睡眠1秒
	sleep(1);
	
	return 1;
}

//删除好友:按姓名
//姓名相同,再按ID删除
BYTE_4 Delete_Contact(List *ls)
{
	if (NULL == ls)
	{
		return -1;
	}
	
	//统计姓名相同的人数
	BYTE_4 count = 0;
	BYTE_4 Id;
	
	BYTE_1 Name[10];
	system("clear");
	printf ("请输入您想删除的好友的姓名:");
	scanf ("%s", Name);
	
	//system("clear"); 
	Node *tmp = ls->head;
	
	//初始:头结点中存的地址值
	while (tmp->next)
	{
		if (0 == strcmp(tmp->next->name, Name))
		{
			count++;	
		}

		tmp = tmp->next;
	}

	//tmp回位
	tmp = ls->head;

	if (0 == count)
	{
		system("clear"); 
			
		printf ("您所删除的姓名为 %s 的好友不存在!\n", Name);
		printf ("请再次输入您想删除的好友的姓名!\n");
		sleep(1);
		
		return 1;
	}
	
	//姓名不重复时,直接删除!
	while (1 == count)
	{
		while (tmp->next)
		{
			if (0 == strcmp(tmp->next->name, Name))
			{
				Node *p = tmp->next;
				tmp->next = p->next;
				free(p);
				printf ("删除成功!\n");
				
				return 0;
			}
		
			tmp = tmp->next;
		}
	}
	
	//姓名重复时,按ID删除
	while(count > 1)
	{
		printf ("姓名为 %s 的好友共有 %d 人,其信息如下:\n", Name, count);
		printf("ID号\t姓名\t手机号码\t\t家庭住址\t\t公司电话\n");
		
		while (tmp->next)
		{
			if (0 == strcmp(tmp->next->name, Name))
			{
				printf ("%-4d\t", tmp->next->id);
				printf ("%-4s\t", tmp->next->name);
				printf ("%-13lld\t\t", tmp->next->mobilephone);
				printf ("%-10s\t\t", tmp->next->homeaddress);
				printf ("%-13lld\n", tmp->next->businessnumber);
			}
			
			tmp = tmp->next;
		}
		
		//tmp回位
		tmp = ls->head;
		printf ("请输入您想删除的好友的ID:");
		scanf ("%d", &Id);
		
		while (tmp->next)
		{
			if (tmp->next->id == Id)
			{
				Node *p = tmp->next;
				tmp->next = p->next;
				free(p);
				printf ("删除成功!\n");
				
				return 0;
			}
		
			tmp = tmp->next;
		}	
	}
	
	return FALSE;
}

//销毁	
void Destory(List *ls)
{
	if (NULL == ls)
	{
		return;
	}
	
	Node *tmp = ls->head;
	
	while (tmp->next)
	{
		Node *p = tmp->next;
		tmp->next = p->next;
		free(p);
	}
	
	free(ls->head);
	free(ls);
}

II、
在电子通讯录/seq/include目录下创建LinkList.h文件

//LinkList.h

#ifndef _LINKLIST_H_
#define _LINKLIST_H_

//退出、增、显、查、删
enum {QUIT, ADD, DISPLAY, SEARCH, DELETE};
typedef enum {TRUE, FALSE, ERROR} BOOL;

typedef char BYTE_1;
typedef int BYTE_4;
typedef long long BYTE_8;

//每一个结点中应包含一个指针变量,用它来存放下一结点的地址
typedef struct _node
{
	//数据域
	BYTE_4 id;//ID号
	BYTE_1 name[10];//姓名
	BYTE_8 mobilephone;//手机号码
	BYTE_1 homeaddress[20];//家庭住址
	BYTE_8 businessnumber;//公司电话
	//指针域
	struct _node *next;
}Node;

typedef  struct _list
{
	//头节点
	Node *head;
}List;

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

//主界面的显示
BOOL Menu(List *ls);

//添加好友信息、尾插
BOOL Add_Contact(List *ls);

//列表好友信息
BOOL Display_Contact(List *ls);

//冒泡排序
BOOL Sort(List *ls);

//搜索好友:按姓名
BYTE_4 Search_Contact(List *ls);

//删除好友:按姓名
BOOL Delete_Contact(List *ls);

//销毁	
void Destory(List *ls);

#endif //_LINKLIST_H
		

III、
在“电子通讯录”目录下创建Makefile文件

src1 = $(wildcard ./src/*.c) 	
obj1 = $(patsubst ./src/%.c, ./obj/%.o, $(src1))  
	
target = ./bin/a.out
all:$(target)
	
$(target):$(obj1)
	gcc $(^) -o $(@)  

$(obj1):./obj/%.o:./src/%.c	
	gcc -c $(^) -I ./include -o $(@) -g

.PHONY:clean all
clean:
	-rm -rf $(target) $(obj1)	

3、测试结果

猜你喜欢

转载自blog.csdn.net/ypjsdtd/article/details/84930614