9【查找单链表的中间结点,要求只能遍历一次链表】,10【查找单链表的倒数第k个结点,要求只能遍历一遍链表】,11【删除链表的倒数第k个结点】,12 【复杂链表的复制】
创建链表 打印链表在上一篇,戳链接
点击打开链接
9.【查找单链表的中间结点,要求只能遍历一次链表】,创建两个指针,都从链表的开头向后遍历,一个一次走一步,一个一次走两步,等到快指针走到链表结束,慢指针也就走到了链表中间结点处
SListNode* SListFindMidNode(SListNode* list)
{
if (list == NULL || list->_next == NULL)//链表为空或者只有一个结点,就没有必要查找了
return list;
SListNode* pSlow = list;//慢指针
SListNode* pQuick = list;//快指针
while (pQuick->_next != NULL)
{
pSlow = pSlow->_next;
pQuick = pQuick->_next;
if (pQuick->_next != NULL)
pQuick = pQuick->_next;//快指针走的第二步
}
return pSlow;
}
10,【查找单链表的倒数第k个结点,要求只能遍历一次链表】,同样的,也是创建两个指针都指向链表开始,让快指针先走K步,然后两个指针在一起一步一步的走,直到快指针走到了链表结束,那么这时慢指针就指向了倒数第K个结点
SListNode* SListFindTailKNode(SListNode* list, size_t k)
{
if (k == 0 || list == NULL)//链表不存在或者k不存在
return NULL;
SListNode* pSlow = list;
SListNode* pQuick = list;
while (k > 1 && pQuick != NULL)//快指针先走K步
{
pQuick = pQuick->_next;
k--;
}
if (k < 1 || pQuick == NULL)//链表的长度不足以让快指针走K步,那么就不存在倒数第K个结点
return NULL;
while (pQuick->_next != NULL)//两个指针一起走,直到快指针走到结束处
{
pQuick = pQuick->_next;
pSlow = pSlow->_next;
}
return pSlow;
}
11,【删除链表的倒数第K个结点】,先调用上面的函数(第10个)找到倒数第K个结点,判断它是否是最后一个结点,是的话直接free然后置空,不是的话,调用删除非尾结点的函数(第2个)
SListNode* SListDelTailKNode(SListNode* list, size_t k)
{
assert(list);
assert(k > 0);
SListNode* g = SListFindTailKNode(list, k);//函数详情见上一个函数
if (g->_next != NULL)
{
SListDelNonTailNode(g);//函数详情戳本篇博客开头的链接
}
else
{
free(g);
g = NULL;
}
return list;
}
12,【复杂链表的复制】,一个链表的每个节点,有一个next指针指向下一个结点,还有一个random指针指向这个链表中的一个随机结点,或者NULL,现在要求实现复制这个链表,返回复制后的新链表,首先给你复杂链表的结构
typedef struct ComplexListNode
{
int _data;
ComplexListNode* _next;//指向下一结点
ComplexListNode* _random;//随机指向一个结点
}ComplexListNode;
首先复制链表,并将结点挨个串起来,然后复制random指针,因为是挨着的,所以复制链表的random在原链表random的后面,将random复制好之后再将俩链表解开
ComplexListNode* CopyComplexList(ComplexListNode* list)
{
ComplexListNode* p = list;
while (p)//复制链表并将俩个链表串起来
{
ComplexListNode* pClone = NULL;
pClone->_data = p->_data;
pClone->_next = p->_next;
pClone->_random = NULL;
p->_next = pClone;
p = pClone->_next;
}
p = list;
ComplexListNode* pClone = NULL;
while(p)//克隆原链表的random指针
{
pClone = p->_next;
if (pClone->_random)
pClone->_random = p->_random->_next;//新链表的random指针是原先链表指针的random的下一个
p = pClone->_next;
}
p = list;
ComplexListNode* pClone = NULL;
ComplexListNode* pCloneList = NULL;
if (p != NULL)//头结点
{
pCloneList = p->_next;
pClone = p->_next;
p->_next = pClone->_next;
p = p->_next;
}
while (p)//将俩链表解开
{
pClone->_next = p->_next;
pCloneList->_next = pClone;
pClone = pClone->_next;
p->_next = pClone->_next;
p = p->_next;
}
return pCloneList;
}
如果有不对的地方,可以评论告诉我,望指导!