鱼C论坛

 找回密码
 立即注册
查看: 3060|回复: 2

[技术交流] 单链表插入问题

[复制链接]
发表于 2015-6-15 22:10:43 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
我照着网上程序编了一个单链表的学生健康统计的c语言程序,但进行插入操作,出现问题。
QQ截图20150615220356.png
#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[NAMELEN + 1];
        long num;
        char sex;
        int age;
        char Class[CLASSLEN + 1];
        int health;
}stud;
typedef  stud ElemType;//链表结点元素类型为结构体

char sta[3][9] ={"健康","一般","神经衰弱"};//健康状况
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[e.health]);         
}
/********************************************************************************/
//初始条件:按非降序排列的顺序线性表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[0],sta[1],sta[2]);
        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[80];
        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[0];
        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[0],sta[1],sta[2]);
        gets(s);
        if(strlen(s))
           e.health = atol(s);//修改完毕
}
/********************************************************************************/
/********************************************************************************/
int main(void)
{   //表的初始记录
        ElemType student[N] = {{"王小林",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[13],name[NAMELEN+1];
        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[j]);
                   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;           
                }
        }
}[/code]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-6-15 22:13:57 | 显示全部楼层
上面程序我是用devc++调试过,调试的时候没有问题,但是直接运行就出现了刚才的问题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-6-17 18:01:46 | 显示全部楼层
怎么我用cfree运行了一下,好像没问题的样子。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-12 12:05

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表