实现功能有:
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: 13260888653@163.com
> 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;
}