双向链表的学生管理系统

直接上源码

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

#define RD_ID  (1<<0)
#define RD_NAME (1<<1)
#define RD_SCORE (1<<2)

struct student        //描述一个学生的属性
{
    int ID;
    char name[10];
    float score;
};

struct node     //创建链表的节点数据结构
{
    struct student data;
    struct node *prior;
    struct node *next;
};
void GetInfo(struct student *p,unsigned char flag);
int menu(void);                    //菜单
int add(struct node *p);          //添加
int all_printf(struct node *p);  //打印所有学生信息
int delete(struct node *p);     //删除
int find(struct node *p);      //查找
int change(struct node *p);   //修改
int quit(void);              //退出
struct node *head = NULL;   //指向头节点的指针变量

int main()
{
    int num;
    while(1)
    {
    num = menu();
    switch(num)
    {
        case 1:add(head);break;
        case 2:delete(head);break;
        case 3:change(head);break;
        case 4:find(head);break;
        case 5:all_printf(head);break;
        case 6:quit();return 0;
    }
    }

}


int menu(void)
{
    int num;
    printf("\t\t*****欢迎进入学生管理系统*****\n");
    printf("\t\t*****    1 添加学生    *****  \n");
    printf("\t\t*****    2 删除学生    ***** \n");
    printf("\t\t*****    3 修改学生    ***** \n");
    printf("\t\t*****    4 查找学生    ***** \n");
    printf("\t\t*****   5 打印所有信息  ***** \n");
    printf("\t\t*****   6 退出学生系统  ***** \n");
    printf("请输入选项:");
    scanf("%d",&num);
    return num;
}

int add(struct node *p)
{
    //创建一个结点,使用new指向这个结点
    struct node *new = malloc(sizeof(struct node));
    //对该结点数据域进行初始化
    GetInfo(&new->data,RD_ID|RD_NAME|RD_SCORE);
    //对该结点指针域进行初始化
    new->prior = NULL;
    new->next = NULL;
    //把新的结点插入到链表
    if(head == NULL)    //如果链表为空
    {
        head = new;
        return 0;
    }
    while(p != NULL)   //链表不为空
    {
        if(head->data.ID > new->data.ID)  
        //如果头结点学号大于新结点学号,那就把新结点放在头结点前面
        {
            head->prior = new;
            new->next = head;
            head = new;
            return 0;
        }
        if(p->data.ID < new->data.ID)
        //如果头结点学号小于新结点学号,那就把新结点放在后面
        {
            if(p->next == NULL)  //插入表尾
            {
                new->prior = p;  
                p->next = new;
            }
            else if(p->next->data.ID > new->data.ID)  //中间插入
            {
                new->prior = p;
                new->next = p->next;
                p->next->prior = new;
                p->next = new;
                return 0;
            }
        }
        p = p->next;
    }
}


int delete(struct node *p)
{
    if(p == NULL)
    {
        return 1;//链表为空
    }
    struct student temp = {0};//保存要删除的信息
    GetInfo(&temp,RD_ID);     //输入要删除的学号
    struct node *del = NULL;  //保存要删除结点的地址
    while(p != NULL)
    {
        if(p->data.ID == temp.ID)
        del = p; //保存要删除结点的地址
        {
            if(del->prior == NULL && del->next == NULL)//只有一个结点
            {
                head = NULL;
                free(del);
                return 0;
            }
            if(del->prior != NULL)  //中间结点
                del->prior->next = del->next;
            else  //删除结点为第一个结点
            {
                del->next->prior = NULL;  
                head = del->next;    //头指针指向del下一个结点
            }
            if(del->next != NULL)   //如果删除结点后面不为空
                del->next->prior = del->prior;  //把删除结点后面结点的地址给del前面
           else  //del指向最后一个结点
           {
                del->prior->next = NULL;  //把del指向的前一个结点的next赋为空
           }
           free(del);
           printf("删除成功\n");
           return 0;
        }
        p = p->next;
    }
    printf("查无此人\n");
}

int find(struct node *p)
{
    struct student temp = {0};
    GetInfo(&temp,RD_ID);
    while(p != NULL)
    {
        if(p->data.ID == temp.ID)
        {
            printf("此人信息如下\n");
            printf("%d\t",p->data.ID);
            printf("%s\t",p->data.name);
            printf("%f\n",p->data.score);
            return 0;
        }
        p = p->next;
    }
    printf("未找到此人\n");
    return 1;
}


int change(struct node *p)
{
    struct student temp = {0};
    GetInfo(&temp,RD_ID);
    while(p != NULL)
    {
        if(p->data.ID == temp.ID)
        {
            GetInfo(&temp,RD_ID|RD_NAME|RD_SCORE);
            p->data = temp;
            printf("修改成功\n");
            return 0;
        }
        p = p->next;
    }
    printf("查无此人\n");
}



int quit(void)
{
    return 0;
}



int all_printf(struct node *p)        //打印所有学生信息
{
    printf("打印所有学生信息操作……\n");
    printf("学号\t姓名\t成绩\n");
    while(p != NULL)
    {
        printf("%d\t",p->data.ID);
        printf("%s\t",p->data.name);
        printf("%f\n",p->data.score);
        p = p->next;
    }
}



/*
flag = 相应的选项是否允许输入
[0]位 -- no_flag    1--允许输入 0 -- 不允许输入
[1]位 -- name_flag  1--允许输入 0 -- 不允许输入
[2]位 -- sex_flag   1--允许输入 0 -- 不允许输入
*/
void GetInfo(struct student *p,unsigned char flag)
{
    if(flag & (1<<0))
    {
        printf("请输入学号:");
        scanf("%d",&p->ID);
    }
    if(flag & (1<<1))
    {
        printf("请输入姓名:");
        scanf("%s",p->name);
    }
    if(flag &(1<<2))
    {
        printf("请输入成绩:");
        scanf("%f",&p->score);
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值