这篇文章是在上一篇的基础上完成的
1.删除无头链表的非尾结点。
解题思路:因为不知道pos的前一个结点,所以只能删除pos的后一个结点。
首先,把pos下一个结点的data赋值给pos的data,然后把pos和pos的下下一个结点连接,最后删除pos的下一个结点。
刚开始的链表如下图所示:
经分析后得到的图如下:
代码如下:
void EraseNotTail(PLinkNode pos)
{
PLinkNode del=NULL;
assert(pos->next !=NULL);
del=pos->next ;
pos->data =pos->next ->data ;
pos->next =del->next ;
free(del);
del=NULL;
}
2.反转链表
例如:1->2->3->4->5反转后为5->4->3->2->1
解题思路:让1的下一结点为空,让2的指向1,3指向2,一次类推为5->4->3->2->1,在循环中实现,最后让5为头指针。
第一次循环后图为黑线第二次循环后图为粉线如下所示:
代码为:
void ReverseList(PLinkList PList)
{
PLinkNode newHead=NULL;
PLinkNode cur=NULL;
assert(PList);
cur=PList->pHead ;
while(cur)
{
PLinkNode tmp=cur;
cur=cur->next ;
tmp->next =newHead;
newHead=tmp;
}
PList->pHead =newHead;
}
3.在当前结点前插入x。
解题思路:先要创建一个结点,data为x,因为不知道pos的前一个结点,所以把新节点连接到pos后,然后交换data,就好了。
图如下所示:在1前插入2,原来是1->3->4最后为2->1->3->4.
void InsetFrontNode(PLinkNode pos,DataType x)
{
DataType tmp=NULL;
PLinkNode newNode=NULL;
assert(pos);
newNode =BuyNode(x);
newNode->next =pos->next ;
pos->next =newNode;
tmp=pos->data ;
pos->data =newNode->data ;
newNode->data =tmp;
}
4.查找链表的中间结点。
解题思路:在只能遍历一次的情况下,定义一个快指针和一个慢指针,快指针一次走两步,慢指针一次走一步,同时出发当快指针走到最后一个结点时,慢指针走到的位置就是中间位置。
PLinkNode FindMidNode(PLinkList PList)
{
PLinkNode fast=NULL;
PLinkNode slow=NULL;
assert(PList->pHead );
fast=PList->pHead ;
slow=PList->pHead ;
while(fast&&fast->next )
{
fast=fast->next ->next ;
slow=slow->next ;
}
return slow;
}
更多的链表面试题,欢迎关注后面的博客。
谢谢!