面试题24:反转链表。定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点,链表节点定义如下:
struct ListNode {
int m_nValue;
ListNode* m_pNext;
};
对于链表中的任意一个节点,我们需要先保存它的下一个节点的值,再让它的m_pNext指针指向它的前一个节点,这就需要先保存它的前一个节点的指针值:
#include <iostream>
#include <stack>
using namespace std;
struct ListNode {
int m_nValue;
ListNode* m_pNext;
};
ListNode* ReverseList(ListNode* pHead) { // 反转链表
if (pHead == nullptr) {
return nullptr;
}
ListNode* preNode = nullptr;
ListNode* pNode = pHead;
ListNode* pReversedHead = nullptr;
while (pNode != nullptr) {
ListNode* pNext = pNode->m_pNext; // 找到当前节点的下一个节点
if (pNext == nullptr) { // 如果当前节点的下一个节点是空节点,说明pNode已经是原链表的尾节点
pReversedHead = pNode; // 原链表的尾节点即为反转后链表的头节点
}
pNode->m_pNext = preNode; // 使当前节点的下一节点指针指向前一节点
preNode = pNode; // 把当前节点记录为下一节点的前一节点
pNode = pNext; // 向后继续遍历链表
}
return pReversedHead;
}
void AddToTail(ListNode** pHead, int value) { // 尾插法
ListNode* pNew = new ListNode(); // 为新结点分配内存
pNew->m_nValue = value;
pNew->m_pNext = nullptr;
if (*pHead == nullptr) { // 如果是空链表
*pHead = pNew;
} else {
ListNode* pNode = *pHead;
while (pNode->m_pNext != nullptr) { // 找到链表末尾
pNode = pNode->m_pNext;
}
pNode->m_pNext = pNew; // 将链表末尾元素的指针指向新节点
}
}
void printListReversingly_iteratively(ListNode* pHead) {
stack<ListNode*> nodes;
ListNode* pNode = pHead;
while (pNode != nullptr) { // 将链表从头到尾压栈
nodes.push(pNode);
pNode = pNode->m_pNext;
}
while (!nodes.empty()) { // 打印栈中内容
cout << nodes.top()->m_nValue << endl; // 打印栈顶值
nodes.pop(); // 栈顶元素出栈
}
}
int main() {
ListNode* pHead = new ListNode();
pHead->m_nValue = 0;
pHead->m_pNext = nullptr;
AddToTail(&pHead, 1);
AddToTail(&pHead, 2);
AddToTail(&pHead, 3);
AddToTail(&pHead, 4);
AddToTail(&pHead, 5);
AddToTail(&pHead, 6);
AddToTail(&pHead, 7);
printListReversingly_iteratively(ReverseList(pHead));
}