目录
前言
相关知识点:
- 单链表的基本操作🔗:【链表】单链表知识总结-内含代码操作及其说明_又秃又弱的博客-CSDN博客_单链表知识总结
- 习题:
- 实现链表逆置:【单链表】实现链表逆置_又秃又弱的博客-CSDN博客
- 判断链表是否有环:【链表】判断链表是否有环-快慢指针_又秃又弱的博客-CSDN博客
一、思想
删除一个结点的做法是让该结点的前驱直接指向该节点后继。因此,需要找到k前驱
法一:思考倒数第k个点是正数第几个点?
倒数第k=顺数第len-k+1个点
法二:快慢指针法则。快指针先走k步,然后快慢指针一起走。当快指针->next为空的时候,慢指针所在结点就是倒数第k个点的前驱。
二、代码
方法一:
typedef struct Node
{
int data;//存放数据
struct Node* next;// 存放下一个结点地址
}Node,*List;
void InitList(List plist)
{
assert(plist != NULL); //断言
if (plist == NULL)
{
return;
}
//头结点数据不使用plist->data可以不处理
plist->next = NULL; //->自带*号解引用
}
//获取plist长度,数据节点的个数
int GetLength(List plist)
{
assert(plist != NULL);
if (plist == NULL)
{
return -1;
}
int count = 0;
for (Node* p = plist->next; p != NULL; p = p->next)
{
count++;
}
return count;
}
//输出
void Show(List plist)
{
assert(plist != NULL);
if (plist == NULL)
{
return;
}
for (Node* p = plist->next; p!= NULL; p = p->next)
{
printf("%d ", p->data);
}
printf("\n");
}
//往plist中头部插入数字val
bool Insert_head(List plist, int val)//时间复杂度O(1)
{
//1.动态创建一个新节点
Node* p = (Node*)malloc(sizeof(Node));
assert(p != NULL);//断言
if (p == NULL)
return false;
//2.把数据val存放到新节点
p->data = val;
//3.把新节点插入在头结点的后面
p->next = plist->next;
plist->next = p;
return true;
}
bool DeleteK(List plist, int k)
{
int len = GetLength(plist);
if (plist == NULL||k<=0||k> len)
{
return false;
}
k = len - k + 1;//转化为正数的点
Node* p = plist;
for (int i = 0; i < k - 1; i++)
{
p = p->next;
}
Node* q;
q= p->next;
p->next = p->next->next;
free(q);
return true;
}
int main()
{
Node head;
for (int i = 0; i < 10; i++)
{
Insert_head(&head, i);
}
Show(&head);
DeleteK(&head, 1);
Show(&head);
return 0;
}
方法二
快慢指针(双指针法)(常用)
typedef struct Node
{
int data;//存放数据
struct Node* next;// 存放下一个结点地址
}Node,*List;
void InitList(List plist)
{
assert(plist != NULL); //断言
if (plist == NULL)
{
return;
}
//头结点数据不使用plist->data可以不处理
plist->next = NULL; //->自带*号解引用
}
//获取plist长度,数据节点的个数
int GetLength(List plist)
{
assert(plist != NULL);
if (plist == NULL)
{
return -1;
}
int count = 0;
for (Node* p = plist->next; p != NULL; p = p->next)
{
count++;
}
return count;
}
//输出
void Show(List plist)
{
assert(plist != NULL);
if (plist == NULL)
{
return;
}
for (Node* p = plist->next; p!= NULL; p = p->next)
{
printf("%d ", p->data);
}
printf("\n");
}
//往plist中头部插入数字val
bool Insert_head(List plist, int val)//时间复杂度O(1)
{
//1.动态创建一个新节点
Node* p = (Node*)malloc(sizeof(Node));
assert(p != NULL);//断言
if (p == NULL)
return false;
//2.把数据val存放到新节点
p->data = val;
//3.把新节点插入在头结点的后面
p->next = plist->next;
plist->next = p;
return true;
}
bool DeleteK(List plist, int k)
{
Node* q = plist;
Node* p = plist;
for (int i = 0; i < k; i++)
{
p = p->next;
}
while (p->next = NULL)
{
p = p->next;
q = q->next;
}
//删除q后面的结点
p = q->next;
q->next = p->next;
free(p);
return true;
}
int main()
{
Node head;
for (int i = 0; i < 10; i++)
{
Insert_head(&head, i);
}
Show(&head);
DeleteK(&head, 1);
Show(&head);
return 0;
}