比如单链表A -> B -> C -> D -> E -> F -> NULL 反转得到 F -> E -> D -> C -> B -> A -> NULL
【算法一】
最通用的算法,对于当前要反转的节点,在反转过程中牵扯到3个节点:前继节点(pPre)、当前节点(pCur)、后继结点(pNext),当然在算法实现的过程中有时候多增加一些变量能带来事半功倍的效果,在这里我们额外定义一个指针变量,用来保存反转后的头节点(pReversedHead),反转的过程实际上就是把当前节点的next指针指向前继节点,后继结点用来保证链表不断裂,所以预设3个指针,步步向前移动,直至NULL,然后返回尾节点的地址。
由于遍历一次可完成反转,时间复杂度为O(n)。
listnode* ReverseLinklist(listnode* pHead)
{
linknode* pReversedHead = NULL;
linknode* pb = NULL; //前继节点
linknode* pc = pHead; //当前节点
linknode* pa = NULL; //后继节点
while(pc != NULL)
{
pa = pc->next;
//如果当前节点的后继结点为NULL,则说明当前节点即为尾节点
if(pa == NULL)
{
pReversedHead = pc;
}
pc->next = pb;
pb = pc;
pc = pa;
}
return pReversedHead;
}
【算法二】
递归法。
优点:代码精简。
缺点:不易理解,且如果链表很长容易导致栈溢出。
Node *ReverseList(Node *p,Node *head)
{
Node *tmp;
if(p->next == NULL)
{
head->next = p;
return p;
}
tmp = ReverseList(p->next,head);
tmp->next = p;
p->next = NULL;
return p;
}