| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 682 人关注过本帖
标题:单向链表 求教
取消只看楼主 加入收藏
qq95620412
Rank: 1
等 级:新手上路
帖 子:81
专家分:0
注 册:2007-11-5
结帖率:100%
收藏
 问题点数:0 回复次数:6 
单向链表 求教

我仿照 李春葆 编著的 《数据结构习题与解析(C语言篇)》(清华大学出版社) 2000年1月第1版
编写的
不带头节点的单向链表程序

在建立链表之后,
若需要在第一个节点之前在插入一个节点,
无法修改表头指针。

应如何编写?

请高手不吝赐教!

另:个人觉得李春葆编著的这本教材谬误太多,实在是误人子弟。不知各位高手意下如何?



修改自:上书P47-P51

附源代码:


#include<stdio.h>
#include<alloc.h>

typedef struct linknode
{
int data;
struct linknode *next;
}node;

node *creat() //建立不带头节点的单向链表
{
node *head,*p,*s;
int x,cycle=1;
head=(node *)malloc(sizeof(node)); //建立头节点
head->next=NULL; //使头节点指针域为空
p=head;
while(cycle) //建立带头节点的单向链表
{
scanf("%d",&x);
if(x!=0)
{
s=(node *)malloc(sizeof(node));
s->data=x;
p->next=s;
p=s;
}
else cycle=0;
}
p->next=NULL; //使尾节点指针域为空
s=head; //删除头节点并使head指向第一个节点
head=head->next;
free(s);
return head; //返回第一个节点的指针
}

void printout(node *WFY) //输出节点的data值
{
node *temp;
temp=WFY;
if(temp==NULL)
{
printf("空表\n");
}
else while(temp)
{
printf("%d",temp->data);
temp=temp->next;
}
printf("输出完毕\n");
}


node *find(node *head,int x)
{
node *p;
p=head;
if(p==NULL)
{
printf("空表,节点未找到\n");
}
else
{
while(p!=NULL && p->data!=x) p=p->next;
if(p!=NULL) printf("节点找到\n");
else printf("节点未找到\n");
}
return p;
}

int length(node *head)
{
int n=0;
node *p;
p=head;
while(p!=NULL)
{
p=p->next;
n++;
}
return n;
}

node *insert(node *head,int i,int x) //在单链表中第i个节点之后插入一个元素为x的节点
/*疑问:若需修改表头指针,显然无法完成任务*/

{

node *insert;
node *p;
int j;
if(i==0)
{
insert=(node *)malloc(sizeof(node));
insert->data=x;
insert->next=head;
*head=*insert;
return insert;
}
else
{
p=head;j=1;
while(p!=NULL &&j<i)
{
p=p->next;
j++;
}
if(p!=NULL)
{
insert=(node *)malloc(sizeof(node));
insert->data=x;
insert->next=p->next;
p->next=insert;
return insert;
}
else
{
printf("不存在第%d个节点\n",i);
return NULL;
}
}

}

int main()
{
node *a;
node *b;
int c,d,e;
a=creat();
printout(a);
// scanf("%d",&c);
// b=find(a,c);
// printf("%d",b->data);
printf("输入插入位置:");
scanf("%d",&d);
printf("输入插入值:");
scanf("%d",&e);
insert(a,d,e);
printout(a);
return 0;
}

搜索更多相关主题的帖子: 链表 
2007-11-05 15:55
qq95620412
Rank: 1
等 级:新手上路
帖 子:81
专家分:0
注 册:2007-11-5
收藏
得分:0 

回2楼:

你发的帖子我已经看过了。确实,我也想过按照您提供的算法来实现,也完全可以实现。

我的问题的实质是:

node *insert(node *head,int i,int x) //在单链表中第i个节点之后插入一个元素为x的节点
/*疑问:若需修改表头指针,显然无法完成任务*/


{
node *insert;
node *p;

int j;
if(i==0)
{
insert=(node *)malloc(sizeof(node));
insert->data=x;
insert->next=head;
*head=*insert;
return insert;
}
else
{
p=head;j=1;
while(p!=NULL &&j<i)
{
p=p->next;
j++;
}
if(p!=NULL)
{
insert=(node *)malloc(sizeof(node));
insert->data=x;
insert->next=p->next;
p->next=insert;
return insert;
}
else
{
printf("不存在第%d个节点\n",i);
return NULL;
}
}

}


中 *head=*insert;
语句无法完成修改表头的任务。
书上提供的是 head=insert
显然也无法完成修改表头的任务。

问:高手应如何在不改变函数原型的情况下完成修改表头的任务。

C++ 可以使用 引用 来完成任务。这个我已知晓。

C可以完成这个任务吗?



人生路难走,转眼已白头。伤心望远山,黯然下小楼。
2007-11-05 16:41
qq95620412
Rank: 1
等 级:新手上路
帖 子:81
专家分:0
注 册:2007-11-5
收藏
得分:0 
回8楼:

head = insert

只是修改了 insert() 函数中的head
而主函数中的head并未发生变化


人生路难走,转眼已白头。伤心望远山,黯然下小楼。
2007-11-05 17:48
qq95620412
Rank: 1
等 级:新手上路
帖 子:81
专家分:0
注 册:2007-11-5
收藏
得分:0 

问题就是这里:

我们来分析一下:

insert(node *head, int i, int x)
{
node *insert;
node *p;
int j;
if(i==0)
{
insert=(node *)malloc(sizeof(node));
insert->data=x;
insert->next=head;
*head=*insert;
return insert;
}
else
...
}


main()
{
...
...
insert(headD,iD,xD);
...
}


main函数在调用insert()函数时,实际上是将对应参数的值通过复制的方式传递的:
即在main函数中的执行如下:

....
head = headD;
i=iD;
x=xD;
node *insert;
node *p;
int j;
if(i==0)
{
insert=(node *)malloc(sizeof(node));
insert->data=x;
insert->next=head;
head=insert; //核心之处:
return insert;
}
else
...

可以看到:
head=insert只是改变了head的值,也就是说,head指向修改后的头节点
而我们需要修改的headD仍然未发生改变。



类似的例子如下


swap(int *a, int *b)
{
int *temp;
temp=a;
a=b;
b=temp;
}

main()
{
int aD=3, int bD=4;
printf("%d,%d",aD,bD);
swap(&aD,&bD);
printf("%d,%d",aD,bD);
}

运行后的结果是: 3,4
3,4

而不是 3,4
4,3

这就是我的问题的本质!
与10楼共勉!


人生路难走,转眼已白头。伤心望远山,黯然下小楼。
2007-11-05 18:12
qq95620412
Rank: 1
等 级:新手上路
帖 子:81
专家分:0
注 册:2007-11-5
收藏
得分:0 

回12楼:

那你在swap()函数中动态生成的sss的空间如何回收?


人生路难走,转眼已白头。伤心望远山,黯然下小楼。
2007-11-05 19:11
qq95620412
Rank: 1
等 级:新手上路
帖 子:81
专家分:0
注 册:2007-11-5
收藏
得分:0 

不过我总算想明白了。
我需要修改

insert(node *head, int i, int x)

中的head的内容,是无法完成目的的。
因为C在传递参数时采用的是传值调用。
因此必须修改函数原型为

insert(node **head,int i,int x)

这样就可以完成任务了。

附修改后的源程序:

#include<stdio.h>
#include<alloc.h>

typedef struct linknode
{
int data;
struct linknode *next;
}node;

node *creat() //建立不带头节点的单向链表
{
node *head,*p,*s;
int x,cycle=1;
head=(node *)malloc(sizeof(node)); //建立头节点
head->next=NULL; //使头节点指针域为空
p=head;
while(cycle) //建立带头节点的单向链表
{
scanf("%d",&x);
if(x!=0)
{
s=(node *)malloc(sizeof(node));
s->data=x;
p->next=s;
p=s;
}
else cycle=0;
}
p->next=NULL; //使尾节点指针域为空
s=head; //删除头节点并使head指向第一个节点
head=head->next;
free(s);
return head; //返回第一个节点的指针
}

void printout(node *WFY) //输出节点的data值
{
if(WFY==NULL) //根本不需要引入临时变量temp
{
printf("空表\n");
}
else while(WFY)
{
printf("%d",WFY->data);
WFY=WFY->next;
}
printf("输出完毕\n");
}


node *find(node *head,int x) //同理此处也不用引入临时变量p,不用担心head的变化不会修改主函数中的head
{
if(head==NULL)
{
printf("空表,节点未找到\n");
}
else
{
while(head!=NULL && head->data!=x) head=head->next;
if(head!=NULL) printf("节点找到\n");
else printf("节点未找到\n");
}
return head;
}

int length(node *head)
{
int n=0;
node *p;
p=head;
while(p!=NULL)
{
p=p->next;
n++;
}
return n;
}

node *insert(node **head,int i,int x) //在单链表中第i个节点之后插入一个元素为x的节点
/*疑问已解决*/

{

node *insert;
node *p;
int j;
if(i==0)
{
insert=(node *)malloc(sizeof(node));
insert->data=x;
insert->next=*head;
*head=insert; //关键之处
return insert;
}
else
{
p=*head;j=1;
while(p!=NULL &&j<i)
{
p=p->next;
j++;
}
if(p!=NULL)
{
insert=(node *)malloc(sizeof(node));
insert->data=x;
insert->next=p->next;
p->next=insert;
return insert;
}
else
{
printf("不存在第%d个节点\n",i);
return NULL;
}
}

}

int main()
{
node *a;
node *b;
int c,d,e;
a=creat();
printout(a);
scanf("%d",&c);
b=find(a,c);
printf("%d",b->data);
printf("输入插入位置:");
scanf("%d",&d);
printf("输入插入值:");
scanf("%d",&e);
insert(&a,d,e);
printout(a);
return 0;
}



我已在turboc++3.1中运行通过,不只是否还有问题,望高手不吝赐教。
感谢 大侠 作弊 的热心帮助。

所以说,C语言在通过参数传值时很多时候都没有C++的引用方便。


[此贴子已经被作者于2007-11-5 19:35:08编辑过]


人生路难走,转眼已白头。伤心望远山,黯然下小楼。
2007-11-05 19:18
qq95620412
Rank: 1
等 级:新手上路
帖 子:81
专家分:0
注 册:2007-11-5
收藏
得分:0 

大侠 作弊 哪儿去了? 请看看我编辑后的帖子。


人生路难走,转眼已白头。伤心望远山,黯然下小楼。
2007-11-05 19:48
快速回复:单向链表 求教
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.013485 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved