数据结构之链表的使用【C语言】

来源:互联网 发布:支持承载网络否 编辑:程序博客网 时间:2024/05/01 12:45

链表在几种数据结构中算是比较简单的,操作也比较简单。链表分为单向、双向、循环链表,其中单向链表是所有链表的基础。结合一个简单的例子,用C语 言实践单向链表的创建、修改、删除操作。在实践的过程中,学习了C语言关于scanf的使用技巧:在scanf使用多次时,需要使用 fflush(stdin)来清空缓冲区,最好每次使用后,就刷新一次,以免出现不确定的输入的问题。

学生信息:姓名、年龄。

操作:1、增加;2、修改;3、删除;4、查询;5、退出。其中查询使用strstr()函数,实现部分匹配查找。顺序查询算法复杂度为O(n)。

缺点:只有顺序添加节点功能,没有随机添加节点功能。

代码:

#include <stdio.h>#include <stdlib.h>#include <string.h>#define NAMEMAX 40#define SUCCESS 1#define FAIL 0struct student{    char studentName[NAMEMAX];    unsigned int studentAge;    struct student* next;};typedef struct student node;typedef struct student* pNode;static int studentNumber;/********* 函数声明 开始 *********/pNode add_student(pNode head);pNode find_lastNode(pNode head);void modify_student(pNode head);pNode delete_student(pNode head);int search_student(pNode head);void quit_student(pNode head);/********* 函数声明 结束 *********//*** * 查找最后一个节点 */pNode find_lastNode(pNode head){    pNode tempPNode;    tempPNode = head;    while(tempPNode->next != NULL)    {        tempPNode = tempPNode->next;    }    return tempPNode;}/*** * 显示学生个人信息 */void show_student_information(pNode node){    printf("姓名:%s\n",node->studentName);    printf("年龄:%u\n",node->studentAge);}/** * 增加学生信息 * 创建单向链表 * head:链表头指针 */pNode add_student(pNode head){    char tempName[NAMEMAX];//学生姓名临时变量    unsigned int tempAge;//学生年龄临时变量    pNode tempPNode;    pNode tempPPreNode;    char isAdd;    printf("\n************************\n");    printf("      增加学生信息\n");    printf("************************\n");    printf("请输入学生姓名: ");    scanf("%s",tempName);//输入姓名    printf("请输入学生年龄: ");    while((scanf("%u",&tempAge) !=1) || tempAge <=0)//输入年龄    {        printf("请输入正确的年龄(大于0的整数): ");    }    printf("************************\n");    printf("学生信息\n");    printf("姓名:%s\n", tempName);    printf("年龄:%u\n", tempAge);    printf("是否增加(Y/N): ");    fflush(stdin);//刷新缓冲区    while((scanf("%c",&isAdd) != 1) || (isAdd != 'Y' && isAdd != 'y' && isAdd != 'N' && isAdd != 'n'))//是否增加    {        printf("请输入Y或者y或者N或者n!\n");        printf("是否增加(Y/N): ");        //刷新缓冲区        fflush(stdin);    }    if(isAdd == 'Y' || isAdd == 'y')    {        if(head == NULL)//无节点        {            head = (pNode)malloc(sizeof(node));            strcpy(head->studentName, tempName);            head->studentAge = tempAge;            head->next = NULL;        }        else//有节点        {            tempPNode = (pNode)malloc(sizeof(node));            strcpy(tempPNode->studentName, tempName);            tempPNode->studentAge = tempAge;            tempPNode->next = NULL;            tempPPreNode = find_lastNode(head);            tempPPreNode->next = tempPNode;        }        studentNumber ++;        printf("增加学生信息成功,");    }    else    {        printf("增加学生信息失败,");    }    printf("返回主菜单\n\n");    return head;}/** * 修改学生信息 * 顺序查找链表 */void modify_student(pNode head){    unsigned int index = 0;//选中学生的序号    unsigned int tmpIndex = 0;//临时变量    pNode tmpNode;//节点临时变量    char tmpName[NAMEMAX];    unsigned int tmpAge = 0;    char isAdd;    if(search_student(head))    {        printf("请选择序号:");        while((scanf("%u",&index) != 1) || index == 0)        {            printf("请输入大于0的整数!\n");            printf("请选择序号:");            fflush(stdin);        }        tmpNode = head;        while(tmpNode)        {            if(strstr(tmpNode->studentName,tmpName) != NULL)/*查找成功*/            {                tmpIndex++;                if(tmpIndex == index)//找到                {                    break;                }                else//未找到                {                    tmpNode = tmpNode->next;                }            }        }        if(tmpIndex != 0 && tmpIndex == index)//找到        {            printf("选中的学生信息:\n");            show_student_information(tmpNode);            printf("新信息:\n");            printf("姓名:");            scanf("%s",tmpName);            printf("年龄:");            while((scanf("%u",&tmpAge) != 1) || tmpAge == 0)            {                printf("请输入大于0的整数!\n");                printf("年龄:");                fflush(stdin);            }            printf("是否修改(Y/N): ");            fflush(stdin);//刷新缓冲区            while((scanf("%c",&isAdd) != 1) || (isAdd != 'Y' && isAdd != 'y' && isAdd != 'N' && isAdd != 'n'))//是否增加            {                printf("请输入Y或者y或者N或者n!\n");                printf("是否修改(Y/N): ");                //刷新缓冲区                fflush(stdin);            }            if(isAdd == 'Y' || isAdd == 'y')//修改            {                strcpy(tmpNode->studentName, tmpName);                tmpNode->studentAge = tmpAge;                printf("已修改!返回主菜单。\n");            }            else//不修改            {                printf("未修改!返回主菜单。\n");            }        }        else//未找到        {            printf("未修改!返回主菜单。\n");            return;        }    }}/*** * 按照姓名模糊查找,并删除相关学生信息 * 删除链表节点 */pNode delete_student(pNode head){    unsigned int index = 0;//选中学生的序号    unsigned int tmpIndex = 0;//临时变量    pNode tmpNode = NULL;//节点临时变量    pNode tmpPreNode = NULL;//要删除的节点的前一个节点临时变量    char tmpName[NAMEMAX];    char isDel;    if(search_student(head))    {        printf("请选择序号:");        while((scanf("%u",&index) != 1) || index == 0)        {            printf("请输入大于0的整数!\n");            printf("请选择序号:");            fflush(stdin);        }        tmpNode = head;        while(tmpNode)        {            if(strstr(tmpNode->studentName,tmpName) != NULL)/*查找成功*/            {                tmpIndex++;                if(tmpIndex == index)//找到                {                    break;                }                else//未找到                {                    tmpPreNode = tmpNode;                    tmpNode = tmpNode->next;                }            }        }        if(tmpIndex !=0 && tmpIndex == index)//找到        {            printf("是否删除(Y/N): ");            fflush(stdin);//刷新缓冲区            while((scanf("%c",&isDel) != 1) || (isDel != 'Y' && isDel != 'y' && isDel != 'N' && isDel != 'n'))//是否增加            {                printf("请输入Y或者y或者N或者n!\n");                printf("是否删除(Y/N): ");                //刷新缓冲区                fflush(stdin);            }            if(isDel == 'Y' || isDel == 'y')//删除            {                if(tmpNode == head)//如果删除的节点为头结点                {                    head = head->next;                }                else if(tmpNode->next != NULL)//删除的节点在中间                {                    tmpPreNode->next = tmpNode->next;                    tmpNode->next = NULL;                }                else if(tmpNode->next == NULL)//删除的节点在末尾                {                    tmpPreNode->next = NULL;                }                free(tmpNode);                tmpNode == NULL;                printf("删除成功!返回主菜单。\n");                studentNumber --;            }            else//不删除            {                printf("未删除!返回主菜单。\n");            }        }        else//未找到        {            printf("未找到!返回主菜单。\n");        }    }    return head;}/*** * 按照姓名模糊查找 * 顺序查找链表 */int search_student(pNode head){    //测试使用    pNode tmpNode;    int tmpIndex = 0;    char tmpName[NAMEMAX];//学生姓名临时变量    if(head == NULL)    {        printf("没有学生信息,请添加!返回主菜单。\n");        return FAIL;    }    printf("\n************************\n");    printf("输入学生姓名【模糊查找】:\n");    fflush(stdin);    scanf("%s",tmpName);    tmpNode = head;    while(tmpNode)    {        if(strstr(tmpNode->studentName,tmpName) != NULL)/*查找成功*/        {            tmpIndex++;            printf("%d:\n",tmpIndex);            show_student_information(tmpNode);        }        tmpNode = tmpNode->next;    }    if(tmpIndex == 0)    {        printf("没有查找到名字中包含%s的学生!\n",tmpName);        printf("\n************************\n");        return FAIL;    }    printf("\n************************\n");    return SUCCESS;}/** * 退出系统,删除所有学生信息 * 删除链表 */void quit_student(pNode head){    pNode tmpNode1 = NULL;    pNode tmpNode2 = NULL;    if(head == NULL)    {        return;    }    tmpNode1 = head;    while(tmpNode1)    {        tmpNode2 = tmpNode1->next;        free(tmpNode1);        tmpNode1 = tmpNode2;    }    head = NULL;}/***** * 主程序 */int main(void){    int choice;//用户选项    int isContinue;//是否继续    pNode head;//链表头    choice = 0;    studentNumber = 0;    head = NULL;    isContinue = 1;    do{        printf("************************\n");        printf("欢迎使用学生信息管理系统\n");        printf("************************\n");        printf("主菜单:\n");        printf("1.增加学生信息\n");        printf("2.修改学生信息\n");        printf("3.删除学生信息\n");        printf("4.查询学生信息\n");        printf("5.退出系统\n");        printf("------------------------\n");        printf("已有%d名学生信息\n",studentNumber);        printf("------------------------\n");        printf("请输入菜单选项(1-5): ");        while((scanf("%d",&choice) != 1) || (choice > 5) || (choice < 1))        {            printf("警告:请输入1-5整数!\n");            printf("请输入菜单选项(1-5): ");            fflush(stdin);//刷新缓冲区        }        switch(choice)        {        case 1://增加            head = add_student(head);            break;        case 2://修改            modify_student(head);            break;        case 3://删除            head = delete_student(head);            break;        case 4://查询            search_student(head);            break;        case 5://退出系统            quit_student(head);            isContinue = 2;            break;        default://异常错误,暂无处理            printf("出现异常错误,退出系统!\n");            break;        }    }while(isContinue == 1);    return 0;}


 

原创粉丝点击