由一道题看链表指针的反转、栈操作(递归)

题目:输入一个链表,从尾到头打印链表每个节点的值。(题目来自剑指offer)

1.首先问面试官是否可以改变原来链表的结构。因为我们看到题目一般都会想到到将链表中的指针反转过来。如果可以则代码如下:

知识点:1.创建链表;2.遍历链表;3.反转结点指针

<span style="color:#333333;">#include <iostream>
 #include <vector>
 using namespace std; 
 struct ListNode {
        int val;
        struct ListNode *next;
        //ListNode(int x) :val(x), next(NULL) {}
  };
  //新建链表
ListNode* creat_list()
{
	int i,j,len;
	cout<<"请输入您要生成链表的结点个数:len=";
	cin>>len;
	int val;
	
	cout<<"请输入第一个节点:";
	cin>>val;
	ListNode *head=new ListNode;
	if(head==NULL)
    	{
    		cout<<"分配失败,程序终止!"<<endl;
    		exit(-1); 
	    }
	head->val =val;
	head->next =NULL;
    ListNode *ptemp=head;
	
	for(i=1;i<len;i++)
	{
		cout<<"输入第"<<i+1<<"个结点:";
    	cin>>val;
		ListNode *pnew=new ListNode;  //	ListNode *head=(ListNode*)malloc(sizeof(ListNode)); //</span><span style="color:#ff0000;"><strong>new和malloc用法</strong></span><span style="color:#333333;">
    	if(pnew==NULL)
    	{
    		cout<<"分配失败,程序终止!"<<endl;
    		exit(-1); 
	    }
	    ptemp->next =pnew;
        pnew->val =val;
        pnew->next =NULL;
        ptemp=pnew;
	 } 
    return head;
 } 
 //遍历链表输出
 void traverse_list(ListNode *head)
{
	ListNode *p=head;
	while(NULL!=p)
	{
		cout<<p->val<<" ";
		p=p->next;
    }
	cout<<endl;
	
	return;  //告诉别人函数执行完毕 
}

ListNode * printListFromTailToHead(struct ListNode* head)  //</span><span style="color:#ff0000;"><strong>反转链表中的指针</strong></span><span style="color:#333333;">
  {
        //if(head==NULL)   return =-1;
        ListNode *p1,*p2,*p3;
        p1=head;
        p2=p1->next;
        p3=p1->next->next;
        p2->next=p1;
        head->next=NULL;
        while(p3!=NULL)
            {
            p1=p2;
            p2=p3;
            p3=p2->next;
            p2->next=p1;   
        }
        return p2;
}
    
int main()
{
	ListNode *head;
	head=creat_list();
	traverse_list(head);
	head=printListFromTailToHead(head);
	traverse_list(head);
	return 0;
}</span>

代码已通过编译,运行正确。

2.如果不能改变原来链表的结构

(1).栈

知识点:1.如何定义栈;2.栈的相关函数:入栈、出栈、是否为空、取栈顶元素;

<span style="color:#333333;">void printListFromTailToHead(struct ListNode* head)
  {
        stack<ListNode *> s;   //</span><span style="color:#ff0000;"><strong>定义栈</strong></span><span style="color:#333333;">的方法,头文件需要加上#include <iostream>
        ListNode *p=head;
        while(p!=NULL)
            {
            s.push(p);
            p=p->next;
        }
        while(!s.empty())
        {
        	p=s.top();
        	cout<<p->val<<" ";
        	s.pop();
		}
}</span>

要求函数的返回值已固定

vector<int> printListFromTailToHead(struct ListNode* head) {
        vector<int> arr;   //<span style="color:#ff0000;">定义容器</span>
        stack<ListNode *> s;   //定义栈的方法,头文件需要加上#include <iostream>
        ListNode *p=head;
        while(p!=NULL)
            {
            s.push(p);
            p=p->next;
        }
        while(!s.empty())
        {
        	p=s.top();
        	arr.push_back(p->val);  //<span style="color:#ff0000;">放入容器</span>
                s.pop();
		}
        return arr;   //<span style="color:#ff0000;">返回容器</span>
    }

代码通过编译运行。


(2).递归:递归在本质上就是一个栈结构,能用栈就可以用递归。

void printListFromTailToHead(struct ListNode* head)
  {
        if(head!=NULL)
        {
        	if(head->next !=NULL)
        	    printListFromTailToHead(head->next);
		}
		cout<<head->val<<" ";
}

(3).直接调用库函数

知识点:arr.insert(position,数值):将数值拷贝插入到由position指定的位置上

vector<int> printListFromTailToHead(struct ListNode* head) {
        vector<int> arr;
        ListNode *p=head;
        while(p!=NULL)
            {
            arr.insert(arr.begin(),p->val);    //调用vector中函数insert,将元素始终插入第一个位置,使得最后一个结点值在第一个位置。
            p=p->next;
        }
        return arr;
    }


其他


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值