您的位置:首页 > 其它

基于单链表的班级通讯录

2018-01-03 19:59 387 查看
[问题描述]

将全班同学的通讯信息存入一个单链表。元素中的通讯信息包括每一位同学的:学号、姓名、性别、宿舍、联系电话等。要求能够利用姓名和序号进行有关查找、插入、删除等操作。

[基本要求]

(1)将本班的通讯信息输入文本文件“student_info.txt”中,读取该文件,将其中的通讯录信息存入一个单链表中;

(2)给定一个姓名,返回其通讯信息;

(3)给定一个序号,返回其通讯信息;

(4)在最后一条记录的后面增加一条学生信息;

(5)将一条新的记录插入在第i条记录之前;

(6)将一条新的记录插入在姓名为“XXX”的学生记录之前;

(7)删除第i条记录;

(8)删除姓名为“XXX”的学生记录;

(9)退出程序时,将单链表中内容再写入文本文件“student_info.txt”中,然后销毁该线性表。

链表结构:

//结点定义
typedef struct telebook //通讯录结点数据域
{
char num[MIX]; //学号
char name[MIX]; //姓名
char sex[MIX]; //性别
char hostel[MIX]; //宿舍
char telephone[MIX]; //电话号码
}telebook;

typedef struct LNode //链表结点
{
telebook data; //结点数据域
struct LNode *next; //结点指针域
}LNode,*LinkList;
重要操作,将文件信息读入链表:

void readFile(LinkList &L) //读取文件信息
{
LinkList q,p;
FILE *fp;
p=L;
q=(LNode*)malloc(sizeof(LNode));
char name[20]="通讯录.txt";
if((fp= fopen(name,"r"))==NULL)
{
printf("error\n");
exit(0);
}
while(p->next!=NULL )
{
p=p->next;
}
while(fscanf(fp,"%s%s%s%s%s\n",q->data.num,q->data.name,q->data.sex,q->data.hostel,q->data.telephone)!=EOF)
{
q->next=NULL;
p->next=q;
p=q;
q=(LNode*)malloc(sizeof(LNode));
}
printf(" 文件读取成功! \n");
fclose(fp);
}

主函数:
void main()
{
int n;
LinkList L;
InitList_L(L);
while(n!=0)
{
printf("*****************************基于单链表的班级通讯录*****************************\n");
printf(" 1:读取文件(**请先读取文件**) | 2:通过姓名查找联系人\n\n");
printf(" 3:通过学号查找联系人 | 4:在最后添加某学生信息\n\n");
printf(" 5:将新联系人加在第i条记录之前 | 6:将新联系人加在“XXX”的学生之前\n\n");
printf(" 7:删除第i条记录 | 8:删除姓名为“XXX”的学生记录\n\n");
printf(" 9:显示结果 | 0:退出程序并保存 \n\n");
printf("--------------------------------------------------------------------------------\n");
printf("请选择操作<1-9>,退出<0>:");
scanf("%d",&n);
switch(n)
{
case 1:readFile(L);
system("pause");//输入任意键继续
system("cls");//清屏
break;
case 2:Find_Name(L);
system("pause");//输入任意键继续
system("cls");//清屏
break;
case 3:Find_Num(L);
system("pause");//输入任意键继续
system("cls");//清屏
break;
case 4:CreateFromTail(L);
system("pause");//输入任意键继续
system("cls");//清屏
break;
case 5:ListInsert_L(L);
system("pause");//输入任意键继续
system("cls");//清屏
break;
case 6:ListInsert_LName(L);
system("pause");//输入任意键继续
system("cls");//清屏
break;
case 7:ListDelete_L(L);
system("pause");//输入任意键继续
system("cls");//清屏
break;
case 8:ListDelete_LName(L);
system("pause");//输入任意键继续
system("cls");//清屏
break;
case 9:PrintElem(L);
system("pause");//输入任意键继续
system("cls");//清屏
break;
case 0:saveFile(L);List_free(L);
system("cls");//清屏
break;
}
}
}


源程序:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define OK 1
#define ERROR 0
#define MIX 100
typedef int Status ;
typedef char ElemType;
//结点定义
typedef struct telebook //通讯录结点数据域
{
char num[MIX]; //学号
char name[MIX]; //姓名
char sex[MIX]; //性别
char hostel[MIX]; //宿舍
char telephone[MIX]; //电话号码
}telebook;

typedef struct LNode //链表结点
{
telebook data; //结点数据域
struct LNode *next; //结点指针域
}LNode,*LinkList;

//读取文本信息
void readFile(LinkList &L);

//单链表的初始化
Status InitList_L(LinkList &L);

void Find_Name(LinkList &L); //按姓名查询

void Find_Num(LinkList &L); //按姓名查询

Status CreateFromTail(LinkList &L); //采用尾插法在尾部插入元素

//初始条件:线性表L已经存在
//在单链线性表L的第i个元素之前插入元素
Status ListInsert_L(LinkList &L);

//在单链线性表L的姓名元素之前插入元素
Status ListInsert_LName(LinkList &L);
Status Fund_LName(LinkList &L); //寻找该姓名的位置

//初始条件:线性表L已经存在
//删除第i个元素
Status ListDelete_L(LinkList &L);

Status ListDelete_LName(LinkList &L); //删除姓名为“XXX”的学生记录

void saveFile(LinkList &L); //保存通讯录到文件

//初始条件:线性表L已经存在
//打印出所有元素
void PrintElem(LinkList L);

void List_free(LinkList L); //销毁链表

//单链表的初始化
Status InitList_L(LinkList &L)
{
L =(LNode *)malloc(sizeof(LNode)); //申请结点空间
if(L == NULL) //判断是否有足够的内存空间
printf("申请内存空间失败\n");
L->next = NULL; //将next设置为NULL,初始长度为0的单链表
return OK;
}

void readFile(LinkList &L) //读取文件信息
{
LinkList q,p;
FILE *fp;
p=L;
q=(LNode*)malloc(sizeof(LNode));
char name[20]="通讯录.txt";
if((fp= fopen(name,"r"))==NULL)
{
printf("error\n");
exit(0);
}
while(p->next!=NULL )
{
p=p->next;
}
while(fscanf(fp,"%s%s%s%s%s\n",q->data.num,q->data.name,q->data.sex,q->data.hostel,q->data.telephone)!=EOF)
{
q->next=NULL;
p->next=q;
p=q;
q=(LNode*)malloc(sizeof(LNode));
}
printf(" 文件读取成功! \n");
fclose(fp);
}

void Find_Name(LinkList &L) //按姓名查询
{
LinkList q,p;
q=L->next;
printf("输入要查询的姓名:\n");
p=(LNode*)malloc(sizeof(LNode));
scanf("%s",p->data.name);
while(q!=NULL&&strcmp(q->data.name,p->data.name)!=0)
{
q=q->next;
}
if(q==NULL)
{
printf("通讯录中没有这个姓名!\n");
}
else
{ printf("已经找到此联系人!\n");
printf(" 学号 姓名 性别 宿舍 电话号码 \n");
printf("%s %s\t %s\t %s %s\n",q->data.num,q->data.name,q->data.sex,q->data.hostel,q->data.telephone);
}
}

void Find_Num(LinkList &L) //按学号查询
{
LinkList q,p;
q=L->next;
printf("输入要查询的编号:\n");
p=(LNode*)malloc(sizeof(LNode));
scanf("%s",p->data.num);
while(q!=NULL&&strcmp(q->data.num,p->data.num)!=0)
{
q=q->next;
}
if(q==NULL)
{
printf("通讯录中没有这个编号!\n");
}
else
{ printf("已经找到此联系人!\n");
printf(" 学号 姓名 性别
b808
宿舍 电话号码 \n");
printf("%s %s\t %s\t %s %s\n",q->data.num,q->data.name,q->data.sex,q->data.hostel,q->data.telephone);
}
}

Status CreateFromTail(LinkList &L) //采用尾插法在尾部插入元素
{
LinkList r, s;
r=L; //r指针始终动态指向链表的当前表尾
while(r->next)
{//尾插法,直接把指针移位到尾部
r=r->next;
}
s=(LinkList)malloc(sizeof(LNode));
printf("在尾部插入的联系人信息为:\n");
printf(" 学号 姓名 性别 宿舍 电话号码 \n");
scanf("%s%s%s%s%s",s->data.num,s->data.name,s->data.sex,s->data.hostel,s->data.telephone);
s->next=NULL;
r->next=s;
return OK;
}

//初始条件:线性表L已经存在
//在单链线性表L的第i个元素之前插入元素
Status ListInsert_L(LinkList &L)
{
LinkList s,p=L;
int j = 0,i;
printf("输入要插入的位置:");
scanf("%d",&i);
while (p&&j < i)
{ // 寻找第i个结点
p = p->next;
++j;
}
if (!p || j > i) {printf("----无此位置添加失败-----\n");return ERROR;} // i小于1或者大于表长
s = (LinkList)malloc(sizeof(LNode)); // 生成新结点
printf("插入的联系人信息为:\n");
printf(" 学号 姓名 性别 宿舍 电话号码 \n");
scanf("%s%s%s%s%s",s->data.num,s->data.name,s->data.sex,s->data.hostel,s->data.telephone);
s->next = p->next; // 插入L中
p->next = s;
return OK;
} // LinstInsert_L

Status Fund_LName(LinkList &L) //寻找该姓名的位置
{
LinkList s,p=L->next;
int i=0;
s=(LNode*)malloc(sizeof(LNode));
scanf("%s",s->data.name);
while(p!=NULL&&strcmp(p->data.name,s->data.name)!=0)
{
p=p->next;
++i;
}
return i+1;
}

//在单链线性表L的姓名元素之前插入元素
Status ListInsert_LName(LinkList &L)
{
LinkList s,q=L,p=L->next;
printf("输入要在谁的姓名之前添加信息:");
int i=Fund_LName(L);
int j=0;
while (q&&j < i-1)
{ // 寻找第i-1个结点
q = q->next;
++j;
}
if (p==NULL) {printf("----查无此人添加失败-----\n");return ERROR;} // 如果没有找到
s = (LinkList)malloc(sizeof(LNode)); // 生成新结点
printf("插入的联系人信息为:\n");
printf(" 学号 姓名 性别 宿舍 电话号码 \n");
scanf("%s%s%s%s%s",s->data.num,s->data.name,s->data.sex,s->data.hostel,s->data.telephone);
s->next = q->next; // 插入L中
q->next = s;
return OK;
}

//初始条件:线性表L已经存在
//删除第i个元素
Status ListDelete_L(LinkList &L)
{
LinkList p=L,q;
int j = 0,i;
printf("输入要删除的位置:");
scanf("%d",&i);
while (p->next && j < i)
{ // 寻找第i个结点,并令p指向其前趋
p = p->next; ++j;
}
if (!(p->next) || j > i) {printf("----查无此人删除失败-----\n");return ERROR;} // 删除位置不合理
q = p->next;
p->next = q->next; // 删除并释放结点
free(q);
printf("----删除成功-----\n");
return OK;
} // ListDelete_L

Status ListDelete_LName(LinkList &L) //删除姓名为“XXX”的学生记录
{
LinkList p=L,q;
printf("输入要删除的学生的姓名:");
int j = 0,i=Fund_LName(L);
while (p->next && j < i-1)
{ // 寻找第i个结点,并令p指向其前趋
p = p->next; ++j;
}
if (!(p->next) || j > i-1) {printf("----查无此人删除失败-----\n");return ERROR;} // 删除位置不合理
q = p->next;
p->next = q->next; // 删除并释放结点
free(q);
printf("----删除成功-----\n");
return OK;
}

//初始条件:线性表L已经存在
//打印出所有元素
void PrintElem(LinkList L)
{
LinkList p=L->next ;
printf("当前的信息为:\n");
while(p!=NULL)
{
printf("%s %s\t %s\t %s %s\n",p->data.num,p->data.name,p->data.sex,p->data.hostel,p->data.telephone);
p=p->next;
}
printf("\n");
}

void saveFile(LinkList &L) //保存通讯录到文件
{
FILE*fp;
LinkList p;
p=L;
if((fp=fopen("通讯录.txt","wt"))==NULL) exit(0); // "wt"方式打开文件时,如果源文件中有内容,追加
if(p==NULL||p->next==NULL) //链表为空
printf("您的操作有误,请确保您的通讯录不为空!\n");
else
{
p=p->next;
while(p!=NULL)
{
fprintf(fp,"%s %s\t %s\t %s %s",p->data.num,p->data.name,p->data.sex,p->data.hostel,p->data.telephone);
fprintf(fp,"\n");
p=p->next;
}
fclose(fp);
printf("通讯录已保存!\n");
}
}

void List_free(LinkList L) //销毁链表
{
LinkList p;
while(L!= NULL)
{
p=L;
L=L->next;
free(p);
}
}

/*readFile(L) InitList_L(L) Find_Name(L) Find_Num(L) CreateFromTail(L) ListInsert_L(L) ListInsert_LName(L)
ListDelete_L(L) ListDelete_LName(L) saveFile(L)
PrintElem(L) List_free(L)*/

void main()
{
int n;
LinkList L;
InitList_L(L);
while(n!=0)
{
printf("*****************************基于单链表的班级通讯录*****************************\n");
printf(" 1:读取文件(**请先读取文件**) | 2:通过姓名查找联系人\n\n");
printf(" 3:通过学号查找联系人 | 4:在最后添加某学生信息\n\n");
printf(" 5:将新联系人加在第i条记录之前 | 6:将新联系人加在“XXX”的学生之前\n\n");
printf(" 7:删除第i条记录 | 8:删除姓名为“XXX”的学生记录\n\n");
printf(" 9:显示结果 | 0:退出程序并保存 \n\n");
printf("--------------------------------------------------------------------------------\n");
printf("请选择操作<1-9>,退出<0>:");
scanf("%d",&n);
switch(n)
{
case 1:readFile(L);
system("pause");//输入任意键继续
system("cls");//清屏
break;
case 2:Find_Name(L);
system("pause");//输入任意键继续
system("cls");//清屏
break;
case 3:Find_Num(L);
system("pause");//输入任意键继续
system("cls");//清屏
break;
case 4:CreateFromTail(L);
system("pause");//输入任意键继续
system("cls");//清屏
break;
case 5:ListInsert_L(L);
system("pause");//输入任意键继续
system("cls");//清屏
break;
case 6:ListInsert_LName(L);
system("pause");//输入任意键继续
system("cls");//清屏
break;
case 7:ListDelete_L(L);
system("pause");//输入任意键继续
system("cls");//清屏
break;
case 8:ListDelete_LName(L);
system("pause");//输入任意键继续
system("cls");//清屏
break;
case 9:PrintElem(L);
system("pause");//输入任意键继续
system("cls");//清屏
break;
case 0:saveFile(L);List_free(L);
system("cls");//清屏
break;
}
}
}


结果展示:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息