**思路:**申请两个指针 比如找第二个节点 我们就让一个指针先走两步,接下来让两个指针同时向后走 先走的那个指针走到了NULL,则另一个指针则停留在要找的那个指针
先写头文件
#pragma once
typedef int ELEM_TYPE;
//有效数据节点结构体设计(头结点借用)
typedef struct Node
{
ELEM_TYPE data;//数据域 (1.头结点:不保存任何数据 2.有效数据节点:保存有效值)
struct Node* next;//指针域 (1.头结点:保存第一个元素的地址 2.有效数据节点:保存下一个有效元素的地址)
}Node, PNode;
/*
//有效数据节点结构体设计
typedef struct Node
{
union
{
int length;
ELEM_TYPE data;//数据域 存放有效值
};
struct Node *next;//指针域 存放下一个有效数据节点的地址
}Node, PNode;
//头结点结构体设计:
typedef struct Head
{
struct Node *next;//指针域 保存第一个有效数据节点的地址
}Head, *PHead;
*/
//带头结点的单链表有哪些操作函数:
//初始化函数(对于头结点进行赋初值)
void Init_list(struct Node* plist);
//购买一个新节点
struct Node* BuyNode(ELEM_TYPE val);
//头插
bool Insert_head(struct Node* plist, ELEM_TYPE val);
//尾插
bool Insert_tail(struct Node* plist, ELEM_TYPE val);
//按位置插入(pos=0 相当于头插 pos==length 相当于尾插)
bool Insert_pos(struct Node* plist, int pos, ELEM_TYPE val);
//头删
bool Del_head(struct Node* plist);
//尾删
bool Del_tail(struct Node* plist);
//按位置删(pos==0 相当于头删 pos==length-1 相当于尾删(pos==length非法))
bool Del_pos(struct Node* plist, int pos);
//按值删
bool Del_val(struct Node* plist, ELEM_TYPE val);
//获取值位置 (如果val值存在, 则返回其地址 不然返回NULL)
struct Node* Search(struct Node* plist, ELEM_TYPE val);
//判空
bool IsEmpty(struct Node* plist);
//判满 单链表不存在满这个概念
//获取单链表有效数据节点个数
int Get_length(struct Node* plist);
//清空 相当于直接调用销毁
void Clear(struct Node* plist);
//销毁1(malloc申请来的空间 全部释放掉)
void Destroy(struct Node* plist);
//销毁2
void Destroy2(struct Node* plist);
//打印
void Show(struct Node* plist);
再写源文件
struct Node* Get_K_Node(PNode plist, int K)
{
assert(plist != NULL);
assert(K >= 1 && K <= Get_length(plist));
PNode p = plist;
PNode q = plist;
for (int i = 0; i < K; i++)
{
p=p->next;
}
while (p != NULL)
{
p = p->next;
q = q->next;
}
return q;
}