1.在链表任意位置插入节点
(1) 节点的内容包括 id、name、telphone number以及p_next,可编写程序对任意 id 位置之前进行插入;
(2) 实现步骤:
1.) (头插入)判断是否 head 的 id 即为所要插入的位置,若是,则先将 node 的 p_next 指向 head 所指向的位置,再将 head 指向 node;
2.) (中间插入)若 id 不是头位置,则找出 id 所在位置的前一个位置,因为要先将 id 所在的节点连接到 node 上,再将 id 的前一个连接到 node之前
3.) (尾插入)若 id 位置为尾节点所在的位置或并没有要插入的 id,则将新节点插入到链表末尾。
#include<stdio.h>
#include<stdlib.h>
typedef struct NAMENOTE
{
int id;
char *name;
char *tel_num;
struct NAMENOTE *p_next;
}NameNote;
NameNote *CreatNode(int id, char *name, char *tel_num);
void AppendNode(NameNote **pp_head, NameNote **pp_end, NameNote *node);
void InsertNode(NameNote **pp_head, NameNote **pp_end, NameNote *node, int id);
int main()
{
NameNote *p_head = NULL;
NameNote *p_end = NULL;
AppendNode(&p_head, &p_end, CreatNode(1, "c", "111"));
AppendNode(&p_head, &p_end, CreatNode(2, "python", "222"));
AppendNode(&p_head, &p_end, CreatNode(3, "java", "333"));
return 0;
}
NameNote *CreatNode(int id, char *name, char *tel_num)
{
NameNote *node = (NameNote*)malloc(sizeof(NameNote));
node->id = id;
node->name = name;
node->tel_num = tel_num;
node->p_next = NULL;
return node;
}
void AppendNode(NameNote **pp_head, NameNote **pp_end, NameNote *node)
{
if(*pp_head == NULL)
{
*pp_head = node;
*pp_end = node;
}
else
{
(*pp_end)->p_next = node;
}
return;
}
void InsertNode(NameNote **pp_head, NameNote **pp_end, NameNote *node, int id)
{
NameNote *p_flag = *pp_head;
//头插入
if(p_flag->id == id)
{
node->p_next = *pp_head;
*pp_head = node;
return;
}
//中间插入
while(p_flag->p_next != NULL)
{
p_flag = p_flag->p_next;
if(p_flag->p_next->id == id)
{
node->p_next = p_flag->p_next;
p_flag->p_next = node;
}
}
//尾插入
(*pp_end)->p_next = node;
*pp_end = node;
return;
}
2.删除某个节点
(1) 对于链表的删除,我们给定某个想删除的节点的 id,通过 id 查找到要删除的位置;
(2) 实现步骤:
1.) 首先判断要删除的 id 是否是头节点的 id,若是,则将 head 指向 head 的下一个位置,并free掉被删除的节点;
2.) 若不是头节点,则寻找要删除的 id 的位置,这里需要两个指针来进行标注,一个用来标记删除的节点的位置 p_del,另一个用来标注 p_del 的前一个位置 p_flag,因为需要 p_flag 来链接 p_del 的下一个节点;
3.) 若要删除的 id 是尾节点的 id,则改变 end 指向的位置(更新尾节点)。
void DeleteNode(NameNote **pp_head, NameNote **pp_end, int id)
{
NameNote *p_del = *pp_head; //标注要删除的节点的位置
NameNote *p_flag = NULL; //标注要删除的节点的前一个位置
//若删除的节点为头节点
if(p_del->id == id)
{
*pp_head = p_del->p_next;
free(p_del);
p_del = NULL;
return;
}
//若删除中间的节点
while(p_del->p_next != NULL)
{
p_flag = p_del;
p_del = p_del->p_next;
if(p_del->id == id)
{
p_flag->p_next = p_del->p_next;
free(p_del);
p_del = NULL;
if(p_flag->p_next == NULL)
*pp_end = p_flag;
return;
}
}
return;
}