Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >二叉树中迭代序遍历的空间复杂度是多少?

二叉树中迭代序遍历的空间复杂度是多少?
EN

Stack Overflow用户
提问于 2018-07-15 02:29:12
回答 2查看 3.6K关注 0票数 5

我一直在想,二叉树的迭代前置遍历(使用堆栈)的空间复杂度是多少。我参考了节目采访的内容,他们说

空间复杂度是O(h),其中h是树的高度,因为除了堆栈的顶部之外,堆栈中的节点对应于从根开始的路径上的节点的正确子节点。

以下是供参考的守则:

代码语言:javascript
运行
AI代码解释
复制
struct Node{
   int data;
   struct Node* left, right;
}
void printPreOrder(struct Node* root){
  if(!root)
   return ;
  stack<struct Node* > s;
  s.push(root);
  while(!s.empty()){
     struct Node *root_element = s.top();
     cout<<root_element->data<<" ";
     s.pop();
      if(root_element->right){
         s.push(root_element->right);
      }
      if(root_element->left){
         s.push(root_element->left);
      }
     }
     cout<<endl;
  }
  return ;
}

我的直觉

在研究该算法时,我观察到,在任何实例中,堆栈中的最大条目数可以是最大(num_of_leaves_in_left_subtree+1,num_of_trees_in_right_subtree)。由此可以推断,对于高度为h的树,最大叶数可为2^ h,因此,左子树中的最大树数为2^(h-1)。因此,堆栈中的最大条目数为2^(h-1)+1。因此,根据我的说法,上述算法的空间复杂度为O(2^(log(N)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-07-15 13:14:01

首先,您的preorder traversal迭代实现有一个错误--您应该推送一个右节点,然后再推一个左节点,反之亦然。

现在解释一下--在每次迭代中,您都要深入一个层次,并在堆栈中添加2个元素(如果它们存在的话),同时弹出一个节点(父节点)。这意味着,最多增加一个新的元素时,你去一个级别下降。一旦到达最左边的节点并弹出它,就会对堆栈-> O(h)中的顶部节点重复相同的过程。

例如,

代码语言:javascript
运行
AI代码解释
复制
      1
     / \
   2     5
  / \   / \
 3   4 6   7

步骤0:1被添加到堆栈-> O(1)中

步骤1:1删除,2和5被添加-> O(2)

步骤2:2删除,3和4被添加-> O(3)

步骤3:3删除-> O(2)

步骤4:4删除-> O(1)

步骤5:5删除,6和7被添加-> O(2)

步骤6:6删除-> O(1)

步骤7:7已删除-> O(0)

正如你所看到的,空间复杂性总是与树的高度成正比。

在最坏的情况下(如果树看起来像列表),空间复杂性是O(1) for --您的实现(正如@Islam Muhammad所指出的),因为在while循环的每一次迭代中,都会从堆栈中删除一项,并添加一项(只有1子项)。

票数 9
EN

Stack Overflow用户

发布于 2018-07-15 06:24:51

让我们按顺序遍历算法来找出它。

尝试观察根节点处的整个树所需的最大堆栈大小将等于添加了1的左侧子树所需的堆栈的最大大小。

但是怎么做?

如果您仔细观察,您会发现,当我们处理根节点时,我们将向堆栈中添加右节点和左节点,然后将堆栈的顶部,即左侧节点进行处理。

因此,如果递归地定义用于查找所需堆栈的最大大小的函数,则如下所示:

代码语言:javascript
运行
AI代码解释
复制
function maxStackSizeReq(struct Node* root){
 if(!root)
    return 0; 
 return maxStackSizeReq(node->left)+1;
}

现在解释一下--在每次迭代中,您都要深入一个层次,并在堆栈中添加2个元素(如果它们存在的话),同时弹出一个节点(父节点)。这意味着,最多增加一个新的元素时,你去一个级别下降。一旦到达最左边的节点并弹出它,就会对堆栈-> O(h)中的顶部节点重复相同的过程。

例如,让我们尝试找出以下树所需的最大堆栈大小。

代码语言:javascript
运行
AI代码解释
复制
     1
     / \
   2     5
  / \   / 
 3   4 6   

步骤0:调用maxStackSizeReq(root_1) ->返回maxStackSizeReq(root_2)+1这里的意思是,所需堆栈的最大大小将是左子树+1所需的堆栈大小。

代码语言:javascript
运行
AI代码解释
复制
  2  
 / \  
3   4

步骤2:调用maxStackSizeReq(root_2) - > return maxStackSizeReq(root_3)+1这里的意思是,所需堆栈的最大大小将是左子树+1. 3所需的堆栈大小。

步骤3:在这里调用maxStackSizeReq(root_3) - > return maxStackSizeReq(root_3->left which is NULL)+1我们的意思是,所需堆栈的最大大小将是左子树所需的堆栈大小,即NULL + 1。

因此,步骤3返回1 -> 步骤2返回2 -> 步骤1返回3;

最后,函数将返回3作为处理根节点树的预顺序遍历所需的最大堆栈大小。

时间复杂度O(h)如何?,如果你仔细遵循上面的算法,你也会发现我们只遍历树的左子树。因此,当执行O(h)递归调用时,上述算法的空间复杂度为O(h)。最后,预序迭代堆栈实现的空间复杂度也将是O(h)。

记住

有时,您可能会听到预序或无序迭代解的空间复杂性是O(n)。但是,请记住,O(h)是一个更好的答案,因为空间复杂度仅为O(n),当h变为n时,这是相当明显的。

代码语言:javascript
运行
AI代码解释
复制
1
 \
  2
   \
    3
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51347487

复制
相关文章
网络请求优化——取消请求
我们可能会遇到这样的场景:当用户切换页面时,上个页面存在pending中的请求。积少成多,如此会造成性能浪费,增加服务器压力。本文在于分享基于小程序提供的请求api及 axios 使用中如何取消不必要的请求。
s4rn
2021/01/06
2.2K0
Volley请求
1. Volley简介 我们平时在开发Android应用的时候不可避免地都需要用到网络技术,而多数情况下应用程序都会使用HTTP协议来发送和接收网络数据。Android系统中主要提供了两种方式来进行HTTP通信,HttpURLConnection和HttpClient,几乎在任何项目的代码中我们都能看到这两个类的身影,使用率非常高。 不过HttpURLConnection和HttpClient的用法还是稍微有些复杂的,如果不进行适当封装的话,很容易就会写出不少重复代码。于是乎,一些Android网络通
xiangzhihong
2018/01/30
1.8K0
volley请求原理
Volley 实现原理解析 本文为 Android 开源项目实现原理解析 中 Volley 部分 项目地址:Volley,分析的版本:35ce778,Demo 地址:Volley Demo 分析者:grumoon,校对者:huxian99,校对状态:完成 1. 功能介绍 1.1. Volley Volley 是 Google 推出的 Android 异步网络请求框架和图片加载框架。在 Google I/O 2013 大会上发布。 名字由来:a burst or emission o
xiangzhihong
2018/01/30
2.2K0
浅谈Volley请求
先简单介绍一下Volley的诞生背景 Volley诞生于 2013年 Google I/O大会上 是Google开发工程师写的一个网络请求框架 特点是进行数据量不大,但通讯频繁的网络操作,内部还封装了图片加载的控件 NetworkImageView 用于直接在网络上面加载图片 本文只是对
后端码匠
2019/12/05
6820
浅谈Volley请求
Android Volley 源码解析(一),网络请求的执行流程
花了好几天,重新研究了 Volley 的源码实现,比起之前又有了一番新的体会,啃源码真的是一件让人纠结的事情,阅读优秀的源码,特别是难度相对较大的源码,一旦陷入代码细节或者情绪一烦躁,很容易让人奔溃,但是真正的啃下来,收获真的很大。从优秀的代码中学习优秀的编程思想以及良好的代码设计和代码风格是一个非常好的方法,这次通读了 Volley 的源码之后,对于 Volley 的代码质量和拓展性深感佩服,为了更好的记录这次的源码研究之旅,写几篇博客记录一下。
developerHaoz
2018/08/20
1.4K0
axios取消请求
在使用Axios发送请求时,有时可能需要取消请求,特别是在用户需要中断请求或离开当前页面时。Axios提供了取消请求的功能,以便有效地管理和处理请求的取消操作。
堕落飞鸟
2023/05/19
2.5K0
Volley网络连接
一、Volley a burst or emission of many things or a large amount at once Volley是Android平台上的网络通信库,能使网络通信更快,更简单,更健壮。 二、特点 异步任务下载图片的操作存在几个问题 1、  代码量大且繁琐 2、  ListView滚动太快,可能导致下载的图片无法正常显示 3、  可能浪费系统资源 4、  旋转屏幕可能导致再次下载 由此提出使用Volley替代 网络操作 但是只适合简单的网络操作: 1、  json/xml
听着music睡
2018/05/18
1.8K0
Volley使用JsonObjectRequest发送Post请求失败
这段时间一直在忙比赛,开发一个Android应用。转眼间博客竟然这么久没更新了,罪过罪过…这两天在用Volley框架,但是当我使用JsonObjectRequest发送Post请求时,竟然失效了。服务器一直响应失败,搞了半天,在StackOverFlow上找到了类似的问题,终于解决掉了。
零式的天空
2022/03/22
2.1K0
AJAX取消请求
在进行 AJAX(Asynchronous JavaScript and XML)请求时,有时候我们需要取消正在进行的请求。取消请求可以帮助我们提高用户体验,并减少不必要的网络流量和服务器负载。
堕落飞鸟
2023/05/19
2K0
axios 取消请求
官方文档:http://www.axios-js.com/zh-cn/docs/#%E5%8F%96%E6%B6%88
小鑫
2022/04/24
1.6K0
如何取消 Fetch 请求
JavaScript 的 promise一直是该语言的一大胜利——它们引发了异步编程的革命,极大地改善了 Web 性能。原生 promise 的一个缺点是,到目前为止,还没有可以取消 fetch 的真正方法。JavaScript 规范中添加了新的 AbortController,允许开发人员使用信号中止一个或多个 fetch 调用。
疯狂的技术宅
2020/03/26
2.4K0
如何取消 Fetch 请求
如何通过抓包分析EasyCVR级联时不回复上级平台的invite请求?
EasyCVR平台基于云边端协同架构,可支持多协议、多类型的海量设备接入与分发,平台既具备传统安防视频监控的能力,也具备接入AI智能分析的能力,在线下均有大量应用。
TSINGSEE青犀视频
2023/06/28
1820
Axios 取消重复请求
项目地址:https://github.com/Ewall1106/mall 有什么用? 当用户频繁点击在短时间内发送多个 ajax 请求,但是由于网络原因服务器数据无法及时响应返回,这时候,就会有可能造成前端页面数据不匹配的情况。 具体场景来说,在用户网速不好的情况下的比如搜索框 onchange 事件的模糊搜索、触底刷新请求列表数据、tab 栏的高频切换等等。 再者,这样也浪费服务器资源,也是性能优化的一种必要手段。 基本使用 官网地址:Axios-CancelToken 官网的基本示例如下。 c
Ewall
2020/11/12
1.5K0
取消(中止)异步请求
问题描述:动态获取图片宽、高。由于图片大小不一,导致异步请求返回时间有差异,频繁操作导致渲染结果出现问题。
奋飛
2021/12/30
1.2K0
取消(中止)异步请求
取消(中止)异步请求
问题描述:动态获取图片宽、高。由于图片大小不一,导致异步请求返回时间有差异,频繁操作导致渲染结果出现问题。
奋飛
2021/09/07
1.1K0
Android知识浅积累——Volley篇#Android网络框架Volley
http://blog.csdn.net/jdsjlzx/article/details/40738181
代码咖啡
2018/08/28
4830
Android知识浅积累——Volley篇#Android网络框架Volley
Carson带你学Android:主流开源网络请求库对比(Volley、OkHttp、Retrofit)
前言 网络请求在 Android 开发中非常常见,为了降低开发周期和难度,我们经常会选用网络请求的开源库 而现在网络请求的开源库越来越多,我们应该选用哪种呢? 今天我就给大家分别介绍 & 对比现今主流的网络请求库。 目录 1. 为什么要用网络请求开源库? 网络请求开源库是一个将 网络请求的相关功能封装好的类库 没有网络请求框架之前 App想与服务器进行网络请求交互是一件很痛苦的事:因为Android的主线程不能进行网络请求,需另开1个线程请求、考虑到线程池,缓存等一堆问题 使用网络请求库后
Carson.Ho
2022/03/24
6080
Carson带你学Android:主流开源网络请求库对比(Volley、OkHttp、Retrofit)
Android Volley完全解析(二),使用Volley加载网络图片
用户1158055
2018/01/05
1.3K0
Android Volley完全解析(二),使用Volley加载网络图片
当我们在谈免费游戏时
技术改变思想 本来不想用“当我们在谈XXX的时候,我们在谈什么”这种俗气的标题,但这个文章的内容,确实在一些人的想法里,还是有那么一点俗气的。所以用这个标题,也算文题对应吧。免费游戏,道具收费(Free To Play)作为一种游戏类型的存在,似乎是一个最近10年才开始的事情,但在中国,这种类型几乎成为了唯一的游戏类型。一切产品,都是因为有用户的市场需求才会存在,但是免费游戏这个市场,又是如何被挖掘出来的呢?——这对于看清楚免费游戏背后的用户需求,应该是有很多好处的。 2006年的某天,我的老板给我打了个
韩伟
2018/03/05
2.3K1
当我们在谈免费游戏时
点击加载更多

相似问题

如何使connect/express在特定目录上使用未过期的缓存?

21

过期后运行Javascript计时器

10

如何使NSIS RMDir在子目录上运行?

33

在多个子目录上运行代码

01

C#计时器-在计时器运行时运行代码

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档