单链表插入问题
我照着网上程序编了一个单链表的学生健康统计的c语言程序,但进行插入操作,出现问题。#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(LinkList)); //申请结点空间
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)//因为是按学号非降序排列
break;
if(q && q->data.num == num)
return TRUE;
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);
ListTraverse(T,Print);
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);
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;
}
}
} 上面程序我是用devc++调试过,调试的时候没有问题,但是直接运行就出现了刚才的问题 怎么我用cfree运行了一下,好像没问题的样子。
页:
[1]