基于单链表的班级通讯录

[问题描述]

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

[基本要求]

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("   学号       姓名      性别         宿舍            电话号码 \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;
	}
	}
}

结果展示:




猜你喜欢

转载自blog.csdn.net/qq_40953393/article/details/78964871