创建单链表除了使用前插法,还可以使用后插法。后插法通过将新结点逐个插入到链表的尾部来创建链表。如下图所示
根据上图所示,可以考虑尾插法实现:
(1) 生成新的结点
(2) 将新结点地址赋值给头结点的指针域,将新结点的指针域设为NULL。
(3) 继续生成新的结点,将新结点的地址赋值给前驱结点的指针域,将新结点的指针域设为NULL。
如果此时用代码实现
L->next = p;
p->next = NULL;
但如果仅仅按此代码运行,p是新生成的结点,在循环中就会每次将新结点的地址赋值给头指针的指针域,并没有按逐一将结点链接,形成链表。
所以对于尾插法,需要引入一个尾指针,使尾指针指向链表的尾节点,保证新结点能够插入到表尾。
引入尾指针后,后插法的实现思路如下
(1) 链表初始化后,头指针和尾指针都指向头结点
(2) 生成一个新的结点,将新结点的地址赋值给头结点的指针域。
(3) 将尾节点指向新生成的结点
代码实现如下:
(1) 初始化变量r,p。变量r是尾指针,变量p是每次生成的新节点。二者都是结构体指针类型
LinkList p, r;
(2) 初始化链表,生成头结点,头指针
L = (LinkList)malloc(sizeof(LNode));
(3) 将头结点的指针域设为NULL,将尾指针r指向头结点
L->next = NULL;
r = L;
(4) 循环执行,使用变量p存储新生成的结点
p = (LinkList)malloc(sizeof(LNode));
(5) 将循环中每次生成的结点挂在新结点之后
p->next = NULL;
p->next中p是新生成的结点,p->next是新节点的指针域,因为新生成的结点总是在最后,所以需要将新结点的指针域设为NULL。
r->next = p;
r是尾指针,r初始化时指向头结点,r->next是r所指向的结点的指针域,所以需要将r的指针域赋值为p。
r = p;
在循环中需要将尾指针指向尾节点,结点p为每次生成的新结点的地址,所以将p赋值给r。
完整代码如下:
void CreatList_R(LinkList &L, int n){
int i;
LinkList p, r;
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
r = L;
printf("使用尾插法,请输入%d个数\n", n);
for(i=0; i<n; i ){
p = (LinkList)malloc(sizeof(LNode));
scanf("%d", &p->data);
p->next = NULL;
r->next = p;
r = p;
}
}