题目描述:输入一个链表,反转链表后,输出新链表的表头。
一、利用栈(空间效率低)
利用栈stack容器后进先出:
1.将链表从头到尾遍历放入stack中;
2.栈依次弹出元素赋给下一个结点值,指针指向下一个结点;
2.然后改变结点指针指向前一个位置,即完成反转。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if(pHead==NULL||pHead->next==NULL) return pHead;//考虑全面,提高鲁棒性
stack <ListNode*> stack1;//利用栈,从头遍历链表存入栈中,利用栈的后进先出
while(pHead->next!=NULL)
{
stack1.push(pHead);
pHead=pHead->next;
}
/*此时stack1栈顶层就是链表尾部*/
/*pHead指向链表最后一个位置*/
ListNode* ptr=pHead;
while(!stack1.empty())//将栈中元素依次弹出,最底下是链表头
{
pHead->next=stack1.top();//pHead->next本来为NULL了,栈依次弹出元素赋给下一个结点值
pHead=pHead->next;//指针指向下一个结点,即原来链表的尾
stack1.pop();//删除栈顶,依次让pHead指向下一个
}//其实就是将链表倒过来,即结点的指针指向前一个
pHead->next=NULL;//最后,让pHead指向的内容为NULL
return ptr;
}
};
二、指针移动解法
需要三个指针,分别指向当前结点、前一个节点、下一个结点;
(1)*pre、*pHead、*pNext
pre=nullptr;
pNext=nullptr;
(2)pNext由null转为指向当前结点下一个
pnext=pHead->next;//pnext指针初始为NULL,此时让它指向pHead的下一个结点
(3)“核心语句”
pHead->next=pre;//切断pHead与下一结点关联,让pHead的next指针指向前一个结点,完成反转
(4)三个节点向后移动,操作下一个
pre=pHead;//三个指针位置依次向后移动,当前结点是下一个的前一个,
pHead=pnext;//下一个结点变成要操作的结点(操作:切断与下一结点关联,指向前一个结点)
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if(pHead==NULL||pHead->next==NULL) return pHead;//链表头指针为空或只有一个节点
/*需要三个指针,分别指向当前遍历结点、前一个、后一个*/
ListNode* pre=nullptr;//前一个
ListNode* pnext=nullptr;//后一个
while(pHead!=NULL)
{
pnext=pHead->next;//pnext指针初始为NULL,此时让它指向pHead的下一个结点
pHead->next=pre;//“核心语句”切断pHead与下一结点关联,让pHead的next指针指向前一个结点,完成反转
pre=pHead;//三个指针位置依次向后移动,当前结点是下一个的前一个,
pHead=pnext;//下一个结点变成要操作的结点(操作:切断与下一结点关联,指向前一个结点)
}
return pre;//依次向后移动指针,循环终止pHead为NULL,此时pre指针恰好指向链表尾
}
};