前言
前面我们已经实现了链表的创建、插入(头插法)、删除、打印功能,下面我们来实现,查找和指定位置插入
5、指定位置插入
5.1前驱插入
//指定位置的前面插入,和按值删除类似
void Inster_PostionPrecursor_List(Lnode* Head_Node,Node_Data posdata,Node_Data data)
{
Lnode* posNode = Head_Node->next;
Lnode* posNodeFront = Head_Node;
Lnode* New_Node = Create_New_Node(data);
if(posNode == NULL || New_Node == NULL)
{
printf("插入失败,此链表为空\n");
return ;
}
else
{
while(posNode->data != posdata)
{
posNodeFront = posNode;
posNode = posNode->next;
if(posNode == NULL)
{
printf("插入失败\n");
return ;
}
}
New_Node->next = posNode;
posNodeFront->next = New_Node;
// printf("插入成功\n");
}
}
posNode
为指定的位置节点,posNodeFront
为指定位置节点的前驱,New_Node
为待插入节点。
while(posNode->data != posdata)
遍历链表,直到找到posdata
所在的节点,确保遍历过程中posNode
与posNodeFront
一前一后( posNodeFront = posNode; posNode = posNode->next;),当不满足循环条件时,表示此时posNode
节点是我们想找到的节点,接下来插入节点New_Node
谨记插入过程中,一和二的顺序别写反了
①、New_Node->next = posNode;
②、posNodeFront->next = New_Node;
5.2后继插入
void Inster_PostionRear_List(Lnode* Head_Node,Node_Data posdata,Node_Data data)
{
Lnode* posNode = Head_Node->next;
Lnode* New_Node = Create_New_Node(data);
if(posNode == NULL)
{
printf("此链表为空,插入失败\n");
return ;
}
else
{
while(posNode->data != posdata)
{
posNode = posNode->next;
if(posNode == NULL)
{
printf("插入失败\n");
return ;
}
}
New_Node->next = posNode->next;
posNode->next = New_Node;
}
}
和前驱插入类似。
①、New_Node->next = posNode->next;
②、posNode->next = New_Node;
6、查找
6.1查找某个值
//查找链表中的某个值
void Find_CertainValue_List(Lnode* Head_Node,Node_Data value)
{
Lnode* pMove = Head_Node->next;
if(pMove == NULL)
{
printf("查找失败,链表为空\n");
return ;
}
else
{
//遍历整个链表
while(pMove->data != value)
{
pMove = pMove->next;
//遍历结束还未找到
if(pMove == NULL)
{
printf("查找失败,不存在该值\n");
return ;
}
}
//跳出while表示查找成功
printf("查找成功\n");
return ;
}
}
此查找方法为直接查找,定义指针pMove
遍历整个链表
6.2查找某个链表的倒数第n个值
给定一个链表,不知道链表长度,查找此链表倒数第n个值 (前提是链表长度大于n)
//不知道链表长度的情况下(链表长度大于n),查找倒数第n个值
Node_Data Find_Value_List(Lnode* Head_Node,int n)
{
Lnode* posNode = Head_Node->next;
Lnode* posNode_Behind_n = Head_Node->next;
while(n--)
{
posNode_Behind_n = posNode_Behind_n->next;
}
if(posNode == NULL)
{
//printf("此链表为空,查找失败\n");
return -1;
}
else
{
while(posNode_Behind_n != NULL)
{
posNode = posNode->next;
posNode_Behind_n = posNode_Behind_n->next;
}
return posNode->data;
}
}
思路如下:
定义两个指针posNode_Behind_n
和posNode
,二者相隔n
个位置,当posNode_Behind_n
为NULL
时,此时posNode
所指向的节点就是链表的倒数第n
个节点。
7、全部代码测试如下
#include<stdio.h>
#include<malloc.h>
typedef int Node_Data;
typedef struct node{
Node_Data data;
struct node* next;
}Lnode;
//创建链表头节点,返回值为struct node*
Lnode* Create_Head_Node()
{
//动态内存申请
Lnode* Head_Node = (Lnode *)malloc(sizeof(Lnode));
if(Head_Node == NULL)
return NULL;
else
{
//初始化头节点
// Head_Node->data = 1; //这个可以随意赋值
Head_Node->next = NULL;
return Head_Node;
}
}
//创建新的节点,并给此节点赋值
Lnode* Create_New_Node(Node_Data data)
{
Lnode* New_Node = (Lnode *)malloc(sizeof(Lnode));
if(New_Node == NULL)
return NULL;
else
{
New_Node->data = data;
New_Node->next = NULL;
return New_Node;
}
}
//打印链表
void Printf_List(Lnode* Head_Node)
{
Lnode* pMove = Head_Node->next;
if(pMove == NULL)
{
printf("此链表为空,打印失败\n");
return ;
}
else
{
while(pMove != NULL)
{
printf("%d->",pMove->data);
pMove = pMove->next;
}
printf("NULL\n");
}
}
//头插法插入数据
void Insert_Data_List(Lnode* Head_Node,Node_Data data)
{
Lnode* New_Node = Create_New_Node(data);
if(New_Node == NULL)
{
printf("插入失败\n");
return ;
}
else
{
New_Node->next = Head_Node->next;
Head_Node->next = New_Node;
//printf("插入成功\n");
return ;
}
}
//按值删除
void Delete_AccordValue_List(Lnode* Head_Node,Node_Data posdata)
{
Lnode* posNode = Head_Node->next;
Lnode* posNodeFornt = Head_Node;
if(posNode == NULL)
{
printf("此链表为空,删除失败\n");
return ;
}
else
{
while(posNode->data != posdata)
{
posNodeFornt = posNode;
posNode = posNode->next;
if(posNode == NULL)
{
printf("删除失败,不存在该值\n");
return ;
}
}
posNodeFornt->next = posNode->next;
free(posNode);
printf("删除成功\n");
}
}
//指定位置的前面插入,和按值删除类似
void Inster_PostionPrecursor_List(Lnode* Head_Node,Node_Data posdata,Node_Data data)
{
Lnode* posNode = Head_Node->next;
Lnode* posNodeFront = Head_Node;
Lnode* New_Node = Create_New_Node(data);
if(posNode == NULL || New_Node == NULL)
{
printf("插入失败,此链表为空\n");
return ;
}
else
{
while(posNode->data != posdata)
{
posNodeFront = posNode;
posNode = posNode->next;
if(posNode == NULL)
{
printf("插入失败\n");
return ;
}
}
New_Node->next = posNode;
posNodeFront->next = New_Node;
// printf("插入成功\n");
}
}
void Inster_PostionRear_List(Lnode* Head_Node,Node_Data posdata,Node_Data data)
{
Lnode* posNode = Head_Node->next;
Lnode* New_Node = Create_New_Node(data);
if(posNode == NULL)
{
printf("此链表为空,插入失败\n");
return ;
}
else
{
while(posNode->data != posdata)
{
posNode = posNode->next;
if(posNode == NULL)
{
printf("插入失败\n");
return ;
}
}
New_Node->next = posNode->next;
posNode->next = New_Node;
}
}
//查找链表中的某个值
void Find_CertainValue_List(Lnode* Head_Node,Node_Data value)
{
Lnode* pMove = Head_Node->next;
if(pMove == NULL)
{
printf("查找失败,链表为空\n");
return ;
}
else
{
while(pMove->data != value)
{
pMove = pMove->next;
if(pMove == NULL)
{
printf("查找失败,不存在该值\n");
return ;
}
}
printf("查找成功\n");
return ;
}
}
//不知道链表长度的情况下(链表长度大于n),查找倒数第n个值
Node_Data Find_List(Lnode* Head_Node,int n)
{
Lnode* posNode = Head_Node->next;
Lnode* posNode_Black_n = Head_Node->next;
while(n--)
{
posNode_Black_n = posNode_Black_n->next;
}
if(posNode == NULL)
{
//printf("此链表为空,查找失败\n");
return -1;
}
else
{
while(posNode_Black_n != NULL)
{
posNode = posNode->next;
posNode_Black_n = posNode_Black_n->next;
}
return posNode->data;
}
}
int main()
{
Lnode* Head_Node = Create_Head_Node();
Insert_Data_List(Head_Node,1);
Insert_Data_List(Head_Node,2);
Insert_Data_List(Head_Node,3);
Insert_Data_List(Head_Node,4);
Insert_Data_List(Head_Node,5);
Insert_Data_List(Head_Node,6);
Insert_Data_List(Head_Node,7);
printf("链表内容如下:");
Printf_List(Head_Node);
printf("\n删除链表中的5:");
Delete_AccordValue_List(Head_Node,5);
printf("删除之后,内容如下:");
Printf_List(Head_Node);
printf("\n在4的前面插入77:");
Inster_PostionRear_List(Head_Node,4,77);
printf("插入数据后,内容如下:");
Printf_List(Head_Node);
printf("\n在6的后面插入88:");
Inster_PostionPrecursor_List(Head_Node,6,88);
printf("插入数据后,内容如下:");
Printf_List(Head_Node);
printf("\n查找链表中的77:");
Find_CertainValue_List(Head_Node,1);
printf("\n查找链表中倒数第3个值:");
printf("%d\n",Find_List(Head_Node,3));
printf("\n测试结束!!!!\n");
return 0;
}
运行结果如下:
END
到这里链表的基本操作已经实现了,下一节我会写一个学生管理系统