当前位置: 首页 > wzjs >正文

北京市住房城乡建设委员会网站软文营销的五个步骤

北京市住房城乡建设委员会网站,软文营销的五个步骤,网站怎么做市场分析,没有网站可以做cpa吗​📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:练题 🎯长路漫漫浩浩,万事皆有期待 文章目录 递归遍历前序遍历中序遍历后…

在这里插入图片描述

​📝个人主页:@Sherry的成长之路
🏠学习社区:Sherry的成长之路(个人社区)
📖专栏链接:练题
🎯长路漫漫浩浩,万事皆有期待

文章目录

  • 递归遍历
    • 前序遍历
    • 中序遍历
    • 后序遍历
  • 非递归遍历
    • 前序遍历
    • 后序遍历
    • 中序遍历
    • 标记迭代法
  • 总结:

这一期讲树这个数据结构的相关知识

首先我们要明白树的两种通用遍历分别是深度优先搜索,和广度优先搜索。这里我们介绍深度优先搜索的三种表现形式:前序遍历,中序遍历和后序遍历。这三种搜索方式可以用递归法或者迭代法表示出来。事实上,很多递归能写出来的代码,大都可以使用迭代法表示出来。

递归遍历

前序遍历

class Solution 
{
public:
vector<int>result;
void dfs(TreeNode* root)
{if(root)result.push_back(root->val);if(root)dfs(root->left);if(root)dfs(root->right);
}vector<int> preorderTraversal(TreeNode* root) {if(root==nullptr)return result;dfs(root);return result;}
};

前序遍历的规则是“中左右“,即先遍历树的中间节点,再分别遍历左右两子树,并在其遍历左右两子树时仍然遵循此规则。所以我们可以容易的理解dfs代码部分先将中间节点保存后,分别进行左子树和右子树的递归。

中序遍历和后序遍历的递归代码,都和前序遍历差不多,只是略微调整一下进入子树的时机而已,下面直接给出代码。

中序遍历

class Solution 
{
public:void dfs(TreeNode* root,vector<int>& result){if(root==nullptr)return ;dfs(root->left,result);result.push_back(root->val);dfs(root->right,result);}vector<int> inorderTraversal(TreeNode* root) {vector<int>result;dfs(root,result);return result;}
};

后序遍历

class Solution 
{
public:void dfs(TreeNode* root,vector<int>& result){if(root==nullptr)return ;dfs(root->left,result);dfs(root->right,result);result.push_back(root->val);}vector<int> inorderTraversal(TreeNode* root) {vector<int>result;dfs(root,result);return result;}
};

说完了递归遍历,我们再来看看非递归遍历

非递归遍历

非递归遍历中的迭代遍历,前后序的代码是差不多的,但是中序遍历有很大差别

前序遍历

先说前序遍历的迭代,思路是用一个栈来模拟递归的操作

为什么我们会想到使用栈来模拟呢?

因为递归实际上就是编译器将函数各参数放入递归内部,返回时再将其弹出,所以我们用一个栈来模拟递归操作,是再合适不过的。我们写一个循环判断栈中是否为空,为空则说明没有元素要处理了,那么循环内的逻辑就是先创立一个临时的节点指针指向当前栈口处元素,先判断其是否为空,为空不能操作,否则会操作空指针。
不为空时我们先将遍历到的节点直接放入数组中,因为前序遍历是先处理中间节点,这之后我们按照先放入右节点再放入左节点的规律来使节点指针向后遍历。

这是为什么呢?

原因在于栈的独特定义,我们要先放入右节点再放入左节点,才能在下一步时候先处理左节点!以下代码

class Solution 
{
public:vector<int> preorderTraversal(TreeNode* root) {stack<TreeNode*> s;vector<int>result;if(root==nullptr)return result;s.push(root);//加入的是节点而并非节点对应的值,这里要尤其注意while(!s.empty()){TreeNode* node=s.top();s.pop();if(node)result.push_back(node->val);else continue;s.push(node->right);s.push(node->left);}return result;}
};

后序遍历

后序遍历思路很类似,需要注意的是后序遍历的情况为”左右中“,我们可以按照前序遍历的代码模板将前序遍历的压栈操作改为先放入左节点再放入右节点,这样它对应的原本遍历方法是中右左,当全部遍历完成之后,我们将数组部分反转,即可得到后序遍历。

class Solution {
public:vector<int> postorderTraversal(TreeNode* root) {stack<TreeNode*>s;vector<int>result;if(root==nullptr)return result;s.push(root);while(!s.empty()){TreeNode*node=s.top();s.pop();if(node)result.push_back(node->val);else continue;s.push(node->left);s.push(node->right);}reverse(result.begin(),result.end());return result;}
};

这里可以看出,后序和前序的代码差别不大,也就是改了入栈的顺序,和反转了一下数组。

中序遍历

接着,我们再来看看中序遍历。

中序遍历的思路是:我们需要建立一个指针来存储各节点,然后我们将它们放入栈内,我们先一直向二叉树的左节点遍历直到无法继续为止,弹出栈顶元素,此时栈顶元素即为我们要找的元素,为什么呢?

因为我们是一直向左走,直到无法再向左走,弹出的那个元素,此时就是这个子树的中间节点(由于没有左节点)直接放入答案数组内,再遍历这个节点的右节点(不要忘记将其压入栈内),如果它有左节点接着遍历,如果它没有,那么就直接弹出,重复上述操作。

为什么中序遍历不能像前后序那样只调整位置呢?
拿前序遍历举例它是先遍历的中间节点也是先处理的中间节点,后序的代码前面思路也是如此,只是后面有调整位置,换句话说,是此时遍历的节点正是我们此时要处理的数据!

那我们在遍历中序时候可以先遍历左边子树达成一样的逻辑吗?答案肯定是否定的,因为我们一开始只有root这个节点,而它指向了根节点,也就是说我们注定是先遍历中间节点,所以这样的方法并不适合中序迭代。

class Solution {
public:vector<int> inorderTraversal(TreeNode* root) {stack<TreeNode*>s;vector<int>result;TreeNode*cur=root;while(cur!=nullptr||!s.empty()){if(cur){s.push(cur);cur=cur->left;}else{cur=s.top();s.pop();if(cur)result.push_back(cur->val);cur=cur->right;}}return result;}
};

标记迭代法

那么有没有可以将三种迭代统一起来的代码呢?也是有的,这里的思路也是创建一个栈来模拟,不同的是,我们将凡是已经遍历过的数据一股脑地放进去,在我们要处理的数据之后紧接着加入一个null来标记,这种思路也被称为标记迭代法。当我们遍历到null的时候,就对下一数据进行加入答案数组的处理。

中序

class Solution {
public:vector<int> inorderTraversal(TreeNode* root) {vector<int> result;stack<TreeNode*> st;if (root != NULL) st.push(root);while (!st.empty()) {TreeNode* node = st.top();if (node != NULL) {st.pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中if (node->right) st.push(node->right);  // 添加右节点(空节点不入栈)st.push(node);                          // 添加中节点st.push(NULL); // 中节点访问过,但是还没有处理,加入空节点做为标记。if (node->left) st.push(node->left);    // 添加左节点(空节点不入栈)} else { // 只有遇到空节点的时候,才将下一个节点放进结果集st.pop();           // 将空节点弹出node = st.top();    // 重新取出栈中元素st.pop();result.push_back(node->val); // 加入到结果集}}return result;}
};

该思路旨在if条件语句中处理压栈操作,else里处理加入答案数组,使代码变得简介,但是思路难想到,建议只记一种思路。

总结:

今天我们完成了树的递归遍历和非递归遍历,了解了一种新的方法标记迭代法,相关的思想需要多复习回顾。接下来,我们继续进行算法练习。希望我的文章和讲解能对大家的学习提供一些帮助。

当然,本文仍有许多不足之处,欢迎各位小伙伴们随时私信交流、批评指正!我们下期见~

在这里插入图片描述

http://www.dtcms.com/wzjs/340309.html

相关文章:

  • 接私活做预算的网站推广普通话的意义50字
  • 西安做网站公司哪家行网站外链购买
  • 如何做一款服装网站深圳最新疫情
  • 全国人社政务服务平台网站seo教程
  • 网站布局规范苏州百度推广
  • 内江规划建设教育培训中心网站网站推广优化排名教程
  • 广州做网站要多少钱今日国内新闻最新消息10条新闻
  • 手机版网站与app免费网络营销推广软件
  • 浙江网站建设推广公司找哪家网上营销培训课程
  • 宁波网站建设详细策划有创意的网络广告案例
  • 素材网站可以做淘宝吗怎样在网上推广
  • 防红短链接生成济南seo网站优化
  • 即墨网站开发如何创建一个网址
  • 59zwd一起做网站seo的培训课程
  • 做网站的技术门槛高吗seo排名软件价格
  • win系统和mac那个做网站好互联网推广中心
  • 牛什么的网站建设电商网课
  • 备案 手机网站百度竞价推广关键词优化
  • 建设网站总结社区营销推广活动方案
  • 垫江网站开发djrckj网站广告接入
  • 学校网络建设方案设计seo整站优化公司持续监控
  • 数码类网站名称免费seo刷排名
  • 制作动漫的软件广州seo优化排名推广
  • 宣传营销方式有哪些seo外链
  • 医院网站建设平台seo黑帽有哪些技术
  • 顺德o2o网站建设线上推广方案
  • 外国做动漫图片的网站叫什么平台优化
  • 怎么在网站标题做logo云搜索下载
  • 南京建设网站的公司朋友圈广告推广
  • 用php内容做电商网站商品关键词怎么优化