一.链表的创建
1.思路分析
链表创建节点有两种方法,一种是前插法,一种是后接法;前插法就是在头节点和首元节点之间插入节点,后接法是在链表的最后一个节点的末尾插入节点.
这里可能有人又有疑问了.什么是头节点?什么是首元节点?那么这里来解释一下:通常为了方便操作,链表的第一个节点是不用来存储数据元素的,这个节点就称作头节点,而从链表的第二个节点才开始存储数据元素,这个节点称为首元节点,又称为表头节点.
2.代码实现
这里举例一个存储学生信息的链表
//学生信息结构体
typedef struct student
{
int sno; //学号
char name[8]; //姓名
struct student *next; //指向下一个节点的指针
} Lnode,*LinkList;
//链表(表头)初始化函数
void InitList(LinkList *L)
{
(*L)=(LinkList)malloc(sizeof(Lnode)); //分配一个节点的空间
(*L)->next=NULL; //节点next指针指向空
}
//前插法创建链表
void CreateList(LinkList L)
{
int sno; //学号
char name[8]; //姓名
scanf("%d %s",&sno,name); //输入学号和姓名
while(sno!=-1) //以输入学号-1为添加学生信息终止操作
{
LinkList node=(LinkList)malloc(sizeof(Lnode)); //创建新的节点
node->sno=sno; //存储学号
strcpy(node->name,name); //存储姓名
node->next=NULL; //节点next指针赋为空
node->next=L->next; //前插
L->next=node;
scanf("%d %s",&sno,name); //输入学号和姓名
}
}
//后接法创建链表
void CreateList(LinkList L)
{
int sno; //学号
char name[8]; //姓名
scanf("%d %s",&sno,name); //输入学号和姓名
while(sno!=-1) //以输入学号-1为添加学生信息终止操作
{
LinkList node=(LinkList)malloc(sizeof(Lnode)); //创建新的节点
node->sno=sno; //存储学号
strcpy(node->name,name); //存储姓名
node->next=NULL; //节点next指针赋为空
L->next=node; //后接
L=node;
scanf("%d %s",&sno,name); //输入学号和姓名
}
}
//输出链表数据
void PrintList(LinkList L)
{
L=L->next;
while(L!=NULL)
{
printf("%d %s\n",L->sno,L->name);
L=L->next;
}
}
注意:新建节点时,一定要将新建节点的next指针指向NULL,即node->next=NULL;因为链表输出时遍历链表节点是以遍历到链表末尾的空指针为结束条件,虽然不把新建节点的next指针赋为空不会对创建链表产生影响,但是却会使输出操作出错,所以一定要记得新建节点时一定要把新建节点的后继指针next赋为NULL.
二.链表的插入
1.思路分析
要在指定位置插入节点,那么我们要找到指定位置的前一个节点,在这个节点和指定位置节点间插入我们的新节点.
2.代码实现
//将节点插入到链表指定位置,参数:链表头指针,插入节点,插入位置
void InsertNode(LinkList L,LinkList node,int pos)
{
int j=1; //遍历位置计数变量
LinkList temp; //暂存节点的指针
while(L->next!=NULL&&j<pos) //遍历到指定位置的前一个位置节点就停止遍历
{
L=L->next; //顺着链表下移
j++; //位置移动计数加1
}
temp=L->next; //暂存要插入位置的节点的头指针
L->next=node; //前一个位置的后继赋为要插入的节点的头指针
node->next=temp; //新键节点的后继赋为插入位置的原来元素的头指针
}
三.链表的删除
1.思路分析
要删除指定位置的节点,那么我们要找到指定位置的前一个节点,使这个节点的后继指向要删除的节点的后继,再释放要删除的节点的存储空间,就完成了删除操作
2.代码实现
//将链表指定位置的节点删除,参数:链表头指针,删除节点的位置
void DeleteNode(LinkList L,int pos)
{
int j=1; //遍历位置计数变量
LinkList temp; //暂存要删除的节点的指针
while(L->next!=NULL&&j<pos) //遍历到指定位置的前一个位置节点就停止遍历
{
L=L->next; //顺着链表下移
j++; //位置移动计数加1
}
temp=L->next; //要删除的节点
L->next=L->next->next; //要删除的节点的前驱节点的后继赋值为要删除的节点的后继
free(temp); //释放要删除节点的存储空间
}
四.总结
为了方便操作,链表的第一个节点通常不存储数据元素,称为头节点.链表的插入与删除操作要依靠插入位置(删除位置)的前一个节点来实现,所以算法关键要找到到指定位置的前一个节点,来进行操作.