(1)算法的基本设计思想
要找到链表中数据最小的结点,可以使用4指针法。具体步骤如下:
- 定义4个指针,分别命名为
MinNodeprev
、MinNode
、CurrentNodePrev
、CurrentNode
,MinNodeprev
、CurrentNodePrev
指向链表的头结点,MinNode
、CurrentNode
指向链表的首结点。 - 同时移动
CurrentNodePrev
、CurrentNode
指针,直到CurrentNodePrev
指针到达链表的末尾(即CurrentNodePrev->next
指针指向NULL),在移动的同时,判断MinNode->data
是否大于CurrentNode->data
,条件成立则记录当前结点和直接前驱结点。 - 此时,
MinNode
就是最小值结点。
这个算法的关键在于使用了4指针,这个算法的时间复杂度是O(n),其中n是链表的长度。因为我们只需要遍历一次链表就可以找到最小值结点。
(2)C语言实现代码
/****************************************************************************
*
* function name : LList_FindReciprocalK
* function : 设计一个算法删除单链表L(有头结点)中的一个最小值结点。
* parameter :
* @Head: 链表的头指针。
*
* return value : 失败返回false,成功返回true。
* note : None
* author : [email protected]
* date : 2024-04-22
* version : V1.0
* revision history : None
*
****************************************************************************/
bool LList_MinDel(LList_t *Head)
{
//1.判断链表是否为空,如果为空,退出
if (NULL == Head->next)
{
printf("LList_MinDel fail, linkedlist is Empty\n");
return false;
}
//2.开始寻找最小值
LList_t *MinNodeprev = Head; //定义一个变量保存最小值的节点地址的直接前驱
LList_t *MinNode = Head->next; //定义一个变量保存最小值的节点地址,初始化为首节点
LList_t *CurrentNodePrev = Head; //定义一个变量保存当前节点的直接前驱
LList_t *CurrentNode = Head->next; //定义一个变量保存当前节点,初始化为首节点
//开始遍历循环
while (CurrentNode) //非零即真,NULL时退出循环,即所有节点数据遍历后退出
{
if (MinNode->data > CurrentNode->data) // 最小值节点data大于当前节点data,成立则进入循环体,链表只有一个首节点也能删除。
{
MinNodeprev = CurrentNodePrev; //记录当前最小值节点的前驱节点
MinNode = CurrentNode; //记录当前最小值节点
}
//不管if条件是否成立,都需要做节点偏移,这样才能遍历节点的所有数据
CurrentNodePrev = CurrentNode;
CurrentNode = CurrentNode->next;
}
//3.while循环后,已经找到最小值节点,连接后删除原有节点即可。
printf("MinNode had delete, the value is [%d]\n", MinNode->data);
MinNodeprev->next = MinNode->next; //将最小值节点的直接前驱 连接 最小值节点的直接后继
MinNode->next = NULL; //将最小值节点的指针域指向NULL
free(MinNode); //释放最小值节点
return true;
}