关于C语言链表的一些问题,代码怎么都运行不成功跪求大神指点

下面代码主要实现链表的创建,插入,删除,并且能将两个年龄递增链表进行合并成递减链表

然而在插入和删除操作中gets函数无法起作用,strcmp函数也出现位置冲突报错。。功力不足实在解决不了。。跪求大神解答。。(感觉自己写的东西除了上面两个错误应该还有,但是因为位置冲突问题就只能编译到那个地方无法进行下去。。我肉眼实在找不出来。。

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

int a[10]={0};
int c[10]={0};
char b[100][10];
char d[100][10];

typedef struct stuInfo {
     char  stuName[10];/*学生姓名*/
      int    age; /*年龄*/
 } ElemType;

typedef struct node {
     ElemType  data;
     struct  node  *next;
}LNode,*ListPtr;/*定义结构*/


ListPtr List_Init(int a[],char b[][10],int n){/*链表载入数据*/
   LNode *s,*h;
   int i;
   h=NULL;
   h=(LNode*)malloc(sizeof(LNode));
   h->data.age=0;
   memset(h->data.stuName,0,10*sizeof(char));
   h->next=NULL;
   for(i=n-1;i>=0;i--)
   {
       s=(LNode*)malloc(sizeof(LNode));/*分配内存*/
       memset(s->data.stuName,0,10*sizeof(char));
       s->data.age=a[i];/*把年龄载入*/
       strcpy(s->data.stuName,b[i]);/*把名字载入*/
       s->next=h->next;/*新的结点指向头节点的下一个结点*/
       h->next=s;/*头结点指向新的结点*/
   }
   return h;
}

ListPtr List_Insert (ListPtr h, ElemType x){/*结点插入*/
    LNode *s;

    s=(LNode*)malloc(sizeof(LNode));

    s->data.age=x.age;
    strcpy(s->data.stuName,x.stuName);/*分配空间结点载入*/
    s->next=h->next;/*新的结点指向前一个结点的后一个结点*/
    h->next=s;/*前一个结点指向新结点*/

    return h;

}
void List_Destroy(ListPtr h,ListPtr L){
    LNode *s,*p;
    s=L->next;/*指向第一个结点*/
    p=s;
    while(s){/*寻找所要删除的数据结点的前一个结点*/
        if(s->data.age==h->data.age&&strcmp(s->data.stuName,h->data.stuName)==0)
            break;
        p=s;
        s=s->next;
    }
    s=p->next;/*s指定要删除的结点*/
    p->next=s->next;/*前一个结点指向所要删除结点的后一个结点*/
    free(s);

}
ListPtr List_Merge(ListPtr La, ListPtr Lb){/*链表变换,使递增链表变为递减链表,并去重*/
    LNode  *s, *pa, *pb;
    pa=La->next;
    pb=Lb->next;/*各指向两个链表的头结点*/
    La->next=NULL;
    while(pa!=NULL&&pb!=NULL){
        if(pa->data.age<=pb->data.age){
            s=pa->next;
            pa->next=La->next;
            La->next=pa;
            pa=s;/*如果pa指向的年龄比pb的小则保留并逆置,pa指针指向下一个数据*/
            if(strcmp(pa->data.stuName,pb->data.stuName)==0){
                pb=pb->next;/*如果pa和pb所指的是同一个人,则pb也指向下一个数据,避免重复*/
            }
        }
        else{
            s=pb->next;
            pb->next=La->next;
            La->next=pb;
            pb=s;
        }/*如果pb指向的年龄比pa的小,则插入到La链表中*/
    }
    while(pa!=NULL){
        s=pa->next;
        pa->next=La->next;
        La->next=pa;
        pa=s;}/*处理La未处理的数据*/
    while(pb!=NULL){
        s=pb->next;
        pb->next=La->next;
        La->next=pb;
        pb=s;}/*处理Lb未处理的数据*/
    Lb->next=NULL;
    free(Lb);/*释放Lb*/
}
void OutPut(ListPtr La){/*输出链表*/
    LNode *s;
    s=La->next;
    while(s){
        printf("%s\t%d\n",s->data.stuName, s->data.age);
    }
}
int  main(){
    ElemType x;
    int n,i,j;
    ListPtr La=NULL, Lb=NULL;
    LNode *p,*r;
    for(i=0;i<10;i++){
        memset(b[i],0,10*sizeof(char));
        memset(d[i],0,10*sizeof(char));
    }/*初始化字符串数组*/
    strcpy(b[0],"Levis");a[0]=22;
    strcpy(b[1],"Adam");a[1]=23;
    strcpy(b[2],"Lord");a[2]=26;
    strcpy(b[3],"Fred");a[3]=28;
    strcpy(b[4],"May");a[4]=30;
    strcpy(b[5],"York");a[5]=35;
    La=List_Init(a, b, 6);
    /*La数据载入*/
    strcpy(d[0],"Yuki");c[0]=19;
    strcpy(d[1],"Soraru");c[1]=27;
    strcpy(d[2],"Katin");c[2]=29;
    strcpy(d[3],"Sinsan");c[3]=31;
    strcpy(d[4],"York");c[4]=35;
    Lb=List_Init(c,  d, 5);
    /*Lb数据载入*/
    printf("choose operation: 1. insert 2. delete 3.nothing: ");
    scanf("%d",&j);
    if(j==1){
    printf("enter the student's name you want to insert:");/*插入数据操作*/
    gets(x.stuName);
    printf("enter the student's age:");
    scanf("%d",&x.age);
    p=La->next;
    while(p){/*查找La中是否有此人*/
        if(strcmp(p->data.stuName,x.stuName)==0)
            break;
        p=p->next;
    }
    if(p=NULL){/*如果没则寻找插入位置*/
        p=La->next;r=p;
        while (p){
        if(x.age<=p->data.age)
            break;
        r=p;
        p=p->next;/*找到比它大的值后,r记录此结点的前一个结点*/
    }
        List_Insert (r, x);/*在r后插入此数据结点*/
}
    else{
        p=Lb->next;/*La中已有此人,则查找Lb*/
    while(p){
        if(strcmp(p->data.stuName,x.stuName)==0)
            break;
        p=p->next;
    }

    if(p=NULL){
        p=Lb->next;r=p;
    while (p){
        if(x.age<=p->data.age)
            break;
        r=p;
        p=p->next;
    }
    List_Insert (r, x);}}/*同La*/
    if(p!=NULL){
        printf("inserted fail");}/*如果两链表中已有此人,则表示插入失败*/
    } 

    if(j==2){
    printf("enter the student's name you want to delete:");/*进行删除操作*/
    gets(x.stuName);
    printf("which lianbiao do you choose, if La, input 1;Lb,input 2:");/*选择要插入的链表*/
    scanf("%d",&i);
    if(i==1){
    p=La->next;
    while(p){
        if(strcmp(p->data.stuName,x.stuName)==0)/*查找La中此人的位置*/
            break;
        p=p->next;/*移动到下一个结点*/
    }
    if(p!=NULL){
    List_Destroy(p,La);}
    else {printf("查无此人");}/*移动到下一个结点*/
    }
    if(i==2){
    p=Lb->next;
    while(p){
        if(strcmp(p->data.stuName,x.stuName)==0)
            break;
        p=p->next;
    }
    if(p!=NULL){List_Destroy(p,Lb);}
    else {printf("查无此人");}}/*同La*/
 }

    printf("now ranking......\n");/*显示递增合并为递减的信息*/
    List_Merge(La, Lb);

   OutPut(La);/*输出函数*/

    return 0;
}

然而在插入和删除操作中gets函数无法起作用,strcmp函数也出现位置冲突报错。。功力不足实在解决不了。。跪求大神解答。。(感觉自己写的东西除了上面两个错误应该还有,但是因为位置冲突问题就只能编译到那个地方无法进行下去。。我肉眼实在找不出来。。

c

9个回答

http://blog.csdn.net/zx824/article/details/6859930
额,这个你可以看看上面的博客,写的很详细。
在linux和windows下面有点不太一样,你是什么平台呢?

错误很多,逆序后面加上return,gets换成scanf。。。。。。。。。

这么简单的功能,写的这么混乱,真是醉了

p=NULL之后再p->next是几个意思?楼上不对,这代码linux和windows通用的

这个函数

ListPtr List_Merge(ListPtr La, ListPtr Lb)

返回值类型应该改为void

这段代码造成了程序停止

 while(pa!=NULL&&pb!=NULL){
        _if(pa->data.age<=pb->data.age){_
            s=pa->next;
            pa->next=La->next;
            La->next=pa;
            pa=s;/*如果pa指向的年龄比pb的小则保留并逆置,pa指针指向下一个数据*/
       _     if(strcmp(pa->data.stuName,pb->data.stuName)==0){
                pb=pb->next;/*如果pa和pb所指的是同一个人,则pb也指向下一个数据,避免重复*/
            }_
        }
        else{
            s=pb->next;
            pb->next=La->next;
            La->next=pb;
            pb=s;
        }/*如果pb指向的年龄比pa的小,则插入到La链表中*/
    }

改成这样就可以了。

 while(pa!=NULL&&pb!=NULL){
       _ if(pa->data.age<=pb->data.age){
            if(strcmp(pa->data.stuName,pb->data.stuName)==0){
                pb=pb->next;/*如果pa和pb所指的是同一个人,则pb也指向下一个数据,避免重复*/
            }_
            s=pa->next;
            pa->next=La->next;
            La->next=pa;
            pa=s;/*如果pa指向的年龄比pb的小则保留并逆置,pa指针指向下一个数据*/
        }
        else{
            s=pb->next;
            pb->next=La->next;
            La->next=pb;
            pb=s;
        }/*如果pb指向的年龄比pa的小,则插入到La链表中*/
    }

那个pa指针有可能变成空在while内部
你的程序还有很多逻辑的错误:
比如Output函数会死循环,所以要修改成:

 void OutPut(ListPtr La){/*输出链表*/
    LNode *s;
    s=La->next;
    while(s){
        printf("%s\t%d\n",s->data.stuName, s->data.age);
        s = s->next;
    }
}

还有gets函数改成scanf函数会好些。
我修改了一部分代码,程序目前不会卡死了。但是似乎还有很多逻辑问题,好像插入不了新结点,你自己再调试下
我改后的代码(你的代码风格我没来得及改,感觉是java风格,不是很好,而且有点乱):

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

int a[10]={0};
int c[10]={0};
char b[100][10];
char d[100][10];

typedef struct stuInfo {
     char  stuName[10];/*学生姓名*/
      int    age; /*年龄*/
 } ElemType;

typedef struct node {
     ElemType  data;
     struct  node  *next;
}LNode,*ListPtr;/*定义结构*/


ListPtr List_Init(int a[],char b[][10],int n){/*链表载入数据*/
   LNode *s,*h;
   int i;
   h=NULL;
   h=(LNode*)malloc(sizeof(LNode));
   h->data.age=0;
   memset(h->data.stuName,0,10*sizeof(char));
   h->next=NULL;
   for(i=n-1;i>=0;i--)
   {
       s=(LNode*)malloc(sizeof(LNode));/*分配内存*/
       memset(s->data.stuName,0,10*sizeof(char));
       s->data.age=a[i];/*把年龄载入*/
       strcpy(s->data.stuName,b[i]);/*把名字载入*/
       s->next=h->next;/*新的结点指向头节点的下一个结点*/
       h->next=s;/*头结点指向新的结点*/
   }
   return h;
}

ListPtr List_Insert (ListPtr h, ElemType x){/*结点插入*/
    LNode *s;

    s=(LNode*)malloc(sizeof(LNode));

    s->data.age=x.age;
    strcpy(s->data.stuName,x.stuName);/*分配空间结点载入*/
    s->next=h->next;/*新的结点指向前一个结点的后一个结点*/
    h->next=s;/*前一个结点指向新结点*/

    return h;

}
void List_Destroy(ListPtr h,ListPtr L){
    LNode *s,*p;
    s=L->next;/*指向第一个结点*/
    p=s;
    while(s){/*寻找所要删除的数据结点的前一个结点*/
        if(s->data.age==h->data.age&&strcmp(s->data.stuName,h->data.stuName)==0)
            break;
        p=s;
        s=s->next;
    }
    s=p->next;/*s指定要删除的结点*/
    p->next=s->next;/*前一个结点指向所要删除结点的后一个结点*/
    free(s);

}
void List_Merge(ListPtr La, ListPtr Lb){/*链表变换,使递增链表变为递减链表,并去重*/
    LNode  *s, *pa, *pb;
    pa=La->next;
    pb=Lb->next;/*各指向两个链表的头结点*/
    La->next=NULL;
    while(pa!=NULL&&pb!=NULL){
        if(pa->data.age<=pb->data.age){
            if(strcmp(pa->data.stuName,pb->data.stuName)==0){
                pb=pb->next;/*如果pa和pb所指的是同一个人,则pb也指向下一个数据,避免重复*/
            }
            s=pa->next;
            pa->next=La->next;
            La->next=pa;
            pa=s;/*如果pa指向的年龄比pb的小则保留并逆置,pa指针指向下一个数据*/
        }
        else{
            s=pb->next;
            pb->next=La->next;
            La->next=pb;
            pb=s;
        }/*如果pb指向的年龄比pa的小,则插入到La链表中*/
    }
    while(pa!=NULL){
        s=pa->next;
        pa->next=La->next;
        La->next=pa;
        pa=s;}/*处理La未处理的数据*/
    while(pb!=NULL){
        s=pb->next;
        pb->next=La->next;
        La->next=pb;
        pb=s;}/*处理Lb未处理的数据*/
    Lb->next=NULL;
    free(Lb);/*释放Lb*/
}
void OutPut(ListPtr La){/*输出链表*/
    LNode *s;
    s=La->next;
    while(s){
        printf("%s\t%d\n",s->data.stuName, s->data.age);
        s = s->next;
    }
}
int  main(){
    ElemType x;
    int i,j;
    ListPtr La=NULL, Lb=NULL;
    LNode *p,*r;
    for(i=0;i<10;i++){
        memset(b[i],0,10*sizeof(char));
        memset(d[i],0,10*sizeof(char));
    }/*初始化字符串数组*/
    strcpy(b[0],"Levis");a[0]=22;
    strcpy(b[1],"Adam");a[1]=23;
    strcpy(b[2],"Lord");a[2]=26;
    strcpy(b[3],"Fred");a[3]=28;
    strcpy(b[4],"May");a[4]=30;
    strcpy(b[5],"York");a[5]=35;
    La=List_Init(a, b, 6);
    /*La数据载入*/
    strcpy(d[0],"Yuki");c[0]=19;
    strcpy(d[1],"Soraru");c[1]=27;
    strcpy(d[2],"Katin");c[2]=29;
    strcpy(d[3],"Sinsan");c[3]=31;
    strcpy(d[4],"York");c[4]=35;
    Lb=List_Init(c,  d, 5);
    /*Lb数据载入*/
    printf("choose operation: 1. insert 2. delete 3.nothing: ");
    scanf("%d",&j);
    if(j==1){
    printf("enter the student's name you want to insert:");/*插入数据操作*/
    scanf("%s", &x.stuName);
    printf("enter the student's age:");
    scanf("%d",&x.age);
    p=La->next;
    while(p){/*查找La中是否有此人*/
        if(strcmp(p->data.stuName,x.stuName)==0)
            break;
        p=p->next;
    }
    if(p=NULL){/*如果没则寻找插入位置*/
        p=La->next;r=p;
        while (p){
        if(x.age<=p->data.age)
            break;
        r=p;
        p=p->next;/*找到比它大的值后,r记录此结点的前一个结点*/
    }
        List_Insert (r, x);/*在r后插入此数据结点*/
}
    else{
        p=Lb->next;/*La中已有此人,则查找Lb*/
    while(p){
        if(strcmp(p->data.stuName,x.stuName)==0)
            break;
        p=p->next;
    }

    if(p=NULL){
        p=Lb->next;r=p;
    while (p){
        if(x.age<=p->data.age)
            break;
        r=p;
        p=p->next;
    }
    List_Insert (r, x);}}/*同La*/
    if(p!=NULL){
        printf("inserted fail");}/*如果两链表中已有此人,则表示插入失败*/
    } 

    if(j==2){
    printf("enter the student's name you want to delete:");/*进行删除操作*/
    gets(x.stuName);
    printf("which lianbiao do you choose, if La, input 1;Lb,input 2:");/*选择要插入的链表*/
    scanf("%d",&i);
    if(i==1){
    p=La->next;
    while(p){
        if(strcmp(p->data.stuName,x.stuName)==0)/*查找La中此人的位置*/
            break;
        p=p->next;/*移动到下一个结点*/
    }
    if(p!=NULL){
    List_Destroy(p,La);}
    else {printf("查无此人");}/*移动到下一个结点*/
    }
    if(i==2){
    p=Lb->next;
    while(p){
        if(strcmp(p->data.stuName,x.stuName)==0)
            break;
        p=p->next;
    }
    if(p!=NULL){List_Destroy(p,Lb);}
    else {printf("查无此人");}}/*同La*/
 }

    printf("now ranking......\n");/*显示递增合并为递减的信息*/
    List_Merge(La, Lb);

   OutPut(La);/*输出函数*/

    return 0;
}

你的data也要分配内存

尝试下模块化吧,你的代码好长……封装对链表操作的函数

调试的话,就在你觉得可能出问题的地方打印一个 printf("be here 1\n");
这样就容易定位到在哪里出问题了
代码太长,看起来好累

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐