x072816 发表于 2015-6-20 13:51:34

单链表构造的学生健康程序

#include <string.h>
#include <ctype.h>
#include <malloc.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <math.h>
#include <process.h>

//函数结果状态
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
typedef int Status;//STATUS 是函数的类型,其值是函数结果状态代码,如OK等
typedef int Boolean;//Boolean是布尔类型,其值是TRUE或FALSE

#define NAMELEN 8//姓名最大长度
#define CLASSLEN 4//班级名最大长度
#define N 4//student记录的个数

typedef struct stud//记录的结构
{
      char name;
      long num;
      char sex;
      int age;
      char Class;
      int health;
}stud;
typedefstud ElemType;//链表结点元素类型为结构体

char sta ={"健康","一般","神经衰弱"};//健康状况
FILE *fp;

typedef struct LNode
{
    ElemType data;            //单链表中的数据域   
    struct LNode *next;          //单链表的指针域   
}LNode,*LinkList;
/********************************************************************************/
//单链表的初始化
//函数要求采用地址调用,才能改变主函数中的值,动态分配内存
Status InitList(LinkList *L)
{
      //构造一个空的单链表
    *L = (LinkList )malloc(sizeof(LNode));   //申请结点空间   
    if(*L == NULL)                     //判断是否有足够的内存空间   
      printf("申请内存空间失败/n");
    (*L)->next = NULL;                  //将next设置为NULL,初始长度为0的单链表
      return OK;
}

/********************************************************************************/
//初始条件单链表已经讯在
//操作结果依次对L的每一个数据元素调用函数vi(),一但调用失败
//则是操作失败,vi()形参为指针,表示可通过调用函数改变元素的值
Status ListTraverse(LinkList L,void(*vi)(ElemType ))
{
      LinkList p = L->next;
      while(p)
      {
                vi(p->data);
                p = p->next;
      }
   printf("\n");
         return OK;
}
/********************************************************************************/
void Print(ElemType e)
{
      //显示记录e的内容
      printf("%-8s %6ld", e.name,e.num);
      if(e.sex == 'm')
          printf(" 男");
      else
          printf(" 女");
      printf("%5d %-4s",e.age,e.Class);
      printf("%9s\n",sta);         
}
/********************************************************************************/
//初始条件:按非降序排列的顺序线性表L已存在
// 操作结果:在L中按非降序插入新的数据元素e,L的长度加1
void InsertAscend(LinkList L,ElemType e)
{
      LinkList q = L, p = L->next;
      LinkList s = (LinkList )malloc(sizeof(LNode));
      if(!s)
      {
          printf("分配内存不成功!");
          exit(0);
    }
      s->data = e;
      while(p && (e.num > p->data.num))
      {
                q = p;
                p = p->next;
      }
      q->next = s;
      s->next = p;      
}

/********************************************************************************/
void ReadIn( stud *e)
{
      //由键盘输入结点信息
      printf("请输入姓名(<=%d个字符):",NAMELEN);
      scanf("%s",e->name);
      printf("请输入学号:");
      scanf("%ld",&e->num);
      printf("请输入性别(m:男f:女)");
      scanf("%*c%c",&e->sex);
      printf("请输入年龄:");
      scanf("%d",&e->age);
      printf("请输入班级(<=%d个字符)",CLASSLEN);
      scanf("%s",e->Class);
      printf("请输入健康状况(0:%s 1:%s 2:%s):",sta,sta,sta);
      scanf("%d",&e->health);
}
/********************************************************************************/
void WriteToFile( stud e)
{
      //将结点信息写入fp指定的文件中
      fwrite(&e,sizeof(stud),1,fp);
}
/********************************************************************************/
Status ReadFromFile(stud e)
{
      //由fp指定的文件读取结点信息到e
      int i ;
      i = fread(&e,sizeof(stud),1,fp);
      if(i == 1) //读取文件成功
          return OK;
      else
          return FALSE;
}
/********************************************************************************/
Status FindFromNum(LinkList L,long num,LinkList *p,LinkList *q)
{
      //查找表中学号为num的结点,如果找到,q指向此结点,p指向q的前驱
      //并返回TRUE,如果无此元素,则返回FALSE
      p = &L;
      while(p)
      {
                *q = (*p)->next;
                if(*q && (*q)->data.num == num)
                {
                   return TRUE;
            }
            if(*q && (*q)->data.num > num)//因为是按学号非降序排列
                  break;
                *p = *q;
      }
      return FALSE;
}
/********************************************************************************/
Status FindFromName(LinkList L,char name[],LinkList p,LinkList q)
{
      //查找表中姓名为name的结点,如果找到,q指向此结点,p指向q的前驱
      //并返回TRUE,如果无此元素,则返回FALSE
      p = L;
      while(p)
      {
                q = p->next;
                if(q && !strcmp(q->data.name , name))//因为是按学号非降序排列
                  return TRUE;
                p = q;
      }
      return FALSE;
}
/********************************************************************************/
Status DeleteElemNum(LinkList L,long num)
{
      //删除表中学号为num的元素,并返回TRUE,如果无此元素,则返回FALSE
      LinkList p,q;
      if(FindFromNum(L, num, &p, &q))//找到此结点,且q指向该结点,p指向其前驱
    {
            p->next = q->next;
                free(q);
                return TRUE;
    }
      return FALSE;         
}
/********************************************************************************/
Status DeleteElemName(LinkList L,char name[])
{
      //删除表中姓名为name的元素,并返回TRUE,如果无此元素,则返回FALSE
      LinkList p,q;
      if(FindFromName(L,name,p,q))//找到此结点,且q指向该结点,p指向其前驱
    {
            p->next = q->next;
                free(q);
                return TRUE;
    }
      return FALSE;         
}
/********************************************************************************/
void Modify(ElemType e)
{
      //修改结点内容
      char s;
      Print(e); //显示原内容
      printf("请输入待修改项的内容,不修改的项按回车键保持原值:\n");
      
      printf("请输入姓名(<=%d个字符):",NAMELEN);
      gets(s);
      if(strlen(s))
         strcpy(e.name,s);
      printf("请输入学号:");
      gets(s);
      if(strlen(s))
         e.num = atol(s);
      printf("请输入性别(m:男f:女)");
      gets(s);
      if(strlen(s))
          e.sex = s;
      printf("请输入年龄:");
      gets(s);
      if(strlen(s))
         e.age = atol(s);
      printf("请输入班级(<=%d个字符)",CLASSLEN);
      gets(s);
      if(strlen(s))
         strcpy(e.Class,s);
      printf("请输入健康状况(0:%s 1:%s 2:%s):",sta,sta,sta);
      gets(s);
      if(strlen(s))
         e.health = atol(s);//修改完毕
}
/********************************************************************************/
/********************************************************************************/
int main(void)
{   //表的初始记录
      ElemType student = {{"王小林",790631,'m',18,"计91",0},
                               {"刘建平",790633,'m',21,"计91",0},
                               {"陈红",790632,'f',20,"计91",1},
                               {"张立立",790634,'m',17,"计91",2}};
      
      int i=0,j=0,flag =1;
      long num;
      char filename,name;
      ElemType e;
      LinkList T,q,p;
      InitList(&T);
      while(flag)
      {
                printf("1:将结构体数组student中的记录按学号非降序插入链表\n");
                printf("2:将文件中的记录按学号非降序插入链表\n");
                printf("3:键盘输入新纪录,并将其按学号非降序插入链表\n");
                printf("4:删除链表中第一个有给定学号的记录\n");
                printf("5:删除链表中第一个有给定姓名的记录\n");
                printf("6:修改链表中第一个有给定学号的记录\n");
                printf("7:修改链表中第一个有给定姓名的记录\n");
                printf("8:查找链表中第一个有给定学号的记录\n");
                printf("9:查找链表中第一个有给定姓名的记录\n");
                printf("10:显示所有记录\n11:将链表中所有记录存入文件\n12:结束\n");
                printf("请选择操作命令:");
                scanf("%d",&i);
                switch(i)
                {
                        case 1:
                        for(j = 0; j < N; j++)
                   InsertAscend(T,student);
                  
                              break;

                        case 2:
                              printf("请输入文件名:");
                              scanf("%s",filename);
                              if((fp = fopen(filename,"rb")) == NULL)
                                 printf("打开文件失败!\n");
                              else
                              {
                                  while(ReadFromFile(e))
                                    InsertAscend(T,e);
                              fclose(fp);
                            }
                            break;
                  case 3:
                            ReadIn(&e);
                            InsertAscend(T,e);
                            break;
                  case 4:
                            printf("请输入待删除记录的学号:");
                              scanf("%ld",&num);
                              if(!DeleteElemNum(T,num))
                                 printf("没有学号为%ld的记录\n",num);
                              ListTraverse(T,Print);
                        break;
                  case 5:
                            printf("请输入待删除记录的姓名:");
                              scanf("%s",name);
                              if(!DeleteElemName(T,name))
                                 printf("没有姓名为%s的记录\n",name);
                            break;
                  case 6:
                            printf("请输入待修改记录的学号:");
                              scanf("%ld%*c",&num);//%*c吃掉回车符
                              if(!FindFromNum(T,num,&p,&q))
                                 printf("没有学号为%ld的记录\n",num);
                              else
                              {
                                        Modify(q->data);
                                        if(q->data.num != num)//学号被修改
                                        {
                                                p->next = q->next;//把q所指的结点从L中删除
                                                InsertAscend(T,q->data);//吧元素插入L
                                                free(q);//删除q
                                        }
                              }
                            break;
                  case 7:
                            printf("请输入待修改记录的姓名:");
                              scanf("%ld%*c",name);//%*c吃掉回车符
                              if(!FindFromName(T,name,p,q))
                                 printf("没有姓名为%s的记录\n",num);
                              else
                              {
                                        num = q->data.num; //把学号存入num
                                        Modify(q->data);
                                        if(q->data.num != num)//学号被修改
                                        {
                                                p->next = q->next;//把q所指的结点从L中删除
                                                InsertAscend(T,q->data);//吧元素插入L
                                                free(q);//删除q
                                        }
                              }
                            break;
                  case 8:
                            printf("请输入待查找记录的学号:");
                              scanf("%ld",&num);
                              if(!FindFromNum(T,num,&p,&q))
                                 printf("没有学号为%ld的记录\n",num);
                              else
                                  Print(q->data);
                            break;
                  case 9:
                            printf("请输入待查找记录的姓名:");
                              scanf("%s",name);
                              if(!FindFromName(T,name,p,q))
                                 printf("没有姓名为%s的记录\n",name);
                              else
                                  Print(q->data);
                            break;
                  case 10:
                            printf("   姓名       学号 性别 年龄 班级 健康状况\n");
                            ListTraverse(T,Print);
                            break;
                  case 11:
                            printf("请输入文件名:");
                              scanf("%s",filename);
                              if((fp = fopen(filename,"rb")) == NULL)
                                 printf("打开文件失败!\n");
                              else
                                 ListTraverse(T,WriteToFile);
                              fclose(fp);
                            break;

                  case 12:
                            flag = 0;
                            break;            
                }
      }
}
主页面的四五六七选项都不对,求解决?
1:将结构体数组student中的记录按学号非降序插入链表
2:将文件中的记录按学号非降序插入链表
3:键盘输入新纪录,并将其按学号非降序插入链表
4:删除链表中第一个有给定学号的记录
5:删除链表中第一个有给定姓名的记录
6:修改链表中第一个有给定学号的记录
7:修改链表中第一个有给定姓名的记录
8:查找链表中第一个有给定学号的记录
9:查找链表中第一个有给定姓名的记录
10:显示所有记录
11:将链表中所有记录存入文件
12:结束
请选择操作命令:1
1:将结构体数组student中的记录按学号非降序插入链表
2:将文件中的记录按学号非降序插入链表
3:键盘输入新纪录,并将其按学号非降序插入链表
4:删除链表中第一个有给定学号的记录
5:删除链表中第一个有给定姓名的记录
6:修改链表中第一个有给定学号的记录
7:修改链表中第一个有给定姓名的记录
8:查找链表中第一个有给定学号的记录
9:查找链表中第一个有给定姓名的记录
10:显示所有记录
11:将链表中所有记录存入文件
12:结束
请选择操作命令:4

这个时候发现没有删除记录

牡丹花下死做鬼 发表于 2015-6-21 13:18:40

你贴这么一堆代码让我慢慢来 大家来找茬???

858418616 发表于 2015-6-21 15:15:55

我是新手,表示看不懂啦!

彼岸花316 发表于 2015-8-19 15:59:15

额,{:1_1:}{:1_1:}

dabaojian 发表于 2015-8-20 17:18:55

好长啊

leonardzzy 发表于 2015-8-26 22:13:30

太长了 不好看啊
页: [1]
查看完整版本: 单链表构造的学生健康程序