单链表的建立
开头
首先这里介绍的建立单链表是有头结点的,因为对于带头结点的单链表,任何一个含有元素的结点都有前驱结点,在表的任何结点之前进行插入结点或删除结点,所要做的都是修改前一结点的指针域。若链表没有头结点,则首元素结点没有前驱结点,那么在其前面插入结点或删除该结点时操作会复杂些。
头插法:
思想:从一个空表开始,重复读入数据,生成新结点,将读入数据存放到新结点的数据域中,然后将新结点插入到当前链表的表头结点之后,直至读入结束标志为止(以下例子结束标志为输入-1)
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct LinkList
{
int data;
struct LinkList *next;
}Node;
//头插法建立单链表
Node *Create_Head()
{
Node *L;
Node *pNew;
int x;
L=(Node*)malloc(sizeof(Node));
L->next=NULL;
scanf("%d",&x);
while(x!=-1)//表示输入-1结束
{
pNew=(Node*)malloc(sizeof(Node));
pNew->data=x;
pNew->next=L->next;//关键代码
L->next=pNew;//关键代码
scanf("%d",&x);
}
return L;
}
void Output(Node *L)
{
Node *p;
p=L->next;
while(p)
{
printf("%d ",p->data);
p=p->next;
}
}
int main(void)
{
Node *L;
printf("开始建立单链表L,输入-1结束: \n");
L=Create_Head();
Output(L);
return 0;
}
运行结果如图:
由运行结果易知由头插法建立的单链表的元素与输入元素顺序是颠倒的,头插法这一特性常运用于单链表的逆置。
尾插法:
思想:与头插法不同,尾插法每次将创建的新结点插到当前单链表的表尾结点之后,所以要增加一个尾指针r,使之指向当前单链表的表尾。
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct LinkList
{
int data;
struct LinkList *next;
}Node;
//尾插法建立单链表
Node *Create_Tail()
{
Node *L;
Node *pNew,*r;
int x;
L=(Node*)malloc(sizeof(Node));
L->next=NULL;
r=L;
scanf("%d",&x);
while(x!=-1)
{
pNew=(Node*)malloc(sizeof(Node));
pNew->data=x;
//pNew->next=r->next;
r->next=pNew;//关键代码
r=pNew;//关键代码,尾指针移动
scanf("%d",&x);
}
r->next=NULL;
return L;
}void Output(Node *L)
{
Node *p;
p=L->next;
while(p)
{
printf("%d ",p->data);
p=p->next;
}
}
int main(void)
{
Node *L;
printf("开始建立单链表L,输入-1结束: \n");
L=Create_Tail();
Output(L);
return 0;
}
运行结果如图:
由运行结果易知由尾插法建立的单链表的数据与输入时候的数据顺序相同,因此尾插法常应用于单链表的合并。