91.【C语言】数据结构之单向链表的查找,中间插入和删除,销毁-4.链表的中间删除函数

时间:2024-10-28 07:31:17

示意图(非头删)

1.在pos之前删除:SLTEraseBefore函数

1.借助头指针pphead

代码示例
void  SLTEraseBefore(SLTNode** pphead, SLTNode* pos)
{
	assert(pphead);
	assert(pos);
	assert(*pphead);
	if (*pphead == pos)
	{
		SLTPopFront(pphead);
	}
	else
	{
		//找pos的前一个
        SLTNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = pos->next;
		free(pos);
	}
}

注意:

1.断言pphead,*pphead(即plist)和pos

2.头删直接调用SLTPopFront函数

3.不采取pos = NULL;,SLTErase中的pos为形参,没有办法真正为删除的节点含有的指针置NULL,应该在main.c中操作

头文件添加SLTErase的声明
main.c的部分代码改为
void TestSList1()
{
	SLTNode* plist = NULL;
	SLTPushBack(&plist, 1);
	SLTPushBack(&plist, 2);
	SLTPushBack(&plist, 3);
	SLTPushBack(&plist, 4);
	SLTPrint(plist);
	SLTNode* pos = SLTFind(plist, 3);
	SLTEraseBefore(&plist,pos);
	pos = NULL;
	SLTPrint(plist);
}

注意pos = NULL;

运行结果

2.不借助头指针pphead

示意图

代码示例
void  SLTEraseBefore(SLTNode** pos)
{
	assert((*pos)->next);
	(*pos)->data = ((*pos)->next)->data;
	(*pos)->next = ((*pos)->next)->next;
}
//或写成下面这样
void  SLTEraseBefore(SLTNode* pos)
{
    assert(pos->next);
    pos->data = (pos->next)->data;
	pos->next = (pos->next)->next;
}

注意:此方法有缺陷,不能尾删,因此断言

2.在pos之后删除:SLTEraseBeforeAfter函数

代码示例
void SLTEraseAfter(SLTNode* pos)
{
	assert(pos);//不为空链表
	assert(pos->next);//不为末尾节点
	SLTNode* delete = pos->next;
    //也可以写成pos->next = delete->next;
	pos->next = (pos->next)->next;
	free(delete);
	delete = NULL;
}

注意:不可以不写SLTNode* delete = pos->next;,一旦pos->next被修改后,要删除的节点的指针会丢失,因此要先用结构体指针delete保存