1.题目:定义一个函数,输入链表的头节点,输出翻转该链表的头节点。
结果:
链表定义如下:
struct ListNode
{
int m_nValue;
ListNode* m_pNext;
};
分析:
翻转一个链表,其实就是调整链表中指针的指向,翻转的过程中为了避免断链,需要三个指针,当前节点的指针,当前节点的下一个结点的指针,当前节点的上一个结点的指针。如下面图示:
对于链表中的单个结点h,i,j。i为当前的结点,i需要知道前一个节点的地址,然后可以指向它,指向之后i的地址和i之后的地址也要知道,才不会断开。
源码:
/*将链表逆序*/
#include<iostream>
using namespace std;
struct ListNode
{
int m_nValue;
ListNode* m_pNext;
};
//创建一个节点
ListNode* CreateListNode(int value)
{
ListNode* pNode = new ListNode();
pNode->m_nValue = value;
pNode->m_pNext = NULL;
return pNode;
}
//打印整个链表
void PrintList(ListNode* pHead)
{
printf("PrintList starts.\n");
ListNode* pNode = pHead;
while (pNode != NULL)
{
printf("%d\t", pNode->m_nValue);
pNode = pNode->m_pNext;
}
printf("\nPrintList ends.\n");
}
//打印结点的值
void PrintListNode(ListNode* pNode)
{
if (pNode == NULL)
{
printf("The node is NULL\n");
}
else
{
printf("The key in node is %d.\n", pNode->m_nValue);
}
}
//将两个结点连接起来
void ConnectListNodes(ListNode* pCurrent, ListNode* pNext)
{
if (pCurrent == NULL)
{
printf("Error to connect two nodes.\n");
exit(1);
}
pCurrent->m_pNext = pNext;
}
//销毁链表
void DestroyList(ListNode* pHead)
{
ListNode* pNode = pHead;
while (pNode != NULL)
{
pHead = pHead->m_pNext;
delete pNode;
pNode = pHead;
}
}
//逆序链表
ListNode* ReverseList(ListNode* pHead)
{
ListNode* pReversedHead = NULL;
ListNode* pNode = pHead;
ListNode* pPrev = NULL;
while (pNode != NULL)
{
ListNode* pNext = pNode->m_pNext;
if (pNext == NULL)//如果pNode当前指向的是尾结点
pReversedHead = pNode;
pNode->m_pNext = pPrev;
pPrev = pNode;
pNode = pNext;
}
return pReversedHead;
}
int main()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
printf("原始链表\n");
PrintList(pNode1);
printf("翻转之后的链表\n");
ListNode* result = ReverseList(pNode1);
PrintList(result);
system("PAUSE");
return 0;
}
结果: