读书人

求教单链表有关问题.纠结一晚上了.

发布时间: 2013-08-04 18:26:16 作者: rapoo

求教单链表问题...纠结一晚上了...
这个程序是我看书之后自己编写的,因为刚刚接触,所以还有很多地方不明白。。。想请各位前辈帮我看一下哪里出错了。。我看了一晚上也没有找出来。。很纠结。。
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<conio.h>
#define OK 1
#define ERROR 0
typedef int datatype;
typedef struct
{
datatype data;
struct lnode *next;
}lnode,*linklist;

void createfromhead(linklist L,int n)
{

lnode *p,*q;
int i;
L=(lnode*)malloc(sizeof(lnode));
L->next=NULL;
p=L;
printf("\n\t依次输入元素:");
for(i=1;i<=n;i++)
{
q=(lnode*)malloc(sizeof(lnode));
scanf("%d",&(q->data));
q->next=p->next;
p->next=q;
p=q;
}
}

int insertlist(linklist L,int i,datatype e)
{

lnode *p,*q;
int j;
j=0;
p=L;
while(j<i-1&&p)
{
p=p->next;
j++;
}
if(!p||j>i-1) return ERROR;
q=(lnode*)malloc(sizeof(lnode));
q->data=e;
q->next=p->next;
p->next=q;
return OK;
}

int deletelist(linklist L,int i,datatype *e)
{
lnode *p,*q;
int j=0;
p=L;
while(j<i-1&&p->next)
{
p=p->next;
j++;
}
if(!(p->next)||j>i-1) return ERROR;
q=p->next;
p->next=q->next;
free(q);
return OK;
}

int locate(linklist L,datatype x)
{
lnode *p;
int i=1;


p=L->next;
while(p)
{
if(p->data==x)
return i;
else
{
p=p->next;
i++;
}
}
return OK;
}

int deleteall(linklist L)
{
lnode *p,*q;
p=L;
q=L->next;
while(q)
{
p->next=q->next;
free(q);
q=p->next;
}
return OK;
}

void printlist(linklist L)
{
lnode *p;
p=L->next;
printf("\n\t单链表的元素为: ");
while(p)
{
printf("%d ",p->data);
p=p->next;
}
}


void operate(linklist L)
{
int i,e,x;
int choose;
while(1)
{
printf("\n\t");
printf("\n\t--------------操作界面--------------");
printf("\n\t1.插入 2.删除 3.查找 4.删除所有 0.退出");
printf("\n\t输入你的选择:");
scanf("%d",&choose);
switch(choose)
{
case 1:
{
printf("\n\t输入要插入元素的位置和数值:");
scanf("%d %d",&i,&e);
if(insertlist(L,i,e))


printlist(L);
else
printf("\n\t输入错误!");
break;
}
case 2:
{
printf("\n\t输入要删除元素的位置:");
scanf("%d",&i);
if(deletelist(L,i,&e))
printlist(L);
else
printf("\n\t输入错误!");
break;
}
case 3:
{
printf("\n\t输入想要查找的元素:");
scanf("%d",&x);
if(locate(L,x))
{
printf("\n\t该元素的位置是:");
printf("\n\t %d",locate(L,x));


break;
}
}
case 4:
{
deleteall(L);
printf("\n\t删除后的链表:");
printlist(L);
}
case 0:
{
exit(OK);
break;
}
default:
printf("\t输入指令错误,请按规则输入\n\n");
break;
}
}
}

int main(int argc, char** argv)
{
int n;
lnode *L;
printf("\n\t输入创建链表元素的个数:");
scanf("%d",&n);
createfromhead(L,n);
printf("\n\t链表创建成功!");
printlist(L);
printf("\n\t任意输入进入操作界面。");
getch();
system("cls");
operate(L);
return OK;
}




单链表


[解决办法]

引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

Quote: 引用:

Quote: 引用:

函数createfromhead(L,n)调用后,L实际并未初始化,未分配到申请的内存,即L指针指向的内存地址是非法的。因为函数参数的传递是“值传递”,传递给createfromhead函数的是L的一个副本。
修改方法:
1.二级指针做参数
2.引用传递
3.在createfromhead函数里malloc头指针,返回该链表的头指针。

请问一下在调用createfromhead(L,n)之后,L为什么实际并未初始化...

要深刻理解C语言函数传递参数是“值传递”,在main函数里定义的L指针,比如&L=addr1,经函数createfromhead调用L,实际传递的是L的一个副本_L,&_L=addr2,addr1不等于addr2,但是L=_L,即指向的内存地址是一样的。createfromhead的malloc函数使_L指向的内存地址发生了变化,但main函数的L还是指向原来的地址。
不知道我说的你明白吗。


那么如果我把malloc用在main函数里面,是不是可以避免这种情况?


可以在main函数里面malloc,不过大部分是在初始化链表的函数里malloc,返回malloc申请的指针,在销毁链表的函数free申请的指针。
常用的方法:
1.二级指针做参数
2.在createfromhead函数里malloc头指针,返回该链表的头指针。


刚才想了一下用二级指针做参数,不知道想的对不对,求请前辈指教一下~
我在main函数里面用的lnode *L,定义L指针,但是在进行初始化,删除或者插入操作的时候,是改变L这个指针的值的,所以我们要在初始化,插入函数或者删除函数里用linklist *L来定义一个指向L指针的指针,所以要用二级指针来做参数。
可是在用malloc的时候,要*L=(LinkList)malloc(sizeof(Node)); (*L)->next=NULL;
我想问一下这个时候*L代表的是什么意思?是指向L指针的指针?那为什么会等于后面的东西呢。。
我刚刚接触数据结构,指针学的也不是很明白,希望前辈能赐教一下。。


传二级指针的目的是希望改变一级指针指向的地址,正如传一级指针可以改变该指针指向的内容。
在主函数这样调用createfromhead(&L),声明如下createfromhead(LinkList *L)。具体的你可以在网上搜一下。

读书人网 >C语言

热点推荐