一、整表的创建(头插法)
单链表整表创建的算法思路:
1、声明一节点p和计数变量i;
2、初始化一空链表L;
3、让L的头节点的指针指向NULL,即建立一个带头节点的单链表;
4、循环:
- 生成一新节点赋值给P
- 随机生成一数字赋值给p的数据域P->data;
- 将p插入到头结点与前一节点之间。
实现代码算法如下:
/* 随机产生n个元素的值,建立带表头节点的单链线性表L(头插法)*/
void CreatListHead(linklist *L,int n)
{
LinkList p;
int i;
srand(time(0)); //初始化随机数
*L =(LinkList)malloc(sizeof(Node));
(*L)->next=NULL; //先建立一个带纯洁点的单链表
for(i=0;i<n;i++)
{
p= (LinkList)malloc(sizeof(Node)); //生成新节点
p->data=rand()%100+1; //随机生成100以内的数字
p->next=(*L)->next;
(*L)->next=p; //插入到表头
}
}
这段算法代码里,我们其实用的是插队的办法,就是始终让新节点在第一的位置,我也可以吧这种算法简称为头插法,如下图
可事实上,我们都是吧新节点放在最后,这才是排队的正常思维,每次新节点都插在终端结点的后面,这种算法称之为尾插法。
二、单链表的创建(尾插法)
实现的代码如下:
/* 随机产生n个元素的值,建立带表头节点的单链线性表L(尾插法)*/
void CreatListHead(linklist *L,int n)
{
LinkList p,r;
int i;
srand(time(0)); //初始化随机数
*L =(LinkList)malloc(sizeof(Node));
r=*L; //先建立一个带纯洁点的单链表
for(i=0;i<n;i++)
{
p= (LinkList)malloc(sizeof(Node)); //生成新节点
p->data=rand()%100+1; //随机生成100以内的数字
r->next=p;
r=p; //插入到表头
}
r->next=NULL;
}
注意L与r的关系,L是指整个单链表,而r是指向尾结点的变量,r会随着循环不断地变化结点,而L则是随着循环增长为一个多结点的链表。
这里需要解释一下,r->next=p;的意思,其实就是将刚才的表尾终端结点r的指针指向新结点p,如下图所示,当中1位置表示这个意思。
r->next=p;这一句话应该还好解释,r=p的含义如下图所示。
它的意思是r本在ai-1元素的结点,可现在它已经不是最后的结点了,现在最后的结点是ai,所以应该让p结点这个最后的结点赋值给r。此时r又是最终的尾结点了。
循环结束后,那么应该让这个链表的指针域置空,因此有了“r->next=NULL;”,以便以后遍历时可以确认其是尾部。