天天看點

基于單連結清單的班級通訊錄

[問題描述]

将全班同學的通訊資訊存入一個單連結清單。元素中的通訊資訊包括每一位同學的:學号、姓名、性别、宿舍、聯系電話等。要求能夠利用姓名和序号進行有關查找、插入、删除等操作。

[基本要求]

(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;
	}
	}
}
           

結果展示:

基于單連結清單的班級通訊錄
基于單連結清單的班級通訊錄

繼續閱讀