输入一个链表的头结点,从尾到头反过来打印每个结点的值。
链表的节点定义如下:
struct ListNode{
int value;
ListNode* next;
}
首先回顾一下链表的基本操作
链表的后插入:
//注意,传入的参数是指向指针的指针,而不是ListNode* phead,因为代码中需要对phead的值修改,传入一级指针导致函数退出结束作用域时,phead的实际值并未得到修改,就跟值交换函数一样,结束作用域后,实际值并未交换。
void AddToTail(ListNode** phead,int pvalue)
{
ListNode* padd=new ListNode();
padd->value=pvalue;
padd->next=nullptr;
if(*phead==nullptr){
*phead=padd;
}
else{
ListNode *it=*phead;
while(it->next!=nullptr){
it=it->next;
}
it->next=padd;
}
}
链表中给定值的删除:
void RemoveNode(ListNode** phead,int pvalue)
{
if(phead==nullptr||*phead==nullptr)
return;
ListNode* pToBeDel=nullptr;
if(*phead->value==pvalue){
pToBeDel=*phead;
}
else{
ListNode* it=*phead;
while(it->next!=nullptr&&it->next->value!=pvalue){
it=it->next;
}
if(it->next!=nullptr&&it->next->value==pvalue){
pTobeDel=it->next;
it->next=it->next->next;
}
}
if(pToBeDel!=nullptr)
{
delete pToBeDel;
pToBeDel=nullptr;//一定要注意让delete后的指针指向nullptr;
}
}
回顾了基本的链表操作之后就可以来考虑如何解决题目中给出的从后向前遍历链表的过程了,链表的结点结构告诉我们这是一个单链表的形式,因此从前往后遍历比较方便,但要求反向的的打印就比较困难了,如果前提是在遍历的过程中不能改变链表的结构,那么最容易想到的方法就是利用到其他的数据结构-栈(顺序遍历链表的过程中先把每个结点都保存在栈中,然后利用栈“后进先出”的特性,就可以达到先输出最后一个入栈的元素即链表的最后一个元素的目的),具体的代码如下:
1 #iinclude<iostream> 2 #include<stack> 3 using namespace std; 4 void PrintToTail(ListNode *phead) 5 { 6 stack<ListNode *> nodes; 7 ListNode* p=phead; 8 while(p!=nullptr){ 9 nodes.push(p); 10 p=p->next; 11 } 12 whlie(!nodes.empty()){ 13 int x=nodes.pop(); 14 cout<<x<<" "; 15 nodes.pop(); 16 } 17 cout<<endl; 18 }
实际上考虑到,每次打印结点时,先打印此结点的下一个结点,然后再打印本结点,这本身就是一个递归的过程,所以可以采用递归的方式来实现逆序的打印。具体代码如下:(但此方法有个缺点,当链表很长的时候,会导致函数的调用栈溢出,所以上述栈的方法更安全一些)
1 void PrintToTail(ListNode* phead) 2 { 3 if(phead!=nullptr) 4 { 5 if(phead->next!=nullptr){ 6 PrintToTail(phead->next); 7 } 8 cout<<phead->value<<" "; 9 } 10 cout<<endl; 11 }
原文:http://www.cnblogs.com/General-up/p/5399409.html