问题描述
- 关于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("%st%dn",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函数也出现位置冲突报错。。功力不足实在解决不了。。跪求大神解答。。(感觉自己写的东西除了上面两个错误应该还有,但是因为位置冲突问题就只能编译到那个地方无法进行下去。。我肉眼实在找不出来。。
解决方案
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("%st%dn",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("%st%dn",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;
}
解决方案六:
参考代码段
https://github.com/707wk/Senior-middle-school/blob/master/Filling%20in%20the%20gaps.c
解决方案七:
你的data也要分配内存
解决方案八:
尝试下模块化吧,你的代码好长……封装对链表操作的函数
解决方案九:
调试的话,就在你觉得可能出问题的地方打印一个 printf("be here 1n");
这样就容易定位到在哪里出问题了
代码太长,看起来好累