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

我仿照 李春葆 编著的 《数据结构习题与解析(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
a464108502
Rank: 1
等 级:新手上路
帖 子:25
专家分:0
注 册:2007-11-5
收藏
得分:0 

我发个非你看下,但未必有用,我要逃离新手区
#include "stdio.h"
#include "conio.h"
typedef int data;
typedef struct link_node{
data info;
struct link_node *next;
}node;
node* init_link_list()
{
return NULL;
}
void print_link_list(node *head)
{
node *p;
p=head;
if(!p)
printf("\n单链表是空的!");
else
{
printf("\n单链表的各个结点的值是:");
while(p)
{
printf("%5d",p->info);
p=p->next;
}
}
}
node* find_num(node *head,data x)
{
node *p;
p=head;
while(p&&p->info!=x)
p=p->next;
return p;
}
node* find_pos(node *head,int pos)
{
int i=1;
node *p;
p=head;
if(pos<1)
{
printf("\n查找的位置不存在!");
exit(1);
}
while(p&&i<pos)
{
p=p->next;
i++;
}
return p;
}
node* insert_in_front(node *head,data x)
{
node *p;
p=(node*)malloc(sizeof(node));
p->info=x;
p->next=head;
head=p;
return head;
}
node* insert_x_after_y(node *head,data x,data y)
{
node *p,*q;
q=find_num(head,y);
if(!q)
printf("\n不存在值为%d的结点.",y);
else
{
p=(node*)malloc(sizeof(node));
p->info=x;
p->next=q->next;
q->next=p;
}
return head;
}
node* insert_x_pos_i(node *head,data x,int i)
{
node *p,*q;
q=find_pos(head,i);
if(!q)
{
printf("\n找不到第%d个结点",i);
exit(1);
}
p=(node*)malloc(sizeof(node));
p->info=x;
p->next=q->next;
q->next=p;
return head;
}
node* del_num(node *head,data x)
{
node *pre=NULL,*p=head;
if(!head)
{
printf("\n单链表是空的,无法删除!");
exit(1);
}
while(p&&p->info!=x)
{
pre=p;
p=p->next;
}
if(!pre&&p->info!=x)
head=head->next;
else
{
pre->next=p->next;
}
free(p);
return head;
}
node* del_pos(node *head,int pos)
{
node *pre=NULL,*p; int i=0;
if(pos<1)
{
printf("\n查找的位置不存在!");
exit(1);
}
p=head;
while(p&&i<pos)
{
pre=p;
p=p->next;
i++;
}
if(i<pos)
printf("\n未找到第%d个结点!",pos);
else
{
if(!pre)
head=head->next;
else
pre->next=p->next;
}
free(p);
return head;
}
node* insert_rear(node *head,data x)
{
node *r;
node *p=(node*)malloc(sizeof(node));
p->info=x;
if(!head)
{
p->next=NULL;
head=p;
}
else
{
r=head;
while(r->next)
r=r->next;
p->next=NULL;
r->next=p;
}
return head;
}
main()
{
node *head=init_link_list();
print_link_list(head);
head=insert_in_front(head,25);
print_link_list(head);
head=insert_rear(head,2112);
head=insert_x_after_y(head,251,2112);
head=del_pos(head,1);
head=insert_x_pos_i(head,1552,1);
print_link_list(head);
printf("\n链表操作!");
getch();
}








2007-11-05 16:24
gurrby
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2007-11-5
收藏
得分:0 
buhui
2007-11-05 16:25
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
icelake
Rank: 1
等 级:新手上路
帖 子:16
专家分:0
注 册:2007-1-17
收藏
得分:0 
不懂

2007-11-05 16:44
新手在线
Rank: 1
等 级:新手上路
帖 子:9
专家分:0
注 册:2007-11-5
收藏
得分:0 
2007-11-05 16:48
作弊
Rank: 1
等 级:新手上路
帖 子:50
专家分:0
注 册:2007-11-3
收藏
得分:0 
*head=*insert;

*head 是pointer to pointer

head 你在import 的时候 就是pointer 而你自己建立的insert也是pointer
直接等就可以 和你上面的 p = s是一个道理

不明白 怎么无法完成修改表头
2007-11-05 17:08
qq95620412
Rank: 1
等 级:新手上路
帖 子:81
专家分:0
注 册:2007-11-5
收藏
得分:0 
回8楼:

head = insert

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


人生路难走,转眼已白头。伤心望远山,黯然下小楼。
2007-11-05 17:48
作弊
Rank: 1
等 级:新手上路
帖 子:50
专家分:0
注 册:2007-11-3
收藏
得分:0 
你import 的head就是 pointer

在function 里面修改后

内存地址直接发生变化

不需要返回
2007-11-05 17:56
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
快速回复:单向链表 求教
数据加载中...
 
   



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

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