c语言实现双循环链表(创建、增、删、查、改、显示、退出功能)学生管理系统

双循环链表(学生管理系统)

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>

typedef struct student//定义数据结构体
{
    int number;
    char name[20];
    char sex[4];
    float suiji;
    float English;
    float tulun;
    float average;
}Stu;
typedef struct node
{
    struct node *prior;//节点前向指针
    Stu data;//节点数据
    struct node *next;//节点后向指针
}Node;

HANDLE lqc;
int count=0;//定义记录学生个数的全局变量

void gotoxy(int x,int y)//使光标跳到指定位置
{
    lqc=GetStdHandle(STD_OUTPUT_HANDLE);
    COORD stay;
    stay.X=x;
    stay.Y=y;
    SetConsoleCursorPosition(lqc,stay);
}

int show()//登录界面显示
{
    char zhanghao[15];
    char password[15];
    while(1)
    {
        system("color 1c");
        printf("\n\n\n\n\n\n\n\n\t\t\t\t  学生登录\n");
        printf("\t\t\t\t\t\t\t  \n");
        printf("\t\t\t  账号:________________");
        printf("\t\t\t\t\t\t\t  \n");
        printf("\t\t\t  密码:________________");
        gotoxy(62,23);
        printf("by—lqc");
        gotoxy(31,10);//光标跳到指定位置
        scanf("%s",zhanghao);
        gotoxy(31,12);
        scanf("%s",password);
        if(strcmp("12345678",zhanghao)!=0||strcmp("666",password)!=0)
        {
            printf("\n\t\t\t账号或密码错误!5秒后请重新输入......\n");
            Sleep(5000);//延时5秒
            system("cls");
        }
        else
            break;
    }
    printf("\t\t\t\t\t\t\t  \n\n");
    printf("\t\t\t登陆成功!3秒后自动转入主页面......\n");
    Sleep(3000);//延时3秒
    system("cls");
    return 0;
}

Node *judge(Node *s,Node *head)//判断创建的学号是否和已存在的学号相同
{
    Node *p;
    int n,i;
    n=s->data.number;//暂存想创建的学号
    p=head->next;//使p指向头结点后第一个节点
    for(i=0;i<count;i++)
    {
        if(p->data.number!=n)//当创建的学号和已存在的学号不相同时
        {
            p=p->next;//使p指向下一节点
            if(i==count-1)
                return NULL;//和已存在的学号不同返回NULL
        }
        else
            return p;//和已存在的学号相同返回p
    }   
}

Node *find_stu(Node *head)//查看学生数据
{
    Node *p;
    int num;
    if(head==NULL)
        return 0;
    p=head->next;//使p指向头结点后存储数据的第一个节点位置
    printf("|----------------------------------------------------------------------------|\n");
    printf("|\t\t\t\t5.查看学生数据\t\t\t\t     |\n");
    printf("|----------------------------------------------------------------------------|\n");
    printf("请选择学生的学号:");
    scanf("%d",&num);
    while(num!=p->data.number)//当在已存储的学生数据中找不到想查看的学号时
    {
        p=p->next;//使p指向下一节点
        if(p==head->next)//若查询完一遍后回到起始位置
            return NULL;//返回NULL
    }
    return p;//找到想查看的节点返回该指针
}

int print_stu(Node *head)//显示学生数据
{
    int flag,N;
    Node *p;
    if(head==NULL)
    {
        printf("学生数据未创建,暂不支持显示!\n");
        return 0;
    }
    printf("|----------------------------------------------------------------------------|\n");
    printf("|\t\t\t\t6.显示学生数据\t\t\t\t     |\n");
    printf("|----------------------------------------------------------------------------|\n");
    printf("(1).顺序显示学生数据      \t\t(2).逆序显示学生数据\n(3).从某个学生开始顺序显示\t\t(4).从某个学生开始逆序显示\n");
    printf("\n请选择显示方式(1/2/3/4):");
    scanf("%d",&flag);
    switch(flag)
    {
    case 1:
        p=head->next;//使p指向第一个存数据节点的位置
        printf("\t|---------------------------------------------------------------|\n");
        printf("\t|学号\t|姓名\t|性别\t|随机\t|英语\t|图论\t|平均分\t\t|\n");
        printf("\t|---------------------------------------------------------------|\n");
        while(p!=head)//当p没有回到头指针时保持输出
        {
            printf("\t|%d\t|%s\t|%s\t|%.2f\t|%.2f\t|%.2f\t|%.2f\t\t|\n",p->data.number,p->data.name,p->data.sex,p->data.suiji,p->data.English,p->data.tulun,p->data.average);
            printf("\t|---------------------------------------------------------------|\n");
            p=p->next;//输完一个节点数据后使p指向下一节点
        }
        break;
    case 2:
        p=head->prior;//使p指向最后一个存数据节点的位置
        printf("\t|---------------------------------------------------------------|\n");
        printf("\t|学号\t|姓名\t|性别\t|随机\t|英语\t|图论\t|平均分\t\t|\n");
        printf("\t|---------------------------------------------------------------|\n");
        while(p!=head)//当p没有回到头指针时
        {
            printf("\t|%d\t|%s\t|%s\t|%.2f\t|%.2f\t|%.2f\t|%.2f\t\t|\n",p->data.number,p->data.name,p->data.sex,p->data.suiji,p->data.English,p->data.tulun,p->data.average);
            printf("\t|---------------------------------------------------------------|\n");
            p=p->prior;//输完一个节点数据后使p指向上一节点
        }
        break;
    case 3:
        p=find_stu(head);//找到指定节点位置然后返回该节点指针
        N=p->data.number;//暂存找到的该节点学生学号
        printf("\t|---------------------------------------------------------------|\n");
        printf("\t|学号\t|姓名\t|性别\t|随机\t|英语\t|图论\t|平均分\t\t|\n");
        printf("\t|---------------------------------------------------------------|\n");
        printf("\t|%d\t|%s\t|%s\t|%.2f\t|%.2f\t|%.2f\t|%.2f\t\t|\n",p->data.number,p->data.name,p->data.sex,p->data.suiji,p->data.English,p->data.tulun,p->data.average);
        printf("\t|---------------------------------------------------------------|\n");
        p=p->next;
        while(p->data.number!=N)//当p没有回到自己位置时
        {
            if(p==head)//若p指向了头结点
            {
                p=p->next;//使p指向下一个节点
                continue;//跳过此次循环
            }
            printf("\t|%d\t|%s\t|%s\t|%.2f\t|%.2f\t|%.2f\t|%.2f\t\t|\n",p->data.number,p->data.name,p->data.sex,p->data.suiji,p->data.English,p->data.tulun,p->data.average);
            printf("\t|---------------------------------------------------------------|\n");
            p=p->next;//使p指向下一个节点
        }
        break;
    case 4:
        p=find_stu(head);//找到指定节点位置然后返回该节点指针
        N=p->data.number;//暂存找到的该节点学生学号
        printf("\t|---------------------------------------------------------------|\n");
        printf("\t|学号\t|姓名\t|性别\t|随机\t|英语\t|图论\t|平均分\t\t|\n");
        printf("\t|---------------------------------------------------------------|\n");
        printf("\t|%d\t|%s\t|%s\t|%.2f\t|%.2f\t|%.2f\t|%.2f\t\t|\n",p->data.number,p->data.name,p->data.sex,p->data.suiji,p->data.English,p->data.tulun,p->data.average);
        printf("\t|---------------------------------------------------------------|\n");
        p=p->prior;
        while(p->data.number!=N)//当p没有回到自己位置时保持输出
        {
            if(p==head)//若p指向了头结点
            {
                p=p->prior;//使p指向上一个节点
                continue;//跳过此次循环
            }
            printf("\t|%d\t|%s\t|%s\t|%.2f\t|%.2f\t|%.2f\t|%.2f\t\t|\n",p->data.number,p->data.name,p->data.sex,p->data.suiji,p->data.English,p->data.tulun,p->data.average);
            printf("\t|---------------------------------------------------------------|\n");
            p=p->prior;//使p指向上一个节点
        }
        break;
    default :
        printf("输入选项序号错误!\n");
        return 0;
    }   
}

int change_stu(Node *head)//改变学生数据
{
    int n,m,t,flag=0;
    Node *p,*temp;
    if(head==NULL)
    {
        printf("学生数据未创建,暂不支持改变!\n");
        return 0;
    }
    printf("|----------------------------------------------------------------------------|\n");
    printf("|\t\t\t\t4.改变学生数据\t\t\t\t     |\n");
    printf("|----------------------------------------------------------------------------|\n");
    p=find_stu(head);//找到指定改变的学生,然后返回该学生指针
    while(p==NULL)//判断更改学号是否存在
    {
        printf("更改学号不存在!\n请重新输入:\n");
        p=find_stu(head);
    }
    printf("%d号学生个人数据为:\n",p->data.number);//显示要更改学生的数据
    printf("\t|---------------------------------------------------------------|\n");
    printf("\t|学号\t|姓名\t|性别\t|随机\t|英语\t|图论\t|平均分\t\t|\n");
    printf("\t|---------------------------------------------------------------|\n");
    printf("\t|%d\t|%s\t|%s\t|%.2f\t|%.2f\t|%.2f\t|%.2f\t\t|\n",p->data.number,p->data.name,p->data.sex,p->data.suiji,p->data.English,p->data.tulun,p->data.average);
    printf("\t|---------------------------------------------------------------|\n");
    temp=p;//暂存更改学生数据的指针
    printf("确认更改该学生数据吗?(1/0):");
    scanf("%d",&n);
    if(n==1)
    {
        printf("|----------------------------------------------------------------------------|\n");
        printf("1.学号      2.姓名      3.性别      4.随机成绩      5.英语成绩      6.图论成绩\n");
        printf("|----------------------------------------------------------------------------|\n");
        printf("请选择更改数据具体序号:");
        scanf("%d",&m);
        switch(m)
        {
        case 1:
            while(1)
            {
                printf("更改学号为:");
                scanf("%d",&p->data.number);
                t=p->data.number;//暂存学号
                p=p->next;//从下一个结点开始判断是否有相同的学号
                while(p->data.number!=t)//判断是否有相同的学号
                {
                    p=p->next;
                    if(p==temp)//查找完一遍回到原位置
                    {
                        flag=1;//无相同学号的标志
                        break;
                    }
                }
                if(flag==1)//不存在相同学号则跳出
                    break;
                else
                {
                    printf("学号已存在!\n请重新更改\n");
                    p=temp;//重新指向原位置
                }
            }
            break;
        case 2:
            printf("更改姓名为:");
            scanf("%s",p->data.name);
            break;
        case 3:
            printf("更改性别为:");
            scanf("%s",p->data.sex);
            break;
        case 4:
            printf("更改随机成绩为:");
            scanf("%f",&p->data.suiji);
            break;
        case 5:
            printf("更改英语成绩为:");
            scanf("%f",&p->data.English);
            break;
        case 6:
            printf("更改图论成绩为:");
            scanf("%f",&p->data.tulun);
            break;
        default:
            printf("输入选择序号错误!\n");
            return 0;
        }
        p->data.average=(p->data.suiji+p->data.English+p->data.tulun)/3;//更新平均分
        printf("更改成功!该学生更改后的个人数据为:\n");//显示更改后的学生数据
        printf("\t|---------------------------------------------------------------|\n");
        printf("\t|学号\t|姓名\t|性别\t|随机\t|英语\t|图论\t|平均分\t\t|\n");
        printf("\t|---------------------------------------------------------------|\n");
        printf("\t|%d\t|%s\t|%s\t|%.2f\t|%.2f\t|%.2f\t|%.2f\t\t|\n",p->data.number,p->data.name,p->data.sex,p->data.suiji,p->data.English,p->data.tulun,p->data.average);
        printf("\t|---------------------------------------------------------------|\n");
    }
    else
        return 0;
}

int del_stu(Node *head)//删除学生数据
{
    int n,m;
    Node *p;
    if(head==NULL)
    {
        printf("学生数据未创建,暂不支持删除!\n");
        return 0;
    }
    printf("|----------------------------------------------------------------------------|\n");
    printf("|\t\t\t\t3.删除学生数据\t\t\t\t     |\n");
    printf("|----------------------------------------------------------------------------|\n");
    p=find_stu(head);//找到指定删除的学生,然后返回该学生指针
    while(p==NULL)//判断指定删除学生是否存在
    {
        printf("删除学号不存在!\n请重新输入:\n");
        p=find_stu(head);
    }
    m=p->data.number;
    printf("%d号学生个人数据为:\n",p->data.number);//在删除前显示要删学生的数据
    printf("\t|---------------------------------------------------------------|\n");
    printf("\t|学号\t|姓名\t|性别\t|随机\t|英语\t|图论\t|平均分\t\t|\n");
    printf("\t|---------------------------------------------------------------|\n");
    printf("\t|%d\t|%s\t|%s\t|%.2f\t|%.2f\t|%.2f\t|%.2f\t\t|\n",p->data.number,p->data.name,p->data.sex,p->data.suiji,p->data.English,p->data.tulun,p->data.average);
    printf("\t|---------------------------------------------------------------|\n");
    printf("确认删除该学生数据吗?(1/0):");
    scanf("%d",&n);
    if(n==1)
    {
        p->prior->next=p->next;
        p->next->prior=p->prior;
        count=count-1;//删除完后学生个数自动减一
        free(p);
        printf("%d号学生数据已删除!\n",m);
    }
    else
        return 0;
}

int add_stu(Node *head)//添加学生数据
{
    int n;
    Node *s,*p,*j;
    s=(Node*)malloc(sizeof(Node));
    if(head==NULL)
    {
        printf("学生数据未创建,暂不支持添加!\n");
        return 0;
    }
    printf("|----------------------------------------------------------------------------|\n");
    printf("|\t\t\t\t2.添加学生数据\t\t\t\t     |\n");
    printf("|----------------------------------------------------------------------------|\n");
    printf("请输入学号:");
    scanf("%d",&s->data.number);
    j=judge(s,head);//判断添加的学号是否和已存在的学号相同
    while(j!=NULL)
    {
        printf("添加学号已存在!\n请重新输入:\n");
        scanf("%d",&s->data.number);
        j=judge(s,head);//重新输入后再次判断
    }
    printf("请输入姓名(汉语):");
    scanf("%s",s->data.name);
    printf("请输入性别(男/女):");
    scanf("%s",s->data.sex);
    printf("请输入随机成绩:");
    scanf("%f",&s->data.suiji);
    printf("请输入图论成绩:");
    scanf("%f",&s->data.tulun);
    printf("请输入英语成绩:");
    scanf("%f",&s->data.English);
    s->data.average=(s->data.suiji+s->data.English+s->data.tulun)/3;
    printf("\n1.在某位学生之前添加该学生数据\t\t2.在某位学生之后添加该学生数据\n");
    printf("\n请选择序号:");
    scanf("%d",&n);
    if(n==1)
    {
        printf("\n请选择在哪位学生之前添加该学生数据:\n");
        p=find_stu(head);//找指定的学生然后返回该学生指针
        while(1)
        {
            if(p==NULL)
            {
                printf("没有该学生!\n请重新输入:\n");
                p=find_stu(head);
            }
            else
                break;
        }
        s->prior=p->prior;
        p->prior->next=s;
        s->next=p;
        p->prior=s;
        count++;//添加完后学生个数自动加一
        printf("添加成功!该学生数据添加在%d号学生之前!\n",p->data.number);
    }
    else
    {
        printf("请选择在哪位学生之后添加该学生数据:\n");
        p=find_stu(head);//找指定的学生然后返回该学生指针
        while(1)
        {
            if(p==NULL)
            {
                printf("没有该学生!\n请重新输入:\n");
                p=find_stu(head);
            }
            else
                break;
        }
        p->next->prior=s;
        s->next=p->next;
        s->prior=p;
        p->next=s;
        count++;//添加完后学生个数自动加一
        printf("添加成功!该学生数据添加在%d号学生之后!\n",p->data.number);
    }
}

Node *creat_stu()//创建学生数据
{
    Node *head,*p,*s,*sp;
    int flag=1;
    head=(Node*)malloc(sizeof(Node));
    p=head;
    printf("|----------------------------------------------------------------------------|\n");
    printf("|\t\t\t\t1.创建学生数据\t\t\t\t     |\n");
    printf("|----------------------------------------------------------------------------|\n");
    while(flag)
    {
        s=(Node*)malloc(sizeof(Node));
        p->next=s;
        s->prior=p;
        p=s;
        printf("请输入学号:");
        scanf("%d",&s->data.number);
        if(count>=1)//从第二个学生开始判断
        {
            sp=judge(s,head);//进入判断是否存在相同学号函数,若存在相同,返回NULL
            while(sp!=NULL)
            {
                printf("输入学号已存在!\n请重新输入:\n");
                scanf("%d",&s->data.number);
                sp=judge(s,head);//重新输入后再次判断
            }
        }
        while(s->data.number<0||s->data.number==0)
        {
            printf("学号必须大于零!\n请重新输入:");
            scanf("%d",&s->data.number);
        }
        printf("请输入姓名(汉语):");
        scanf("%s",s->data.name);
        printf("请输入性别(男/女):");
        scanf("%s",s->data.sex);
        printf("请输入随机成绩:");
        scanf("%f",&s->data.suiji);
        printf("请输入图论成绩:");
        scanf("%f",&s->data.tulun);
        printf("请输入英语成绩:");
        scanf("%f",&s->data.English);
        s->data.average=(s->data.suiji+s->data.English+s->data.tulun)/3;//平均成绩
        count++;//输入完一个学生个数自动加一
        printf("\n是否继续输入数据(1/0):");
        scanf("%d",&flag);
        printf("\n");
    }
    head->prior=s;//连接首尾,构成双循环
    p->next=head;
    printf("创建成功!创建了%d个学生数据!\n",count);
    return head;//返回创建成功后的头指针
}

int main()//主函数
{
    Node *head,*p;
    int flag;
    char ch;
    head=NULL;
    show();
    while(1)
    {
        system("color 3c");
        printf("\n\t\t\t欢迎进入重邮研究生管理系统!\n");//显示主页面
        printf("\t\tWelcome To Postgraduates' System of CQUPT!\n");
        printf("|----------------------------------------------------------------------------|\n");
        printf("|1创建学生数据\t\t\t2添加学生数据\t\t\t3删除学生数据|\n");
        printf("|4改变学生数据\t\t\t5查看学生数据\t\t\t6显示学生数据|\n");
        printf("|0退出程序\t\t\t\t\t\t\t\t     |\n");
        printf("|----------------------------------------------------------------------------|\n");
        printf("\n请您选择操作方式:");
        scanf("%d",&flag);
        switch(flag)
        {
        case 0:system("cls");//退出程序
            printf("\n\n\n\n\n\n\n\n|----------------------------------------------------------------------------|\n");
            printf("|\t\t\t感谢您使用重邮研究生管理系统!\t\t\t     |\n");
            printf("|----------------------------------------------------------------------------|\n");
            return 0;
        case 1:system("cls");
            head=creat_stu();//创建学生数据
            getchar();
            printf("\n按回车键返回主页面:");
            if(ch=getchar())
                system("cls");
            break;
        case 2:system("cls");
            add_stu(head);//添加学生数据
            getchar();
            printf("\n按回车键返回主页面:");
            if(ch=getchar())
                system("cls");
            break;
        case 3:system("cls");
            del_stu(head);//删除学生数据
            getchar();
            printf("\n按回车键返回主页面:");
            if(ch=getchar())
                system("cls");
            break;
        case 4:system("cls");
            change_stu(head);//改变学生数据
            getchar();
            printf("\n按回车键返回主页面:");
            if(ch=getchar())
                system("cls");
            break;
        case 5:system("cls");
            p=find_stu(head);//查看学生数据
            if(p!=NULL)
            {
                printf("\t|---------------------------------------------------------------|\n");
                printf("\t|学号\t|姓名\t|性别\t|随机\t|英语\t|图论\t|平均分\t\t|\n");
                printf("\t|---------------------------------------------------------------|\n");
                printf("\t|%d\t|%s\t|%s\t|%.2f\t|%.2f\t|%.2f\t|%.2f\t\t|\n",p->data.number,p->data.name,p->data.sex,p->data.suiji,p->data.English,p->data.tulun,p->data.average);
                printf("\t|---------------------------------------------------------------|\n");
            }
            else
                printf("没有学生数据!\n");
            getchar();
            printf("\n按回车键返回主页面:");
            if(ch=getchar())
                system("cls");
            break;
        case 6:system("cls");
            print_stu(head);//显示学生数据
            getchar();
            printf("\n按回车键返回主页面:");
            if(ch=getchar())
                system("cls");
            break;  
        default:
            printf("请重新输入序号!\n");//序号输入错误
            break;
        }
    }
}

显示如下:
输入账号密码界面
这里写图片描述
显示菜单界面
这里写图片描述
创建
这里写图片描述
添加
这里写图片描述
删除
这里写图片描述
更改
这里写图片描述
查看
这里写图片描述
显示
这里写图片描述
退出
这里写图片描述

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值