Linux下用单链表实现一个电话本


完成了链表的学习,我们可以尝试写一些小的案例练习链表的操作。
下面我来为大家介绍用单链表实现一个简单的电话本程序。


首先我们分析一下一个完整的电话本应该包含以下功能:
1.添加联系人
2.删除联系人
3.修改联系人
4.查找联系人
5.查看所有联系人
6.清空联系人
而修改练习人又可能包含以下选项:
(1)修改姓名
(2)修改性别
(3)修改年龄
(4)修改电话号码
(5)修改地址
分析到这儿,我们就可以着手写代码了。

头文件:
//book.h
#pragma
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>

#define TestType printf("\n################################# %s #############################\n",__FUNCTION__)

typedef struct BookNode{
    char name[20];
    char gender[8];
    int age;
    char telephone[20];
    char address[100];
    struct BookNode* next;
} BookNode;
//初始化电话本
void BookListInit(BookNode** phead);
//打印电话本
void BookListPrint(BookNode* head, const char* msg);
//插入联系人
void BookListInsert(BookNode** phead,char* name,char* gender,int age,char* telephone,char* address);
//寻找联系人的位置
BookNode* BookListFindPos(BookNode* phead, char* to_find);
//删除联系人
void BookListErase(BookNode** phead, char* to_delete);
//查找联系人
void BookListFind(BookNode* phead, char* to_find);
//销毁电话本
void BookListDestroy(BookNode** phead);
//更改联系人信息
void BookListChange(BookNode** phead, char* to_change, int flag, char* newmsg);
//菜单
void TelephoneBookMenu();
具体实现
#include"book.h"

void BookListInit(BookNode** phead){
    if(phead == NULL){
        return;
    }
    *phead = NULL;
}

void Destroynode(BookNode* node){
    free(node);
}
//创建一个新的联系人节点
BookNode* CreateMum(char* uname,char* ugender,int uage,char* utelephone,char* uaddress){
    BookNode* new_node = (BookNode*)malloc(sizeof(BookNode));
    if(new_node == NULL){
    //申请内存失败
        return NULL;
    }
    //存入将练习人信息保存到节点中
    strcpy(new_node->name,uname);
    strcpy(new_node->gender,ugender);
    new_node->age = uage;
    strcpy(new_node->telephone,utelephone);
    strcpy(new_node->address,uaddress);
    new_node->next = NULL;
    return new_node;
}
//打印电话本
void BookListPrint(BookNode* head, const char* msg){
    printf("[ %s ]:\n", msg);
    BookNode* cur = head;
    if(cur == NULL){
        printf("电话簿为空!\n");
        return;
    }
    for(;cur != NULL;cur = cur->next){
        printf("name:[ %s ]\ngender:[ %s ]\nage:[ %d ]\ntelephone:[ %s ]\naddress:[ %s ]\n\n",cur->name,cur->gender,cur->age,cur->telephone,cur->address);
    }
    return;
}

//将联系人信息插入链表中
void BookListInsert(BookNode** phead,char* name,char* gender,int age,char* telephone,char* address){
    if(phead == NULL){
    //非法输入
        return;
    }
    if(*phead == NULL){
    //空链表,直接将新节点插入链表
        *phead = CreateMum(name,gender,age,telephone,address);
        return;
    }
    BookNode* cur = *phead;
    while(cur->next != NULL){
        cur = cur->next;
    }
    //不是空链表,找到最后一个节点,将新节点查到该节点之后
    cur->next = CreateMum(name,gender,age,telephone,address);
    return;
}

BookNode* BookListFindPos(BookNode* phead, char* to_find){
    if(phead == NULL){
        return NULL;
    }
    BookNode* cur = phead;
    while(cur != NULL){
        if(!strcmp(cur->name,to_find)){
            return cur;
        }
        cur = cur->next;
    }
    return NULL;
}

//删除联系人节点
void BookListErase(BookNode** phead, char* to_delete){
    if(phead == NULL){
    //非法输入
        return;
    }
    if(*phead == NULL){
    //空链表
        return;
    }
    BookNode* pos = BookListFindPos(*phead,to_delete);

    if(pos == NULL){
        return;
    }

    if( pos->next != NULL){
        strcpy((pos->name),(pos->next->name));
        strcpy((pos->gender),(pos->next->gender));
        strcpy((pos->telephone),(pos->next->telephone));
        strcpy((pos->address),(pos->next->address));
        pos->age = pos->next->age;
        BookNode* cur = pos->next;
        pos->next = pos->next->next;
        Destroynode(cur);
        cur = NULL;
        return;
    }
    if(pos->next == NULL){
        BookNode* cur = *phead;
        while(cur->next != pos){
            cur = cur->next;
        }
        Destroynode(pos);
        cur->next = NULL;
        return;
    }
}
//查找联系人,并打印具体信息
void BookListFind(BookNode* phead, char* to_find){
    if(phead == NULL){
    //空链表
        return;
    }
    BookNode* cur = phead;
    while(cur != NULL){
        if(!strcmp((cur->name),to_find)){
            printf("name:[ %s ]\ngender:[ %s ]\nage:[ %d ]\ntelephone:[ %s ]\naddress:[ %s ]\n\n",cur->name,cur->gender,cur->age,cur->telephone,cur->address);
            return;
        }
        cur = cur->next;
    }
    printf("[ 抱歉,没有找到联系人! ]\n");
    return;
}

void BookListDestroy(BookNode** phead){
    if(phead == NULL){
        return;
    }
    if(*phead == NULL){
        printf("[ 电话本为空,无法删除! ]\n");
        return;
    }

    while((*phead)!= NULL){
        BookNode* cur = *phead;
        Destroynode(cur);
        (*phead) = (*phead)->next;
    }
    return;
}

void BookListChange(BookNode** phead,char* to_change,int flag,char* newmsg){
    if(phead == NULL){
        return;
    }
    if(*phead == NULL){
        return;
    }
    BookNode* pos = BookListFindPos(*phead, to_change);

    if(pos == NULL){
        return;
    }

    switch(flag){
        case 1:
        //因为输入的是字符串,所以我们用atoi函数将字符串转换为整型
            strcpy((pos->name),newmsg);
            break;
        case 2:
            pos->age = atoi(newmsg);
            break;
        case 3:
            strcpy(pos->telephone,newmsg);
            break;
        case 4:
            strcpy(pos->address,newmsg);
            break;
    }
    return;
}

void TelephoneBookMenu(){
    printf("************************************************************\n");
    printf("******************* 大凯凯的电话本 ***************************\n");
    printf("************************************************************\n");
    printf("****** 1.添加联系人 ************* 2.删除联系人 *************\n");
    printf("************************************************************\n");
    printf("****** 3.修改联系人 ************* 4.查找联系人 *************\n");
    printf("************************************************************\n");
    printf("****** 5.查看所有联系人 ********* 6.清空所有联系人 *********\n");
    printf("************************************************************\n");
    printf("********************************************* 0.退出 *******\n");
    printf("************************************************************\n");
}

接下来是主函数:

int main(){
    BookNode* phead;
    BookListInit(&phead);
    char uname[20];
    char ugender[8];
    int uage;
    char utelephone[20];
    char uaddress[100];

    while(1){
        int choose = 0;
        TelephoneBookMenu();
        printf("请选择:");
        scanf("%d",&choose);
        switch(choose){
            case 0:
                    exit(1);
            case 1: 
               {    
                    printf("请输入姓名:\n");
                    scanf("%s",uname);  
                    printf("请输入性别:\n");
                    scanf("%s",ugender);
                    printf("请输入年龄:\n");
                    scanf("%d",&uage);
                    printf("请输入电话号:\n");
                    scanf("%s",utelephone);
                    printf("请输入地址:\n");
                    scanf("%s",uaddress);
                    BookListInsert(&phead,uname,ugender,uage,utelephone,uaddress);
               }
                    break;
            case 2:
                {
                    printf("请输入删除联系人姓名:\n");
                    scanf("%s",uname);
                    BookListErase(&phead,uname);
                }break;
            case 3:
                {
                   int choose2 = 0;
                   char newmsg[100];
                   printf("请输入修改联系人姓名\n");
                   scanf("%s",uname);
                   printf("#############################################################\n");
                   printf("#########1.修改姓名 ##############2.修改年龄#################\n");
                   printf("#############################################################\n");
                   printf("#########3.修改电话号码###########4.修改地址#################\n");
                   printf("#############################################################\n");
                   printf("请选择:");
                   scanf("%d",&choose2);
                   printf("请输入修改信息:\n");
                   scanf("%s",newmsg);
                   BookListChange(&phead,uname,choose2,newmsg);
               }break;
           case 4:
               {
                   printf("请输入查找联系人姓名:\n");
                   scanf("%s",uname);
                   BookListFind(phead,uname);
               }break;
           case 5:
               {
                   BookListPrint(phead,"联系人信息");
               }break;
           case 6:
               {
                   BookListDestroy(&phead);
               }break;
        }
    }
}

双手奉上,Makefile.

telephone_book:book.c main.c
    gcc -g $^ -o $@
.PHONY:clean
clean:
    rm telephone_book

大功告成!

最后,还有一些小建议,为了便于程序的调试,我们最好在每个函数完成之后,都单独写一个测试函数,例如:

//BookListInsert的测试函数
TestBookListInsert(){
    TestType;
    BookNode* phead;
    BookListInit(&phead);
    BookListInsert(&phead,"凯凯","男",22,"1778279xxxx","陕西科技大学六公寓");
    BookListPrint(phead,"打印信息");
    BookListInsert(&phead,"晨佩","女",21,"1829200xxxx","陕西科技大学四公寓");
    BookListInsert(&phead,"赵某某","女",21,"1559184xxxx","陕西科技大学九公寓");
    BookListPrint(phead,"打印信息");
}

int main(){
  TestBookListInsert();
  return 0;
}

这样可以极大程度的减少我们在后期调试的复杂度。

这是我自己胡乱琢磨的一个小案例,如果有什么bug或者不妥之处,欢迎发邮件到我的邮箱 ( Cyrus_wen@163.com ) 批评指正。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值