题目:定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。
思路:如果全部改变指针指向,则可以反转链表,那么对当前结点,要指向它前面的结点,同时它的下一节点要在下一步中指向自己,所以函数没执行一步,需要前一结点和下一结点,防止链表断裂。当前结点的下一结点为NULL时,表明已经到尾结点,执行过程结束,同时将尾结点置为新的表头。
ListNode* ReverseList(ListNode* pListHead)
{
ListNode* pReverseHead = NULL;
ListNode* pNode = pListHead;
ListNode* pPrev = NULL;
while(pNode != NULL)
{
ListNode* pNext = pNode->m_pNext;
if(pNext == NULL)
pReverseHead = pNode;
pNode->m_pNext = pPrev;
pPrev = pNode;
pNode = pNext;
}
return pReverseHead;
}
问题扩展:用递归实现同样的反转链表的功能。
思路:问题细分,假设头结点后面的链表已经反转,只要将头结点插入到子链表后尾部就可以了。也就是将子链表的尾结点指向头结点。在寻找子链表尾结点的时候犯了一点错误,一开始用的方法是遍历子链表寻找尾结点。实际上尾结点就是头结点的下一结点。错误的根源是我以为头结点和子链表已经断开,所以无法直接获取头结点的下一结点。实际上由于利用了递归算法,链表的反转是从表尾开始的,直到后面n-1个结点已经反转了头结点仍然是指向它在原链表中的下一结点的。
ListNode* ReverseList(ListNode* pListHead)
{
if(pListHead == NULL || pListHead->m_pNext == NULL)
return pListHead;
else
{
ListNode* NewHead = ReverseList(pListHead->m_pNext);
pListHead->m_pNext->m_pNext = pListHead;
pListHead->m_pNext = NULL;
return NewHead;
}
}