目录
1.链表的逆置
给定链表如下:
给定链表如上图:将除了头节点以外的其他节点依次成为0号节点,1号节点等等。
要想完成链表的逆置,可以从1号这个节点开始一直头插,即将1号节点插入到头节点后边,再将2号节点插入到头节点后边,依次直到将最后一个节点头插完毕,此时0节点的next为nullptr,这个时候,链表的逆置就完成了。
先定义p指针指向头节点下一个节点,也就是0节点;再来判断p是否还有下一个节点。如果p后面没有任何元素了,那么说明链表只有一个节点,就不需要逆置了。如果p后面还有元素,那么就要进行下一步操作:将p的next赋值给q;让q指向要头插的节点。
(1):先将p->next赋值为q->next;防止q后面的节点丢失;(图中绿色部分)
(2):再将q与head后面的节点连接起来,也就是将q->next赋值为phead.next;
(图中黄色部分)
(3):再将q与head连接起来,phead.next=q;(蓝色部分)
这个时候就已经完成第一个节点的头插了;
整理一下:
接着,让q继续往后跑,也就是q=p->next;
一直重复上述操作,一直到原来链表的第一个节点的next为nullptr;也就是一直到p->next==nullptr
到此链表的逆置就已经完成了。
代码实现:
bool Contrary(List& phead) //逆置
{
if (phead.next ==nullptr)
{
return false;
}
List* p = phead.next;
List* q = nullptr;
if (p->next != nullptr)
{
q = p->next;
while (q != nullptr)
{
p->next = q->next;
q->next = phead.next;
phead.next = q;
q = p->next;
}
}
return true;
}
看一眼结果
2.查找单链表倒数第k个元素
对于双向循环链表来说,查找倒数第k个元素很容易,但是对于单链表而言,就显得稍微有点麻烦。我们还是用刚才的链表来举例:
如果给了链表的长度,或者说允许计算链表的长度,那么这个问题就很简单了;
倒数第k个节点也就是正数第(长度-k+1)个节点。
如果不允许去计算链表的长度的话,可以这样想:先将整个链表逆置,这样的话就是去找正数第k个节点了。找到节点就可以对其进行操作(删除,修改等等);
//找到倒数第k个节点
int Reciprocal(List& p, int k)
{
if (p.next == nullptr)
{
return -1;
}
List* q = p.next;
List* ql = nullptr;
if (q->next != nullptr)
{
ql=q->next;
while (ql != nullptr)
{
q->next = ql->next;
ql->next = p.next;
p.next = ql;
ql = q->next;
}
}
List* qq = p.next;
if (qq == nullptr)
{
return 0;
}
for (int i = 0; i < k-1; ++i)
{
qq = qq->next;
}
return qq->data;
}
先逆置,再进行遍历,查找。
第二种方法也比较好理解:
定义俩个指针,让其中一个先先后走k步,也就是q=q->next先执行k次,然后再让俩个指针同步向后走。当q走到最后一个节点的时候,ql指向的就是要查找的节点!
代码实现:
List* Reciprocal(List& p, int k)
{
List* q = p.next;
List* ql = p.next;
for (int i = 0; i < k; ++i)
{
q = q->next;
}
while (q != nullptr)
{
q = q->next;
ql = ql->next;
}
return ql;
}
以上就是单链表的逆置和查找倒数第k个元素的方法。
感谢阅读!