【无标题】面试常考算法(3):二叉树遍历(创建、遍历、销毁)

news/2024/11/7 7:53:03/

这部分不够熟悉的话,面试直接递归就行。不过实际中虽然递归在某些情况下可以提供简洁和优雅的解决方案,但可能占用大量的内存空间和导致额外时间开销,所以还是尽量使用非递归。因为每次递归调用时,函数的局部变量和参数都需要在栈上创建新的实例,这可能导致栈溢出或耗尽系统资源,尤其是当递归深度很大时。而且递归调用的开销包括函数调用、堆栈帧的创建和销毁等,大规模问题上使用递归可能导致时间性能下降

目录

  • 二叉树中序遍历

对于其他的遍历,只需要画个树写写递归伪代码,和

二叉树中序遍历

  给定一个二叉树的根节点root,返回它的中序遍历(“左根右”)结果。
  数据范围: 树上节点数满足 0 ≤ n ≤ 1000 0 \leq n \leq 1000 0n1000 ,树上每个节点的值满足 − 1000 ≤ v a l ≤ 1000 -1000 \leq v a l \leq 1000 1000val1000
  要求:空间复杂度 O ( n ) O(n) O(n) ,时间复杂度 O ( n ) O(n) O(n)

树节点:struct类型数据有聚合初始化(Aggregate initialization)、默认成员初始化和成员初始化列表(Member initialization list)等初始化方法,这里自定义构造函数以便使用成员初始化列表初始化

struct TreeNode {int val;struct TreeNode* left;struct TreeNode* right;TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}  //自定义构造函数以便使用成员初始化列表初始化
};
}

创建树和销毁树:

//递归法构建二叉树
int n; 
TreeNode* creatTree(vector<int> nums, int index) {// 二叉树结点x(x指该节点在C++数组中的索引位置)的左孩子在C++数组中的位置等于 2x+1 ,右孩子等于 2x+2 。if (nums[index] == '#')return nullptr;//创建新结点TreeNode* root= new TreeNode(nums[index]);printf("The value is %d \n", nums[index]);//设置左右指针if (index * 2+1 <= n)root->left = creatTree(nums, index * 2+1);	//找到左孩子elseroot->left = nullptr;if (index * 2 + 2 <= n)root->right = creatTree(nums, index * 2 + 2);	//找到右孩子elseroot->right = nullptr;return root;
}// 注意创建树后不用了需要销毁,这里得手动释放空间
void destroyTree(TreeNode* node) {if (node == nullptr) {return;}destroyTree(node->left);destroyTree(node->right);printf("destroy node value is %d \n", node->val);delete node;
}

两种实现中序遍历的方法:利用栈非递归,递归

vector<int> inorderTraversal(TreeNode* root) {  //非递归方法vector<int> res;  // 存放中序遍历的输出值stack<TreeNode*> st;  // 栈中存放结点TreeNode* p = root;while (!st.empty() || p)  // p等于空说明根节点为空或者到了叶子节点的某个空子节点{// 循环条件为 【st非空 或者 p指向确定对象时(使用指针变量进行条件判断时,当指针变量为nullptr时,条件判断为假)】// 终止条件为 【st为空,且p等于nullptr】while (p)                //一直沿左子树向下{st.push(p);  // 由于st是栈,父节点先进入,后出p = p->left;}TreeNode* tt = st.top();   //到达叶子节点的某个空子节点,返回st.pop();res.push_back(tt->val);p = tt->right;  // 去检查右节点}return res;
}void inorder(vector<int>& res, TreeNode* root) {//遇到空节点则返回if (root == NULL)return;//先遍历左子树inorder(res, root->left);//再遍历根节点res.push_back(root->val);//最后遍历右子树inorder(res, root->right);
}vector<int> inorderTraversal2(TreeNode* root) {vector<int> res;//递归中序遍历inorder(res, root);return res;
}

main函数测试:

int main() {// 创建一颗树{1,2,#,#,3}vector<int> nums = { 1,2,'#','#',3 };n = nums.size();TreeNode* root = creatTree(nums, 0);vector<int> Non_recursice_res = inorderTraversal(root);cout << "非递归中序遍历:" << ' ';for (auto& element : Non_recursice_res) {std::cout << element << " ";}std::cout << std::endl;vector<int> recursice_res = inorderTraversal(root);cout<< "递归中序遍历:" << ' ';for (auto& element : recursice_res) {std::cout << element << " ";}std::cout << std::endl;destroyTree(root);
}

测试结果:
在这里插入图片描述


http://www.ppmy.cn/news/404121.html

相关文章

VBA基础(宏编程)

VBA介绍&#xff1a; Visual Basic for Applications&#xff08;VBA&#xff09;是 VisualBasic 的一种宏语言&#xff0c;是微软开发出来在其桌面应用程序中执行通用的自动化(OLE)任务的编程语言。主要能用来扩展 Windows 的应用程序功能&#xff0c;特别是Microsoft Office…

360全景拍摄为什么要使用鱼眼镜头,与超广角镜头区别?

360全景摄影&#xff0c;通常使用8mm至15mm鱼眼镜头。360全景摄影之后以一定要选择鱼眼镜头进行360全景摄影&#xff0c;其主要原因为了单张照片拍摄到较大的视角范围&#xff0c;从而以较少的照片拼接成一个360全景图。 使用8mm鱼眼镜头&#xff0c;360全景摄影少则拍摄…

vue3+ts+vite+element plus中使用luckysheet(预览效果)

前言&#xff1a; 这两天一个项目&#xff0c;需要在页面中以excel的形式展示大量数据&#xff0c;喜欢偷懒的我果断扒拉了一堆适用于vue3的插件&#xff0c;下面简单说说我使用的luckysheet 使用&#xff1a; 一、准备一个vue3tsviteelement plus的项目 此处省略n个字。。。…

618父亲节,感恩的祝福送给父亲!

父亲节&#xff08;Fathers Day&#xff09;&#xff0c;是感恩父亲的节日。Fathers day, is a day of thanksgiving for fathers. 第一个提出父亲节理念的人是1906年的多德夫人。她想用一个特殊的日子来纪念她的父亲&#xff0c;她的妈妈多年前就去世了。起初&#xff0c;多德…

【闭包函数与装饰器大全】——python基础

目录索引 闭包&#xff1a;闭包三要素&#xff1a;闭包的作用&#xff1a;闭包演示&#xff1a;闭包的意义&#xff1a; 装饰器&#xff1a;特点&#xff1a;实例演示&#xff1a;实例演示2之参数&#xff1a; 装饰器常用的场景&#xff1a;编写一个计时的装饰器&#xff1a;*普…

实测Maven依赖包可通过域名抢注实现钓鱼攻击吗

先说结论&#xff1a;基本不可行 原理 Maven包中 groupId 字段是域名反写&#xff0c;比如你有一个 12345.com&#xff0c;就可以申请到 com.12345 的groupId。 很多开源项目都停止维护&#xff0c;但是很多人使用&#xff0c;这些团队可能忘记续费域名&#xff1b;同时目前…

永久存储:文件处理与路径处理

&#x1f4e2;博客主页&#xff1a;盾山狂热粉的博客_CSDN博客-C、C语言,机器视觉领域博主&#x1f4e2;努力努力再努力嗷~~~✨ &#x1f4a1;大纲 ⭕如何将数据永久的存放到硬盘上 &#x1f449;不要打开文件&#xff0c;然后直接关闭文件&#xff0c;会导致截断 一、如何操作…

JavaScript中基本数据类型怎样使用?

JavaScript中的数据类型分为两大类&#xff0c;分别是基本数据类型和复杂数据类型(或称为引用数据类型)&#xff0c;如图所示。 本节重点讲解基本数据类型。下面我们用代码演示基本数据类型的使用。 (1)数字型(Number)&#xff0c;包含整型值和浮点型值: var numl 21; …