复试算法练习Day17——从头到尾打印链表

news2024/9/22 1:32:52

复试算法练习Day17——从头到尾打印链表

题目描述

输入一个链表的头节点,按链表从尾到头的顺序返回每个节点的值(用数组返回)。

如输入{1,2,3}的链表如下图:

img

返回一个数组为[3,2,1]

0 <= 链表长度 <= 10000

示例1

输入:

{1,2,3}

返回值:

[3,2,1]

示例2

输入:

{67,0,24,58}

返回值:

[58,24,0,67]

思路

思路一:虽然从头到尾输出比较简单,但是如果需要从尾到头打印链表,最好的方法就是直接把链表中的结点指针翻转过来,改变链表方向,就可以从头到尾输出,但是这样会改变链表数据结构。因此,可以考虑直接从头到尾输出数据后,把数据依次入栈,然后从栈中输出结果,这样就可以得到从尾到头的链表在数组中输出的结果了。

思路二:利用两个数组,首先建立链表然后把链表的数据输出到第一个数组,统计数组长度,然后利用两个相同的长度的数组,来互相首尾互换给出反转后的数据结果,输出即可得到从尾到头的数组。

具体实现

//利用栈FILO的原理,在不破坏链表结构的条件下,
//利用数组从尾到头逆序输出数据
#include <stdio.h>
#include <stdlib.h>
//链表初始化 
typedef struct _list{
	struct _list *next;
	int data;
}List;
//数据栈初始化
typedef struct _stack{
	int data[10];
	int top;
}Stack;
//入栈函数
int InitStack(Stack *s){
	if(s == NULL){
		return 0;
	}
	s->top = -1;
	
	return 1;
}
//链表插入函数
int Insert_list(List *list, int data){
	//如果链表为空,返回0
    if(list == NULL){
		return 0;
	}
	//否则开辟空间存放链表指针和链表节点
	List *node = (List *)malloc(sizeof(List)/sizeof(char));
	//如果节点为空,则返回0
	if(node == NULL){
		return 0;
	}
	//利用尾插法插入节点,并插入数据
	node->data = data;
	node->next = list->next;
	list->next = node;
	//结束后返回1
	return 1;
}
//利用栈打印链表元素
int Display(Stack *s, List *list) {
	//在栈指针为空且链表节点为空,输出0
    if(s == NULL || list == NULL){
		return 0;
	}
	//将链表数据依次入栈
	List *tmp = list->next;
	while(tmp){
		s->data[++s->top] = tmp->data;
		tmp = tmp->next;
	}
    //当栈满后,依次输出栈底元素
	while(s->top != -1){
		printf("%4d",s->data[s->top--]);
	}
	printf("\n");
	return 1;
}

 //递归打印链表元素
void r_display(List *list){
	//如果链表为空输出0
    if(list->next == NULL){
		return  0;
	}
    //否则多次递归输出节点内容   
	r_display(list->next);
	printf("%4d",list->next->data);
}
 
int main(){
    //栈空间初始化
	Stack *s = (Stack *)malloc(sizeof(Stack)/sizeof(char));
	if(s == NULL){
		return 0;
	}
    //置空栈
	InitStack(s);
	
    //链表空间初始化
	List *list = (List *)malloc(sizeof(List)/sizeof(char));
	if(list == NULL){
		return 0;
	}
	list->next = NULL;
    
    //链表头插法输入元素,后输入
	Insert_list(list,1);
	Insert_list(list,2);
	Insert_list(list,3);
	Insert_list(list,4);
	Insert_list(list,5);
	Insert_list(list,6);
	Insert_list(list,7);
	r_display(list);
	printf("\n");
	//Display(s,list);
	
	return 0;
}
 
 

//注意返回值必须初始化地址之后,才可以将链表节点释放
/**定义链表结构体
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

//建立反向输出函数后递归调用
int* reversePrint(struct ListNode* head, int* returnSize){
    //如果链表为空
    if(NULL == head){
        //返回值指针为0
        * returnSize = 0;
        return NULL;
    }
    
    //设置头结点指针
    struct ListNode *p = head;
    int count = 0;
    int i = 0;
    
    //数组空间初始化
    int* temp = (int*)malloc(sizeof(int) * 10000);
    int* res = (int*)malloc(sizeof(int) * 10000);
    //依次出入链表中数据
    while(NULL != p->next){
        temp[count] = p->val;  
        count++;  
        p = p->next;    
    }
    //数组内容计数
    temp[count] = p->val;
    count++;

    *returnSize = count;
    
    //将数组反转后调整内容对应输出
    for(i = 0;i < count;i++){
        res[i] = temp[count - 1 - i];
    }
    return res;
}

时间复杂度

对于方案一,采用栈的方法FILO输出,遍历一次即可,时间复杂度为O(n),设置栈空间与数组空间因此可以给出,本算法的空间复杂度为O(n)

对于方案二,采用建立两个数组的方法,输入一次链表内容时间复杂度为O(n),建立两个数组得到数组长度反转则其空间复杂度为O(n)

小结

总结:如果每次只考虑打印输出一个节点的值,那么这样的时间复杂度会为O(n^2),所以这种方法是不可取的。进而可以考虑采用栈这种数据类型就是先进后出,与题目中要求不谋而合,所以采用栈的方式去打印链表,利用递归方法,这样可以使你的代码变得很简洁,或者采用方法二,利用数组知道长度可以反转数组的特性,先顺序输出内容,后采用两个相同长度数组反转数组内容就可以得到从尾到头输出的链表中的数据,且数据保存在数组中,这种方法极大的考虑到了数组的用法,但是如果数组内容过大,其运算结果也会变慢,需要灵活处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/196521.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringMVC之JSON数据传输参数

目录 一&#xff1a;JSON普通数组 二&#xff1a;JSON对象数据 三&#xff1a;JSON对象数组 前面我们说过&#xff0c;现在比较流行的开发方式为异步调用。前后台以异步方式进行交换&#xff0c;传输的数据使用的是JSON,所以前端如果发送的是JSON数据&#xff0c;后端该如何…

C++11中的多线程的支持

C11中的多线程的支持 千禧年以后&#xff0c;主流的芯片厂商都开始生产多核处理器&#xff0c;所以并行编程越来越重要了。在C98中根本没有自己的一套多线程编程库,它采用的是C99中的POSIX标准的pthread库中的互斥锁,来完成多线程编程。 首先来简单一个概念:原子操作,即多线程…

目标检测框架在目标跟踪中的应用

目标检测框架在目标跟踪中的应用 从SiamRPN将跟踪问题定义为one-shot detection任务之后&#xff0c;出现了大量将检测组件由于跟踪的研究。不过Siamese系列一个很大的问题在于其本质仍然是一个模板匹配问题&#xff0c;网络关注的是寻找与target相似的东西&#xff0c;而忽视…

HCIA之数据发送过程

数据发送过程1、同广播域2、跨广播域&#xff08;需要将数据发送给网关&#xff0c;这通过路由器发包&#xff09;&#xff1a;总结1、同广播域 假设PC1要与PC2通讯&#xff1b; PC1不知道PC2的MAC地址&#xff0c;先发送ARP找到PC2的MAC地址&#xff1b; PC1知道了PC2的MAC地…

使用Python Seaborn绘制热力图(heatmap)的时候怎么改变配色

看到最近有些论文中会对Transformer encoder的attention weights进行可视化&#xff0c;通常会使用heatmap&#xff0c;我参考了一些博客&#xff0c;感觉已经总结得很详细了&#xff0c;例如这篇&#xff1a;python绘制热度图(heatmap)_黄思博呀的博客-CSDN博客_python heatma…

pm2:ecosystem.config.js

一、理解ecosystem.config.js1.1、字面理解&#xff1a;pm2生态系统配置文件。1.2、个人理解&#xff1a;pm2配置文件。类似于vite.config.ts、nuxt.config.ts。1.3、理解pm2&#xff1a;pm2 是一个带有负载均衡功能的Node应用的进程管理器。1.4、pm2的能力&#xff1a;1.4.1、…

【React】React入门(一)--React的创建、Jsx语法与组件以及状态(state)

&#x1f380;个人主页&#xff1a;努力学习前端知识的小羊 感谢你们的支持&#xff1a;收藏&#x1f384; 点赞&#x1f36c; 加关注&#x1fa90; 文章目录React简介react的特性虚拟Dom传统dom更新虚拟Domcreate-react-appJSX语法与组件jsx语法class组件函数组件组件嵌套组件…

基于Springboot搭建java项目(三十六)—— 服务监控工具WGCLOUD

服务监控工具WGCLOUD 一、服务监控 ​ “要想晚上睡的好&#xff0c;服务监控少不了”&#xff0c;服务器监控是应用程序开发中必不可少的一部分&#xff0c;做好服务监控有以下几个优点&#xff1a; 能够及时发现应用程序的漏洞能够定位到程序运行的瓶颈&#xff0c;查看程…

一篇搞懂SQL

前言 根据廖雪峰老师的教程&#xff0c;整理出一篇文章 一&#xff0c;为什么需要数据库&#xff1f; 小量的数据可以使用excel或者cvs存储&#xff0c;但是大批量的数据&#xff0c;这些都无法满足需求。如何管理这些数据就成了大问题。 所以&#xff0c;数据库作为一种专门…

机器视觉_HALCON_HDevelop用户指南_5.HDevelop过程(打磨ing)

文章目录五、HDevelop过程5.1. 过程类型5.2. 文件类型5.2.1. HDevelop程序5.2.2. 过程文件5.2.3. 库5.3. 过程作用域5.4. 过程位置5.5. 过程解析5.6. 受保护的过程5.7. 过程文档5.8. 即时编译&#x1f53a;五、HDevelop过程 Procedure&#xff1a; 在HDevelop文档中&#xff08…

【PyTorch】ImageNet数据集的使用和miniImageNet的构建

【PyTorch】ImageNet的使用和miniImageNet的构建1. ImageNet下载和简介1.1 下载地址1.2 初步处理1.3 devkit介绍2. miniImageNet2.1 miniImageNet的划分3. 使用ImageFolder构建数据集类3.1 重写DataFolder中的方法3.2 BatchSampler实现episode采样3.3 batch可视化1. ImageNet下…

Oracle数据库入门大全

oracle数据库 Oracle 数据库、实例、用户、表空间、表之间的关系 数据库 数据库是数据集合。Oracle是一种数据库管理系统&#xff0c;是一种关系型的数据库管理系统。 通常情况了我们称的“数据库”&#xff0c;并不仅指物理的数据集合&#xff0c;他包含物理数据、数据库管理…

let/const相关内容(五)

1.块级作用域的应用 &#xff08;一&#xff09;if-switch-for代码中的应用 ① if语句的代码就是块级作用域 // if语句的代码块是块级作用域 if (true) {var foo "foo"let bar "bar" }console.log(foo) console.log(bar);② switch语句的代码也是块级…

SQL面试题62--一种准确求近30天消费金额的方法

1 需求现在test表有三个字段 用户&#xff1a; user_id 日期&#xff1a;dt 订单金额 price&#xff0c;计算出一个消费者历史上“首次”在近30天周期内累计消费金额达到1W的日期2 分析&#xff08;1&#xff09;数据准备create table test as select a as user_id,7000 as pri…

数据分析很火吗?千万不要轻易尝试!

据说数据分析现在很火&#xff1f;“现在是数字化时代&#xff0c;工作生活都是与互联网交织在一起&#xff0c;我们的生活习惯、兴趣爱好等都会演变成各种不同的数据被互联网收集存储&#xff08;云存储&#xff09;。作为个人而言这些数据单看的话是没有什么价值和意义的&…

安全卫“视”!昂视助力极片卷绕对齐度检测

价格大涨、产能扩充、加速融资、加快出海、与车企深度绑定&#xff0c;动力电池产业在2022年表现出了极高的市场活力&#xff0c;在疫情的大环境之下&#xff0c;其发展势头是业内外公认的“高亢”。全国乘用车市场信息联席会预计&#xff0c;2023年新能源乘用车销量有望达850万…

SCI论文阅读-深度学习在测井气体红外光谱定量分析中的应用

期刊&#xff1a; Applied Optics中科院最新分区&#xff08;2022年12月最新版&#xff09;&#xff1a;4区影响因子&#xff08;2021-2022&#xff09;&#xff1a;1.905第一作者&#xff1a;宋丽梅通讯作者&#xff1a;Yangang Yang原文链接&#xff1a;Application of deep …

一文弄懂什么是对比学习(Contrastive Learning)

本文是自己学习对比学习的总结&#xff0c;如有问题&#xff0c;欢迎批评指正。 前言 有的paper将对比学习称为自监督学习&#xff08;Self-supervised learning&#xff09;&#xff0c;有的将其称为无监督学习&#xff08;Unsupervised Learning , UL&#xff09;。自监督学…

spring事务执行流程分析_6(事务的真正执行)

代理对象的执行 执行案例中的bookService.addUser(user);会调用到JdkDynamicAopProxy#invoke方法 JdkDynamicAopProxy#invoke public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object oldProxy null;boolean setProxyContext false;…

2023年黑马Java入门到精通教程--编程思维训练

编程案例分享 编程思维 使用所学的Java技术解决问题的思维方式和编写代码实现出来的能力。 关于提升编程思维和编程能力的建议 编程思维和编程能力不是一朝一夕形成的&#xff0c;需要时间的沉淀和大量练习。 前期&#xff1a;先模仿&#xff0c;后期&#xff1a;再创新。…