【C/C++】【数据结构】通讯录——链表实现

实现功能有:

1.新建,添加联系人,理论上没有上限

2.查看当前通讯录内所有联系人

3.以名字为索引查找联系人

4.以名字为索引修改联系人

5.以名字为索引删除联系人

6.按名字ASCII码值从小到大排序

7.按下按键esc退出

8.十分贴心地把字体调成了红色。

头文件 linkbook.h

#ifndef _LINKBOOK_H
#define _LINKBOOK_H

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

#define ENTER 0x0d
#define ESC 0x1b
#define NEW '1'
#define SHOW '2'
#define FIND '3'
#define MODIFY '4'
#define DELETE '5'
#define SORT '6'
#define EXIT ESC

typedef struct
{
	char name[20];
	char tel[20];
}ElemType;

struct node
{
	ElemType recoder;
	struct node *next;
};
typedef struct node Node;

int LinkInit(Node **Link);
int LinkInsert(Node *Link, int position, ElemType recoder);
int LinkLength(Node *Link);
int LinkTraverse(Node *Link, void (*visit)(ElemType));
int LinkDelete(Node *Link, int position);
void print(ElemType recoder);

void welcome();
void menu();
void AddInfo(Node *Link);
void ShowAll(Node *Link);
void Find(Node *Link);
void Modify(Node *Link);
void Delete(Node *Link);
void Sort(Node *Link);

#endif
#include <stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include "linkbook.h"


//初始化链表
int LinkInit(Node **Link)
{
	if( NULL == Link)		//若未定义实参则初始化失败
	{
		return FAILURE;
	}
	
	(*Link) = (Node *) malloc( sizeof( Node) * 1);
	(*Link)->next = NULL;
	
	return SUCCESS;
}

//链表插入节点
int LinkInsert(Node *Link, int position, ElemType recoder)
{
	if( NULL == Link)		//作插入操作的表必须存在
	{
		return FAILURE;
	}
	
	if( position < 1)		//要插入的位置必须大于0
	{
		return FAILURE;
	}
	
	Node *new;				//要插入的新节点
	Node *current = Link;	//用作寻找位置的指针
	int count = 0;			//指针移动的次数
	
	
	//将current移动到要插入的位置的前一个节点,即 position-1.
	
	while( current != NULL && count < position -1)
	{
		current = current->next;
		count++;
	}
	
	if( current == NULL || count != position - 1)	//current移动到表外或位置不对则插入失败
	{
		return FAILURE;
	}
	
	if( NULL == ( new = (Node *) malloc( sizeof( Node) * 1)))		//查找成功,生成新节点
	{
		exit(1);
	}
	
	new->recoder = recoder;							//把记录赋给新节点
	new->next = current->next;						//插入操作
	current->next = new;
	
	return SUCCESS;
}

//求链表节点个数
int LinkLength(Node *Link)
{
	if( NULL == Link)		//作求长操作的表必须存在
	{
		return FAILURE;
	}
	
	Node *current = Link;
	int length = 0;
	
	while( current->next != NULL)	//如果当前节点的下个节点存在则继续遍历
	{
		current = current->next;
		length++;
	}
	
	return length;
}

//链表遍历
int LinkTraverse(Node *Link, void (*visit)(ElemType))
{
	if( NULL == Link)
	{
		return FAILURE;
	}
	
	Node *current = Link->next;
	
	while( current != NULL)
	{
		(*visit)(current->recoder);
		current = current->next;
	}
	
	return SUCCESS;
}

//链表删除节点
int LinkDelete(Node *Link, int position)
{
	if( NULL == Link)	//作删除操作的表必须存在
	{
		return FAILURE;
	}
	
	if(position < 1)	//要删除的位置必须大于0
	{
		return FAILURE;
	}
	
	Node *current = Link;
	Node *previous;
	int count = 0;
	
	//current移动到要删除的节点的位置,用previous记录该节点前驱的位置
	while( current != NULL && count < position )
	{
		previous = current;
		current = current->next;
		count++;
	}
	
	if( NULL == current || count != position)	//current移动到表外或位置不对则删除失败
	{
		return FAILURE;
	}
	
	//删除操作
	previous->next = current->next;
	free(current);
	current = NULL;
	
	return SUCCESS;
}


void print(ElemType recoder)
{
	printf("\t%-20s %-20s\n", recoder.name, recoder.tel);
}

void welcome()
{
	system("clear");
	printf("\n\n\n\033[1;33;40m----------------------------------------------------\n\n\n\n");
	printf("%20sWelcome\n"," ");
	printf("\n\n\n----------------------------------------------------\n");
	sleep(2);
}

void menu()
{
	system("clear");
	printf("\n\n\n----------------------------------------------------\n");
	printf("\n%10s%-10s%10s%-10s\n"," ", "1.New"," ","2.Show");
	printf("\n%10s%-10s%10s%-10s\n"," ", "3.Find"," ","4.Modify");
	printf("\n%10s%-10s%10s%-10s\n"," ", "5.Delete"," ","6.Sort");
	printf("%15sPress <ESC> exit\n"," ");
	printf("----------------------------------------------------\n");
}

void AddInfo(Node *Link)
{
	if( NULL == Link)
	{
		printf("ERROR 1\n");
		sleep(1);
		exit(1);
	}
	
	char ch;
	int ret;
	ElemType recoder;
	
	
	printf("Please TYPE:\n");
	while(1)
	{
		printf("    Name: ");
		scanf("%s", recoder.name);
		printf("    Tel : ");
		scanf("%s", recoder.tel);
		
		ret = LinkInsert(Link, 1, recoder);	//头插
		#if 0	//尾插
		if( FAILURE != LinkLength(Link))
		{
			ret = LinkInsert(Link, LinkLength(Link) + 1, recoder);
		}
		else
		{
			printf("error 1.2\n");
			sleep(1);
			exit(1);
		}
		#endif
		
		if( FAILURE == ret)
		{
			printf("ERROR 1.1\n");
			sleep(1);
			exit(1);
		}
		
		printf("Quit<ESC> Continue<ENTER> \n");
		scanf("%c", &ch);
		scanf("%c", &ch);
		fflush(stdout);
		if(ch == ESC)
		{
			break;
		}
		printf("\n");
	}
}

void ShowAll(Node *Link)
{
	if( NULL == Link)
	{
		printf("error 2\n");
		sleep(1);
		exit(1);
	}
	
	int ret;
	
	printf("\t%-20s %-20s\n", "Name", "Telephone number");
	
	ret = LinkTraverse(Link, print);
	if( FAILURE == ret)
	{
		printf("error 2.1\n");
		sleep(1);
		exit(1);
	}
	else
	{
		sleep(3);
	}
}


void Find(Node *Link)
{
	if( NULL == Link)
	{
		printf("error 3\n");
		sleep(1);
		exit(1);
	}
	
	Node *current = Link;		// current 	指向目标节点的前一个
	Node *target;				// target	记录找到的目标节点
	char name[20];
	
	printf("Press name:");
	scanf("%s", name);
	
	printf("Find result:\n");
	printf("\t%-20s %-20s\n", "Name", "Telephone number");
	
	while( current->next != NULL )
	{
		target = current->next;		
		if( 0 == strcmp(target->recoder.name, name))
		{
			
			printf("\t%-20s %-20s\n", target->recoder.name, target->recoder.tel);
			printf("Find success.\n");
			sleep(1);
			return;
		}
		current = current->next;
	}	
	printf("Can't find %s's infomation", name);
	fflush(stdout);
	sleep(2);
}


void Modify(Node *Link)
{
	if( NULL == Link)
	{
		printf("error 3\n");
		sleep(1);
		exit(1);
	}
	
	Node *current = Link;		// current 	指向目标节点的前一个
	Node *target;				// target	记录找到的目标节点
	char name[20];
	
	printf("Press name:");
	scanf("%s", name);
	
	printf("Find result:\n");
	printf("\t%-20s %-20s\n", "Name", "Telephone number");
	
	while( current->next != NULL )
	{
		target = current->next;		
		if( 0 == strcmp(target->recoder.name, name))	
		{
			printf("\t%-20s %-20s\n", target->recoder.name, target->recoder.tel);
			printf("Please TYPE:\n");
			printf("    %s's new Tel : ", name);
			scanf("%s", target->recoder.tel);
			printf("\n");
			printf("Modify success.\n");
			sleep(1);
			return;
		}
		current = current->next;
	}	
	printf("Can't find %s's infomation", name);
	fflush(stdout);
	sleep(2);
}

void Delete(Node *Link)
{
	if( NULL == Link)
	{
		printf("error 3\n");
		sleep(1);
		exit(1);
	}
	
	Node *current = Link;		// current 	指向目标节点的前一个
	Node *target;				// target	记录找到的目标节点
	char name[20];
	
	printf("Press name:");
	scanf("%s", name);
	
	printf("Find result:\n");
	printf("\t%-20s %-20s\n", "Name", "Telephone number");
	
	while( current->next != NULL )
	{
		target = current->next;		
		if( 0 == strcmp(target->recoder.name, name))
		{
			printf("\t%-20s %-20s\n", target->recoder.name, target->recoder.tel);
			current->next = target->next;	//脱离目标节点
			free(target);		//free释放目标节点
			target = NULL;
			printf("Delete success.\n");
			sleep(1);
			return;
		}
		current = current->next;
	}	
	printf("Can't find %s's infomation", name);
	fflush(stdout);
	sleep(2);
}

void Sort(Node *Link)
{
	if( NULL == Link)
	{
		printf("error 6\n");
		sleep(1);
		exit(1);
	}
	
	Node *current;	//current 指向要进行排序的节点
	Node *rest;		//rest    指向剩下的未排序的节点,从第二个节点开始
	Node *travel;	//travel  指向排序后的节点
	
	int ret;
	
	rest = Link->next->next;  	//rest	指向第二节点,单一节点是有序的,排序从第二节点开始
	Link->next->next = NULL;	// 第一节点指针域指向NULL
	
	while( rest != NULL)
	{
		travel = Link;			//travel	从头指针开始
		current = rest;			//current	指向第一个未排序的节点
		rest = current->next;	//rest		指向剩下的未排序的节点
		
		//移动 travel 到最后一个current->name大于排序后的节点
		//移动 travel 到 current->name 小于 travel->next->name
		while( NULL != travel->next && strcmp(current->recoder.name, travel->next->recoder.name) > 0)
		{
			travel = travel->next;
			//printf("+++\n");
		}//跳出循环时 current->name 仍然大于 travel->name
		 //但是 current->name 小于 travel->next->name
		 //这时把 current 插入在 travel 和 travel->next 之间
		
		if( NULL == travel->next )	//current->name小于所有的已排序的节点时,current插在最后
		{
			travel->next = current;
			current->next = NULL;
			continue;
		}
		//插入操作
		current->next = travel->next;
		travel->next = current;	
	}
	
	
	printf("Sort success\n");
	sleep(1);
}

/*************************************************************************
	> File Name: book.c
	> Author: xiehaibing
	> Mail: [email protected] 
	> Created Time: Sun 29 Jul 2018 02:41:46 PM CST
 ************************************************************************/

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include "linkbook.h"

int main()
{
	Node *Link;
	char choice;
	int ret;
	ret = LinkInit(&Link);
	if( FAILURE == ret)
	{
		exit(1);
	}
	
	welcome();
	while(1)
	{
		menu();
		scanf("%c", &choice);
		switch(choice)
		{
			case NEW:
				AddInfo(Link);
				break;
			case SHOW:
				ShowAll(Link);
				break;
			case FIND:
				Find(Link);
				break;
			case MODIFY:
				Modify(Link);
				break;
			case DELETE:
				Delete(Link);
				break;
			case SORT:
				Sort(Link);
				break;
			case EXIT:
				exit(0);
				break;
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42379345/article/details/81436594
今日推荐