链表实现一个学生信息统计的功能

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

/* 宏定义 */
#define NAMELEN 20
#define ADDRLEN 255
#define MAXAGE 150
#define MINAGE 1
#define MAXSCORE 100
#define MINSCORE 0

/* 定义学生信息*/
typedef struct StdInfo
{
    char    cname[NAMELEN + 1]; /*姓名*/
    unsigned int        nage;       /*年龄*/
    unsigned int        nscore;    /*分数*/
    char    caddr[ADDRLEN + 1];/*地址*/
    struct    StdInfo *next;
}STD_T;

/*************************************************************************
* 函数名  : initList
* 负责人  caibiaoyu
* 创建日期:20130105
* 函数功能:初始化线性表,即置单链表的表头指针为空
* 输入参数:表头指针的地址
* 输出参数:无
* 返回值:    无
* 调用关系:无
* 其    它:
*************************************************************************/
void initList(STD_T **pNode)
{
    *pNode = NULL;
    printf("initList succ.\n");
}

/*************************************************************************
* 函数名  : CreatNode
* 负责人  caibiaoyu
* 创建日期:20130105
* 函数功能:创建保存学生信息的链表
* 输入参数:链表头节点指针, 链表结束的标识
* 输出参数:无
* 返回值:    链表头节点指针
* 调用关系:无
* 其    它:
*************************************************************************/
STD_T *CreatNode(STD_T *phead)
{
    STD_T *p1 = NULL;
    STD_T *p2 = NULL;
    char tmp_name[NAMELEN + 1] = {0};

    while(1)/*循环录入学生信息*/
    {
        /*临时变量存放录入的学生名称*/
        printf("\ninput student name (maxlen:20):");
        scanf("%s", tmp_name);


        if(strlen(tmp_name) > NAMELEN)/*判断录入的名称长度是否超长*/
        {
            printf("input name too long, maxlen is 20!");
            break;
        }
        
        if(0 == strcmp(tmp_name, "end"))/*判断是否录入end*/
        {
            printf("input end!\n");
            break;
        }

        /*其他情况分配内存存储学生信息*/
        p1 = (STD_T *)malloc(sizeof(STD_T));

        if(NULL == p1)/*判断指针是否有效*/
        {
            printf("malloc mem failed.\n");
            break;
        }

        memset(p1, '\0', sizeof(STD_T));/*初始化内存内容*/

        /*开始存储录入的内容*/
        memcpy(p1->cname, tmp_name, NAMELEN + 1);/*姓名*/
        memset(tmp_name, '\0', NAMELEN + 1);/*临时变量初始化,用于下次存储输入的学生名称*/

        printf("input student age(1-150):");/*录入学生年龄*/
        scanf("%d", &p1->nage);

        if(p1->nage < MINAGE || p1->nage > MAXAGE)/*判断年龄范围*/
        {
            printf("input age erro!");
            exit(0);/*此次内存已经分配,如果输入错误,那么直接程序退出由系统回收内存*/
        }

        printf("input student score(0-100):");/*录入学生分数*/
        scanf("%d", &p1->nscore);

        if(p1->nscore < MINSCORE || p1->nscore > MAXSCORE)/*判断分数范围*/
        {
            printf("input score erro!");
            exit(0);/*此次内存已经分配,如果输入错误,那么直接程序退出由系统回收内存*/
        }

        printf("input student addr(maxlen:255):");/*录入学生地址*/
        scanf("%s", p1->caddr);

        if(strlen(p1->caddr) > ADDRLEN)/*判断地址长度*/
        {
            printf("input addr too long, maxlen is 255!");
            exit(0);
        }

        /*节点内容录入完成*/

        if(NULL == phead)/*第一次p1指针交给head*/
        {
            phead = p1;
        }
        else /*其他节点*/
        {
            if(NULL != p2)/*判断指针是否有效*/
            {
                p2->next = p1;
            }
        }
        p2 = p1;/*用p2记录上一个节点的指针*/
    }

    return phead;
}

/*************************************************************************
* 函数名  : GetMaxScoreNode
* 负责人  caibiaoyu
* 创建日期:20130105
* 函数功能:遍历链表,获取最高分节点
* 输入参数:链表头节点指针
* 输出参数:无
* 返回值:    最高分节点的指针
* 调用关系:无
* 其    它:
*************************************************************************/
STD_T *GetMaxScoreNode(STD_T *phead)
{
    STD_T *p = NULL;/*临时指针*/
    STD_T *pmax = NULL;/*最高分节点指针*/
    unsigned int num = 0;
    unsigned int maxscore = 0;/*最高分*/

    if(NULL == phead)/*参数判断*/
    {
        printf("list is null\n");
        exit(0);
    }

    p = phead;
    while(NULL != p)/*遍历链表,寻找最高分节点*/
    {
        if(0 == num)/*头节点*/
        {
            maxscore = p->nscore;
            pmax = p;
        }
        num++;

        p = p->next;
        if(NULL == p)/*退出循环条件*/
        {
            break;
        }

        if(p->nscore >= maxscore)/*比较节点分数值*/
        {
            maxscore = p->nscore;
            pmax = p;
        }
    }

    return pmax;
}

/*************************************************************************
* 函数名  : GetMaxScoreNode
* 负责人  caibiaoyu
* 创建日期:20130105
* 函数功能:遍历链表,获取最低分节点
* 输入参数:链表头节点指针
* 输出参数:无
* 返回值:    最低分节点的指针
* 调用关系:无
* 其    它:
*************************************************************************/
STD_T *GetMinScoreNode(STD_T *phead)
{
    STD_T *p = NULL;/*临时指针*/
    STD_T *pmin = NULL;/*最高分节点指针*/
    unsigned int num = 0;
    unsigned int minscore = 0;/*最高分*/

    if(NULL == phead)/*参数判断*/
    {
        printf("list is null\n");
        exit(0);
    }

    p = phead;
    while(NULL != p)/*遍历链表,寻找最低分节点*/
    {
        if(0 == num)/*头节点*/
        {
            minscore = p->nscore;
            pmin = p;
        }
        num++;

        p = p->next;
        if(NULL == p)/*退出循环条件*/
        {
            break;
        }

        if(p->nscore <= minscore)/*比较节点分数值*/
        {
            minscore = p->nscore;
            pmin = p;
        }
    }

    return pmin;
}

/*************************************************************************
* 函数名  : GetAvgScoreNode
* 负责人  caibiaoyu
* 创建日期:20130105
* 函数功能:遍历链表,获取学生成绩的平均值
* 输入参数:链表头节点指针
* 输出参数:无
* 返回值:    返回学生成绩的平均值
* 调用关系:无
* 其    它:
*************************************************************************/
unsigned int GetAvgScoreNode(STD_T *phead)
{
    STD_T *p = NULL;
    unsigned int num = 0;
    unsigned int avgscore = 0;/*平均分*/
    unsigned int totalscore = 0;/*分数和*/

    if(NULL == phead)/*参数判断*/
    {
        printf("list is null\n");
        exit(0);
    }
    
    p = phead;
    for(num = 0; NULL != p; num++)/*循环录入*/
    {
        totalscore = totalscore + p->nscore;
        
        p = p->next;
        if(NULL == p)/*退出循环条件*/
        {
            break;
        }    
    }
    avgscore = totalscore/num;/*计算学生分数平均值*/

    return avgscore;
}

/*************************************************************************
* 函数名  : PrintStatInfo
* 负责人  caibiaoyu
* 创建日期:20130105
* 函数功能:遍历链表,打印统计信息
* 输入参数:链表头节点指针, 链表结束的标识
* 输出参数:无
* 返回值:    无
* 调用关系:无
* 其    它:
*************************************************************************/
void PrintStatInfo(STD_T *phead)
{
    STD_T *pmin = NULL;/*最低分节点指针*/
    STD_T *pmax = NULL;/*最高分节点指针*/
    unsigned int avgscore = 0;/*平均分*/

    pmin = GetMinScoreNode(phead);
    if(NULL == pmin)/*检查函数返回的值*/
    {
        printf("get statinfo failed.\n");
        return;
    }

    pmax = GetMaxScoreNode(phead);
    if(NULL == pmax)/*检查函数返回的值*/
    {
        printf("get statinfo failed.\n");
        return;
    }
    avgscore = GetAvgScoreNode(phead);
    if(MINSCORE > avgscore || MAXSCORE < avgscore)/*检查函数返回的值*/
    {
        printf("get statinfo failed.\n");
    }

    printf("statinfo: maxscore[%d] minscore[%d] avgscore[%d]\n", pmax->nscore, pmin->nscore, avgscore);/*打印统计信息*/
}

/*************************************************************************
* 函数名  : FreeNode
* 负责人  caibiaoyu
* 创建日期:20130105
* 函数功能:释放指定节点的内存
* 输入参数:需要释放的链表节点指针
* 输出参数:无
* 返回值:    无
* 调用关系:无
* 其    它:
*************************************************************************/
void FreeNode(STD_T *pfreenode)
{
    if(NULL == pfreenode)/*参数判断*/
    {
        printf("FreeNode failed.\n");
    }

    free(pfreenode);
    pfreenode = NULL;
}

/*************************************************************************
* 函数名  : DeleNode
* 负责人  caibiaoyu
* 创建日期:20130105
* 函数功能:删除指定的链表节点,释放该节点的内存
* 输入参数:链表的头指针;
            需要删除的链表节点指针
* 输出参数:无
* 返回值:    链表头指针;
* 调用关系:无
* 其    它:
*************************************************************************/
STD_T *DeleNode(STD_T *phead, STD_T *pdelnode)
{
    STD_T *p = NULL;/*临时指针*/
    STD_T *pcur = NULL;/*当前节点指针*/
    STD_T *ppre = NULL;/*前一个节点指针*/
    STD_T *pback = NULL;/*后一个节点指针*/

    if(NULL == phead || NULL == pdelnode)/*参数校验*/
    {
        printf("DeleNode failed.\n");
        return NULL;
    }

    p = phead;
    while(NULL != p)/*遍历链表*/
    {
        if(phead == pdelnode)/*要删除的就是头结点*/
        {
            phead = p->next;
            free(pdelnode);
            pdelnode = NULL;
            break;
        }

        if(p == phead)/*判断是否是头节点*/
        {
            ppre = NULL;    
        }
        else/*其他节点*/
        {
            ppre = pcur;    
        }
        
        pcur = p;
        pback = p->next;

        if(pcur == pdelnode)/*判断是否到删除节点*/
        {
            if(NULL != ppre)/*判断参数有效性*/
            {
                ppre->next = pback;
            }
            
            free(pdelnode);
            pdelnode = NULL;
            break;
        }

        p = p->next;
    }

    return phead;
}

/*************************************************************************
* 函数名  : SortInfo
* 负责人  caibiaoyu
* 创建日期:20130105
* 函数功能:按照学生成绩降序排列学生信息
* 输入参数:链表头节点指针, 链表结束的标识
* 输出参数:无
* 返回值:    无
* 调用关系:无
* 其    它:
*************************************************************************/
void SortInfo(STD_T *phead)
{
    STD_T *pmax = NULL;
    unsigned int iline = 1;

    while (NULL != phead)/*循环遍历*/
    {
        pmax = GetMaxScoreNode(phead);
        if(NULL != pmax)/*判断参数是否有效*/
        {
        printf("line[%d], name[%s], age[%d], score[%d], addr[%s]\n",
            iline++, pmax->cname, pmax->nage, pmax->nscore, pmax->caddr);
        }        
        phead = DeleNode(phead, pmax);
    }
}

/*************************************************************************
* 函数名  : main
* 负责人  caibiaoyu
* 创建日期:20130104
* 函数功能:接收键盘输入 多个学生的信息 包括  name (名字,字符串),
                age(正整数),score(分数,正整数),address(地址 字符串)
* 输入参数:无
* 输出参数:无
* 返回值:    无         
* 调用关系:无
* 其    它:
*************************************************************************/
void main()
{
    STD_T *head = NULL;
    
    initList(&head);
    head = CreatNode(head);
    PrintStatInfo(head);
    SortInfo(head);
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值