题目:
输入一个链表,从尾到头打印链表每个节点的值。
问题解析:
*链表是动态数据结构,找其某个值,只能从头结点开始。后进先出结构。
链接:
剑指Offer(第2版):P58
思路标签:
数据结构:链表、栈、vector
算法:递归
解答:
1. C++
- (1) 从头到尾输出比较简单,一种想法是反转结点的指针。但是会破坏原链表的结构,不推荐;
- (2) 从头遍历链表,先访问的后输出,后访问的先输出,“后进先出”,利用栈来实现;
- (3) 递归本质上就是一个栈的结构,可以利用递归来实现。但是当链表比较长的时候,递归会导致函数调用的层级很深,有可能会导致函数调用栈的溢出,故还是推荐使用栈来实现。
栈的实现:
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) :
* val(x), next(NULL) {
* }
* };
*/
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
std::vector<int> values;
std::stack<ListNode*> nodes;
ListNode* pNode = head;
while(pNode != nullptr){
nodes.push(pNode);
pNode = pNode->next;
}
while(!nodes.empty()){
pNode = nodes.top();
values.push_back(pNode->val);
nodes.pop();
}
return values;
}
};
递归实现::
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
std::vector<int> values;
if(head != nullptr){
if(head->next != nullptr){
printListFromTailToHead(head->next);
}
values.push_back(head->val);
}
return values;
}
};
链表其他操作:
// 在末尾加入新的结点
void AddToTail(ListNode** pHead, int value){
ListNode* pNew = new ListNode();
pNew->val = value;
pNew->next = nullptr;
if (*pHead == nullptr){
*pHead = pNew;
}else{
ListNode* pNode = *pHead;
while(pNode->next != nullptr)
pNode = pNode->next;
pNode->next = pNew;
}
return;
}
// 删除某个值为value的结点
void RemoveNode(ListNode** pHead, int value){
if(pHead == nullptr || *pHead == nullptr) return;
ListNode* pToDeleted = nullptr;
if((*pHead)->val == value){
pToDeleted = *pHead;
*pHead = (*pHead)->next;
}else{
ListNode* pNode = *pHead;
while(pNode->next != nullptr && pNode->next->val != value)
pNode = pNode->next;
if(pNode->next != nullptr && pNode->next->val == value){
pToDeleted = pNode->next;
pNode->next = pNode->next->next;
}
}
if(pToDeleted != nullptr){
delete pToDeleted;
pToDeleted = nullptr;
}
return;
}
C++相关:
链表添加函数中为什么要用指向链表指针的指针: