[問題描述]
将全班同學的通訊資訊存入一個單連結清單。元素中的通訊資訊包括每一位同學的:學号、姓名、性别、宿舍、聯系電話等。要求能夠利用姓名和序号進行有關查找、插入、删除等操作。
[基本要求]
(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;
}
}
}
結果展示:
