下面是动态链表的创建、连接两个链表,并打印出链表的代码。
看程序(完整可运行代码):
#include <stdio.h>
/*********定义结构体***********/
struct node
{
char data;
struct node *next;
};
/*********创建链表************/
struct node *createlist()
{
char ch;
struct node *head,*p,*r;
r=head=NULL;
while ((ch=getchar())!='/n')
{
p=(struct node *)malloc(sizeof(struct node));
p->data=ch;
if(head==NULL)
head=p;
else
r->next=p;
r=p;
}
p->next=NULL;
return head;
}
/**************连接两个链表******************/
struct node *concatenate(struct node *list1,struct node *list2)
{
struct node *temp;
if (list1==NULL)
return list2;
else {
if (list2!=NULL) {
for ( temp =list1; temp->next; temp = temp->next );
/*遍历到list1的末尾*/
temp->next=list2;/*将list2链接到list1末尾*/
}
}
return list1;
}
/**************主函数********************/
main()
{
struct node *list1,*list2,*list3;
list1=createlist();
list2=createlist();
list3=concatenate(list1,list2);
do
{
printf("%c",list3->data);
list3=list3->next;
}while(list3!=NULL);
printf("/n");
getch();
}
本程序运用了尾插法创建了链表,先输入的节点在链表的前面,后输入的节点在后面。struct node *head,*p,*r;先定义结构体指针变量,问:何为变量?所谓变量,就是可以赋值给它的一种符号。在没有赋值给它们之前它们只是一个符号而已。那么我们就可以把结构体空间赋给这样的符号。当我们把NULL赋给了变量之后,该变量就发生了质的变化!比如head=NULL;此时代号head代表的是一个空结构体,而没有赋值之前什么都不是,这是显然不同的概念!
下面看while循环:
while ((ch=getchar())!='/n')
{
p=(struct node *)malloc(sizeof(struct node));
p->data=ch;
if(head==NULL)
head=p;
else
r->next=p;
r=p;
}
while循环实现了动态地创建链表,这个循环要实现的目的:head指向链表的第一个节点,在不停地产生节点的过程中,来一个就接在链表的后面。这样的目的怎样来实现呢?链表的动态产生,必然要用到循环,这里毫无疑问选择while循环。
while ((ch=getchar())!='/n')
{
p=(struct node *)malloc(sizeof(struct node));
p->data=ch;
}
这是动态生成节点。这样不停地产生却无法连接!!!无法连接的原因何在?没有媒介!这就如同化学反应中的催化剂一样,在反应中起到中间媒介一样。我们可以假设节点的前一个节点为r,然后再把该节点赋给r。也就是说r是“可移动的盒子”!
所以有这样的代码:
while ((ch=getchar())!='/n')
{
p=(struct node *)malloc(sizeof(struct node));
p->data=ch;
r->next=p;
r=p;
}
我们认为前一个节点是r ,那么追溯到最前面呢?所以最先面的必须是r,所以在while循环之前让r指向表头!这里的问题是在while循环之前,表头还未产生,应为head是专门用来间接第一个节点的,所以我们只需要把r指向head即可。然后在第一个链表节点产生的时候将节点赋给head就ok了!
while ((ch=getchar())!='/n')
{
p=(struct node *)malloc(sizeof(struct node));
p->data=ch;
if(head=NULL)
head=p;
else
r->next=p;
r=p;
}
所以这样创建链表是一种非常符合逻辑的创建方式。
下面看看链表的连接问题:
当两个链表已经创建完毕后,如何实现两个链表的连接呢?谁都能想到只要把第一个链表的最后一个节点连接到第二个链表的第一个节点即可。那么现在的问题就是要找到第一个链表的最后一个节点和第二个链表的第一个节点!
p=list1;
if(list1==NULL)
{ printf("list=NULL");
return list2;
}
else
{
if(list2!=NULL)
{
while(p->next)
{
p=p->next;
}
p->next=list2;
}
return list1;
}
这样的代码就是一个符合逻辑的代码,所以程序的编写一定要符合逻辑,不然即使结果是对的但是很容易会出现漏洞!
本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/wanglei8013/archive/2010/06/19/5680242.aspx