笔者遇到单链表反转问题时,是这样思考的,将链表分为两部分,作为lis1 和 list2 ,然后将list2的节点逐个插入到表头head 后面第一个元素前面,整个过程示意图如下:
1、节点node由data 和 next 指针组成,链表list A——>B——>C——>D
2、将list分为两部分 list1 A,list2 B——>C——>D
3、将list2的B插到head后面作为第一个元素
4、形成list1 B——>A 和list2 C——>D
重复步骤3、4 完成整个链表的反转。
具体代码如下:
void list_reverse(linklist H)
{
linklist p,q;
if((H->next == NULL) || (H->next->next == NULL)) //只有head或head+node无需反转。
{
return ;
}
else
{
p = H->next->next; //将链表分为两部分。H:list1,p:list2的node1
H->next->next = NULL; //将list1 node1的next置空作为后续循环结束的条件
while(p!= NULL) //如果list2有元素
{
q = p->next; //q 记录list2
p->next = H->next; //将list2的元素依次插入到 H表头后面(即list1 node1前面
H->next = p;
p = q;
}
}
}
测试结果如图:
但是笔者在写代码时突然想到自己思考复杂了,其实可以将链表分为 list1 head 和list2 A——>B——>C——>D这样的两部分而不是 list1 A,list2 B——>C——>D。这样代码更简洁,具体代码如下:
void list_reverse(linklist H)
{
linklist p,q;
p = H->next; //p指向list2的node1
H->next = NULL; //将head的next置空,不再指向 第一个元素
while(p)
{
q = p; //利用q记录list2的node1
p = p->next; //p始终指向list2的第一个元素
q->next = H->next;
H->next = q;
}
}
测试结果如下:
反思:
思维的局限性导致代码冗余
总想着少移动元素,结果代码更复杂。