移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——12.二叉树(习题)

news2025/2/23 0:31:57

1.根据二叉树创建字符串

. - 力扣(LeetCode)

我的思路:

1. 根节点单独讨论,因为,根节点之后才会开始有括号

2.根节点的左孩子和右孩子分别进入operation函数

operation函数:

1.如果root不为空,先加(,再加root->val

2.分类讨论:

1.if(root->left==NULL&&root->right==NULL)

如果为叶子节点:直接加)

2.if(root->left==NULL&&root->right!=NULL)

如果左为空,右不为空;

无法省略括号,需要加()

3.如果左右都不为空

递归

 operation(root->left,arr);

 operation(root->right,arr);

最后加)

 函数介绍:to_string,可将整形转换为string;

class Solution {
public:
     void operation(TreeNode* root,string& arr)
     {
        if(root)
        {
          arr.push_back('(');
          arr+=to_string(root->val);
          if(root->left==NULL&&root->right==NULL)
          {
             arr.push_back(')');
          }
          else
          {
             if(root->left==NULL&&root->right!=NULL)
             {
                arr.push_back('(');
                arr.push_back(')');
             }
              
              operation(root->left,arr);
              operation(root->right,arr);
              arr.push_back(')');
          }
        }
     }

    string tree2str(TreeNode* root) {
     string arr;
     if(root)
     {
        arr+=to_string(root->val);
        if(root->left==NULL&&root->right!=NULL)
        {
                arr.push_back('(');
                arr.push_back(')');
        }
        operation(root->left,arr);
        operation(root->right,arr);
     }
     return arr;
    }
};

 2.二叉树的分层遍历1

 . - 力扣(LeetCode)

我的思路:

1. 建一个栈,并把根节点入栈,记录栈的大小;

2.while(size)

出栈,size--,并将左右节点入栈

3.size=栈的size;

4.若栈为空,则已经遍历完毕;

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
     TreeNode* tmp;
     vector<int> brr;
     vector<vector<int>> arr;
     queue<TreeNode*> it;
     int size=0;
     if(root!=NULL)
     {
       it.push(root);
       size++;
     }
      while(it.size())
      {
        while(size)
        {
          tmp=it.front();
          brr.push_back(tmp->val);
          it.pop();
          size--;
          if(tmp->left)
          {
            it.push(tmp->left);
          }

          if(tmp->right)
          {
            it.push(tmp->right);
          }
        }
        arr.push_back(brr);
        brr.clear();
        size=it.size();
      }

      return arr;

    }
};

 3.二叉树的分层遍历2

 . - 力扣(LeetCode)

 

和前一题一样,只需在最后reverse(arr.begin(),arr.end()); 

class Solution {
public:
    vector<vector<int>> levelOrderBottom(TreeNode* root) {
     TreeNode* tmp;
     vector<int> brr;
     vector<vector<int>> arr;
     queue<TreeNode*> it;
     int size=0;
     if(root!=NULL)
     {
       it.push(root);
       size++;
     }
      while(it.size())
      {
        while(size)
        {
          tmp=it.front();
          brr.push_back(tmp->val);
          it.pop();
          size--;
          if(tmp->left)
          {
            it.push(tmp->left);
          }

          if(tmp->right)
          {
            it.push(tmp->right);
          }
        }
        arr.push_back(brr);
        brr.clear();
        size=it.size();
      }
      reverse(arr.begin(),arr.end());
      return arr;
    }
};

 4.最近公共祖先

. - 力扣(LeetCode)

我的思路:

1.先写一个查找函数

2.从根节点开始查找p

3. 再从p开始查找q

如果找到了,返回p

如果没找到,那么p就变成p的父节点,再继续查找,直至从p可以找到q,返回p 

class Solution {
public:
      bool qfirstfind(TreeNode* p, TreeNode* q)
      {
        if(p==nullptr)
        return false;
        else if(p!=q)
        {
            if(qfirstfind(p->left, q))
            return true;
            else
            return qfirstfind(p->right, q);
        }
        else if(p==q)
        return true;
        
        return 1;
      }                          //这个函数用来查找p之下是否有q
       

       void firstfind(TreeNode* p, TreeNode* q,TreeNode*&parent)
      {
        if(p!=nullptr)
        {
            if(p->left!=q&&p->right!=q)
            {
               firstfind(p->left, q,parent);
               firstfind(p->right, q,parent);
            }
        else
        {
            parent=p;            //这里用来保存q的父节点
        }
        }
      }

       void secondfind(TreeNode* root, TreeNode*&p, TreeNode*&q)
       {
            TreeNode* it;
            while((p->left!=q)&&(p->right!=q)&&(p!=root))
            {
                firstfind(root,p,it);
                p=it;           //p赋值为其父节点
                if(qfirstfind(p,q))
                {
                    break;
                }
            }
       }

    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        {
            if(qfirstfind(p,q))
            return p;
            if(qfirstfind(q,p))
            return q;                    //如果p,q有一个是公共祖先,则直接返回
            secondfind(root, p, q);
            return p;
    
        }
    }
};

更好的的思路 !!!!!!!!:

用两个栈分别存放从根找到p,q的路径

1.若两个栈大小不一致

则用pop函数,保证二者大小一致

2.若两栈的top不一致,则二者都pop

直至两者的top相同,返回二者的top,即为最近的公共祖先

class Solution {
public:
     bool findpath(TreeNode* root, TreeNode* x,stack<TreeNode*>&path)
     {
        if(root==nullptr)
        return false;

        path.push(root);     

        if(root==x)
        return true;
        
        if(findpath(root->left,x,path))
        return true;

        if(findpath(root->right,x,path))
        return true;

        path.pop();     //走到这一步,证明root的左右子树都没有x,所以要把root删除
        return false;
     }





    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        stack<TreeNode*> ppath,qpath;
        findpath(root,p,ppath);
        findpath(root,q,qpath);
        while(ppath.size()!=qpath.size())
        {
            if(ppath.size()>qpath.size())
            ppath.pop();
            else
            qpath.pop();
        }
        
        while(ppath.top()!=qpath.top())
        {
             ppath.pop();
             qpath.pop();
        }
 
        return ppath.top();
    }
};

5.二叉树搜索树转换成排序双向链表 

二叉搜索树与双向链表_牛客题霸_牛客网

我的思路:

1.find1函数:寻找左子树中的最大值

2.find2函数:寻找右子树中的最小值

3.find3函数:寻找头节点,即二叉树中的最小值 

从叶子节点开始连接

class Solution {
public:
    
	void creat(TreeNode*root)
	{
		if(root!=nullptr)
         {
			if(root->left==nullptr&&root->right==nullptr)
		 {
			return;
		 }
          else{

             TreeNode*qleft=root->left;
             TreeNode*qright=root->right;
            creat(qleft);
			creat(qright);

             TreeNode*nleft=find1(root);
             TreeNode*nright=find2(root);
			 if(nleft)
		     nleft->right=root;
			 if(nright)
		     nright->left=root;
		     root->left=nleft;
		     root->right=nright;

			
		  }
		 }
	}


 TreeNode*find1(TreeNode*root)
 {
	 TreeNode*it = root->left;  
	 if(it)            //左右都不为空,找左子树最大的
    {
		while (it->right)
      {
	  it = it->right;
      }
	  return it;
	}
	else {
	return nullptr;
	}
 }

TreeNode*find2(TreeNode*root)
 {
	 TreeNode*it = root->right;  //左右都不为空,找右子树最小的
	 if(it)
      {
		while (it->left)
       {
	     it = it->left;
       }
	return it;
	  }
	  else {
	  return nullptr;
	  }
 }

TreeNode*find3(TreeNode*root)
 {            //找根
    TreeNode* it=root;
    while (it->left)
    {
	  it = it->left;
    }
	return it;
 }
    TreeNode* Convert(TreeNode* pRootOfTree) {

        if(pRootOfTree==nullptr)
		return pRootOfTree;

		TreeNode*head=find3(pRootOfTree);
        creat(pRootOfTree);
        return head;
    }
};

6.前序中序还原二叉树 

 . - 力扣(LeetCode)

思路:

1.preorder 确定根

2.确定根了之后,将inorder分成两部分,左边为左子树,右边为右子树

3.分别递归左边和右边

class Solution {
public:
    TreeNode* creat(vector<int>& preorder, vector<int>& inorder,int &prev,int begin,int end)
    {
        TreeNode* root;
        if(begin>end)
        return nullptr;
        int flag=preorder[prev];
        int i=0;
       while(flag!=inorder[i])
       {
         i++;
       }
        root=new TreeNode(flag);
        prev++;
       root->left=creat(preorder,inorder,prev,begin,i-1);  //前序遍历,根左右,根后是左子树,所以先构建左子树
       root->right=creat(preorder,inorder,prev,i+1,end);   //有点类似并归排序
       return root;
    }


    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
    TreeNode* root;
    int prev=0;     //前序遍历,从头开始找根
    root=creat(preorder,inorder,prev,0,preorder.size()-1);
    return root;
    }
};

7.中序和后序还原二叉树 

. - 力扣(LeetCode)

 

和上一题一样,中序确定左右子树

但不同的是得从后序遍历的尾开始找根,且根前是右子树 

class Solution {
public:
 TreeNode* creat(vector<int>& postorder, vector<int>& inorder,int &prev,int begin,int end)
    {
        TreeNode* root;
        if(begin>end)
        return nullptr;
        int flag=postorder[prev];
        int i=0;
       while(flag!=inorder[i])
       {
         i++;
       }
        root=new TreeNode(flag);
        prev--;
       root->right=creat(postorder,inorder,prev,i+1,end);   //后序遍历左右根,倒着找的话,根的前面是右子树,所以右子树先建立
       root->left=creat(postorder,inorder,prev,begin,i-1);
       return root;
    }
    

    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
    TreeNode* root;
    int prev=inorder.size()-1;   //从尾开始找根
    root=creat(postorder,inorder,prev,0,inorder.size()-1);
    return root;
    }
};

 

 

 

 

 

 

 

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

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

相关文章

计算机毕业设计选题推荐-在线投票系统-Java/Python项目实战

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

程序员的 AI 启蒙:ChatGPT+ Copilot开发Vue3 仿简书项目 90%代码AI生成

在人工智能技术日益成熟的今天&#xff0c;程序员们正在迎来一场全新的编程革命。ChatGPT和Copilot等AI工具的出现&#xff0c;让代码生成不再是遥不可及的梦想。本文将带你体验如何利用这些先进技术&#xff0c;仅用90%的代码量&#xff0c;开发出一个基于Vue3的仿简书项目&am…

电容笔有必要买吗?西圣、wiwu、倍思好不好用?王者产品测评对比

当下很多年轻人都热衷于使用 iPad 来进行学习与娱乐&#xff0c;因此电容笔还是很有必要买的&#xff0c;它可以提升我们的效率。然而作为一名数码测评博主&#xff0c;我十分清楚一旦选到质量不佳的产品&#xff0c;就会出现诸如断触、延迟等问题&#xff0c;进而拉低效率。 …

2024年9月一区SCI-神经种群动态优化算法NPDOA-附Matlab免费代码

引言 本期介绍了一种受脑神经科学启发的元启发式算法&#xff0c;称为神经种群动态优化算法Neural population dynamics optimization algorithm(NPDOA)的元启发式算法。该成果于2024年9月最新发表在中科院1区 Top SCI期刊 Knowledge-Based Systems。 原文作者将NPDOA与其他9种…

大学生必备10个AI工具网站,辅助完成辩论/开题/实践/形势政策报告、创新创业计划书、思想汇报、心得感悟等作业,提升学习效率和学术表现!

大学新生和学长学姐们都已经开学了&#xff0c;忙碌的课程和多样的作业也随之开始&#xff0c;下面将给大学生们介绍10个辅助完成作业、寻找灵感&#xff0c;提升学习专注力和学术表现的AI工具~ 1、笔墨写作 笔墨写作 - 领先的写作智能AI创作平台 | 官方首页笔墨写作是一款专…

深度剖析去中心化存储:IPFS、Arweave 和 BNB Greenfield 的技术革新与生态系统演进

引言&#xff1a; 在数字时代的浪潮中&#xff0c;数据已然成为驱动创新和决策的核心资产。然而&#xff0c;随着数据量呈指数级增长&#xff0c;传统中心化存储模式面临着前所未有的挑战。安全漏洞、隐私泄露、数据垄断等问题日益凸显&#xff0c;促使技术界重新思考数据存储…

QT多线程编程(基础概念以及示例)

QT多线程编程 前言&#xff1a;基础夯实&#xff1a;一:多线程概述二:QT多线程的使用1. 继承QThread类2. 继承QObject类3. QtConcurrent模块 三:线程同步与通信四:线程安全五:线程管理六:总结 效果展示&#xff1a;实现功能&#xff1a;核心代码&#xff1a;mainwindow.hmythre…

2024数学建模国赛官方评阅标准发布!

​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑​↑…

被百度 AI 文心一言推荐的 Mac App 惊喜到了!

由于工作需要&#xff0c;我需要一款 Mac 软件帮我记录所有的复制记录。 当我去百度搜索“mac 复制记录”“mac 复制历史”时&#xff0c;百度 AI 给我推荐了这三款 App&#xff1a;Maccy、CleanClip、Collect Boy。 我开始分别试用这三款软件&#xff0c;我现在还没全部试用完…

002集—— CAD划线并模拟向命令窗口发送命令(CAD—C#二次开发入门)

模拟向命令窗口发送全图居中的命令&#xff1a; Application.DocumentManager.MdiActiveDocument.SendStringToExecute("z\ne\n",true,false,false); 弹窗命令&#xff1a; Application.ShowAlertDialog("Erase the newly added polyline."); 本例在ca…

macos清理垃圾桶时提示 “操作无法完成,因为该项目正在使用中” 解决方法 , 强制清理mac废纸篓 方法

在macos中&#xff0c;删除文件后&#xff0c; 在清理垃圾桶时提示 “操作无法完成&#xff0c;因为该项目正在使用中” 出现这个提示&#xff0c;在大多数的情况下是因为数据问题导致&#xff0c;需要通过磁盘管理工具进行修复&#xff0c;修复后才可彻底的清理垃圾桶。 另外…

FPGA低功耗设计

FPGA低功耗设计 文章目录 FPGA低功耗设计前言一、功耗类型1.1 动态功耗1.2 静态功耗1.3 浪涌功耗 二、系统级低功耗设计2.1 **多电压技术&#xff1a;**即工作频率、电压和功耗的关系2.2 系统时钟分配&#xff1a;2.3 软硬件划分2.4 p 或单元库选择 三、RTL级别低功耗设计3.1 并…

运算放大电路

填鸭子呢 兴趣没了&#xff0c;啥也没了 运行过程&#xff0c;少了什么 差分放大 二极放大 功率放大 输出为饱和 反馈调整放大 倍数 考试 我可以认为就应该那样 但理解却不能如 懂了不妨碍我不会用 会用不妨碍我不懂 也想设计一个如哆来A梦那样的&#xff1b; 什么…

Gapless-REMA100:一个通过多源DEM填补空白的南极洲无缝100米参考高程模型

ABSTRACT 南极洲的数字高程模型&#xff08;DEM&#xff09;是冰川学应用中至关重要的数据集&#xff0c;广泛用于从野外工作规划到冰盖动力学分析等多个方面。高空间分辨率的DEM数据能够更详细地描绘地形。南极洲参考高程模型&#xff08;REMA&#xff09;马赛克是最近发布的…

VR全景视频编辑SDK解决方案,指尖玩转全景世界

随着虚拟现实&#xff08;VR&#xff09;技术的日益成熟&#xff0c;全景视频以其沉浸式、全方位的视觉体验&#xff0c;成为了连接现实与虚拟世界的桥梁。然而&#xff0c;传统VR视频编辑的繁琐流程和高门槛&#xff0c;往往限制了创作者们的灵感释放与作品传播。如今&#xf…

我的独立游戏-休闲社交游戏-“淘金城堡“CSDN上线了

大家好&#xff0c;我的休闲社交游戏-"淘金城堡"在CSDN课堂上线了&#xff0c;有91节视频课和三个开发阶段的项目源码&#xff0c;非常适合分阶段学习。 项目的地址&#xff1a; http://t.csdnimg.cn/m0hFd 游戏截图 这个项目是我开发的一款独立游戏的附属产物。 …

【信道复用技术】

信道复用技术 复用&#xff08;multiplexing&#xff09;是通信技术种的基本概念。它允许用户使用一个共享信道进行通信&#xff0c;降低成本&#xff0c;提高利用率。 如下图所示&#xff0c;情况a是A1&#xff0c;B1&#xff0c;C1各自使用自己单独的信道&#xff0c;情况b…

苹果CMS与海洋CMS安全性对比:为什么苹果CMS更值得信赖

苹果CMS&#xff08;Maccms&#xff09;介绍及安全性分析 在选择内容管理系统&#xff08;CMS&#xff09;时&#xff0c;安全性是每个网站管理员都必须重点考虑的因素。苹果CMS&#xff08;maccmscn&#xff09;和海洋CMS都是在国内较受欢迎的CMS平台&#xff0c;但它们在安全…

在WordPress中最佳Elementor主题推荐:进阶级指南

如果你已经熟悉WordPress和Elementor&#xff0c;选择功能更强大、定制性更高的主题能进一步提升网站质量。今天&#xff0c;我为大家介绍五款适合用户的进阶级Elementor主题&#xff1a;Shoptimizer、OceanWP、Hestia、Zakra和Phlox。这些主题不仅功能丰富&#xff0c;而且非常…

Maven私服Nexus安装及使用

前言 周末在家闲着无聊&#xff0c;不知道做点啥&#xff0c;就想着自己搭建一个Maven私服来玩玩。刚好使用自己之前在电脑上搭建的虚拟机服务器来操作体验了一把。搭建好私服后&#xff0c;以后自己写的一些小模块啊&#xff0c;工具包啥的就可以发布到自己的私服上了&#xf…