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

二叉搜索树经典笔试题【力扣、牛客】

文章目录

  • 1.根据二叉树创建字符串
  • 2. 二叉树的层序遍历
  • 3.二叉树的层序遍历Ⅱ
  • 4.二叉树的最近公共祖先
    • 1.法一:定位p、q在左还是右 分类讨论
    • 2.法二:利用stack求出p、q路径 求相交值
  • 5.二叉搜索树与双向链表
    • 1.法一:递归:递归过程修正指针指向
    • 2.数组:将二叉搜索树进行中序遍历可以得到由小到大的顺序排列
  • 6.前序中序遍历序列构造二叉树
  • 7.中序后序遍历序列构造二叉树
  • 8.二叉树的前序遍历【非递归】
  • 9.二叉树的中序遍历【非递归】
  • 10.二叉树的后序遍历【非递归】
    • 1.法一:栈模拟实现递归
    • 2.法二:前序遍历修改

在这里插入图片描述

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

根据二叉树创建字符串在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

struct TreeNode
{int val;TreeNode* left;TreeNode* right;TreeNode(): val(0), left(nullptr), right(nullptr){}TreeNode(int x): val(x), left(nullptr), right(nullptr){}TreeNode(int x, TreeNode* eft, TreeNode* right): val(x), left(left), right(right){}
};//图一分析:
//左不空 (左递归直至遇空返回上一层) 
//然后在当层判断右子树 
//右空 (返回上层 + )
//右不空 (左递归直至遇空返回上一层)
//然后在当层判断右子树 
//右空 (返回上一层 + )//图二分析:
//左不空 (左递归直至遇空返回上一层) 
//然后在当层判断右子树 
//右不空 (左递归直至遇空返回上一层)
//然后在当层判断右子树 
//右空 (返回上层 + )
//右不空 (左递归直至遇空返回上一层)//左不空 右空  --省略
// 左空时第一个if两个条件才判断完
//左空   右空  --省略
//左空  右不空 --不省略
class Solution
{
public:string tree2str(TreeNode* root){if (root == nullptr)return "";string str = to_string(root->val);//遍历完根后遍历左 遍历左的前提是左不空 如果左空看看右空不空//如果右也空没必要遍历 return//如果右不空 正常遍历if (root->left || root->right){str += '(';str += tree2str(root->left);str += ')';}if (root->right) //遍历完左后遍历右 遍历右的前提是右不空 //右不空 正常遍历 右空 【看注释知右空的一律省略 直接return】{str += '(';str += tree2str(root->right);str += ')';}return str;}
};

2. 二叉树的层序遍历

二叉树的层序遍历
在这里插入图片描述
在这里插入图片描述
点击 二叉树【C】 查看上篇博客中的层序遍历
在这里插入图片描述

struct TreeNode
{int val;TreeNode* left;TreeNode* right;TreeNode(): val(0), left(nullptr), right(nullptr){}TreeNode(int x): val(x), left(nullptr), right(nullptr){}TreeNode(int x, TreeNode* eft, TreeNode* right): val(x), left(left), right(right){}
};class Solution 
{
public:vector<vector<int>> levelorder(TreeNode* root) {queue<TreeNode*> q;int LevelNodeCount = 0;if (root){q.push(root);LevelNodeCount = 1;}vector<vector<int>> vv;while (!q.empty()){vector<int> v;while (LevelNodeCount--){TreeNode* front = q.front();q.pop();v.push_back(front->val);if (front->left)q.push(front->left);if (front->right)q.push(front->right);}vv.push_back(v);LevelNodeCount = q.size();}return vv;}
};

3.二叉树的层序遍历Ⅱ

二叉树的层序遍历Ⅱ
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

class Solution 
{
public:vector<vector<int>> levelorder(TreeNode* root) {queue<TreeNode*> q;int LevelNodeCount = 0;if (root){q.push(root);LevelNodeCount = 1;}vector<vector<int>> vv;while (!q.empty()){vector<int> v;while (LevelNodeCount--){TreeNode* front = q.front();q.pop();v.push_back(front->val);if (front->left)q.push(front->left);if (front->right)q.push(front->right);}vv.push_back(v);LevelNodeCount = q.size();}reverse(vv.begin(), vv.end());return vv;}
};

4.二叉树的最近公共祖先

二叉树的最近公共祖先
在这里插入图片描述在这里插入图片描述

1.法一:定位p、q在左还是右 分类讨论

T(N)=O(N^2)
最坏情况:树为单链即均在左侧或右侧,p、q均在单侧的底部
判断p、q的左右侧时 n-2 n-1
假设p、q均在左侧 接下来递归到左子树 继续判断p、q中是否为根?在左?在右?n-3 n-2 …

class Solution 
{
public:bool IsInTree(TreeNode* root, TreeNode* x){if (root == nullptr)return false;return root == x|| IsInTree(root->left, x)|| IsInTree(root->right,x);}//求p、q的最近公共祖先TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q){if (root == nullptr)return nullptr;//p、q其中一个是根 那么根就为objif (root == p || root == q)return root;//判断p、q在左 ?右bool pInLeft = IsInTree(root->left, p);bool pInRight = !pInLeft;bool qInLeft = IsInTree(root->left, q);bool qInRight = !qInLeft;//一左一右==》root为objif ((pInLeft && qInRight) || (pInRight && qInLeft))return root;//均左==》递归到左子树if (pInLeft && qInLeft)return lowestCommonAncestor(root->left, p, q);//均右==》递归到右子树elsereturn lowestCommonAncestor(root->right, p, q);}
};

2.法二:利用stack求出p、q路径 求相交值

class Solution
{
public:bool GetPath(TreeNode* root, TreeNode* pobj, stack<TreeNode*>& route){if (root == nullptr)return false;route.push(root);if (root == pobj)return true;if (GetPath(root->left, pobj, route))return true;if (GetPath(root->right, pobj, route))return true;route.pop();return false;}TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {stack<TreeNode*> pRoute;stack<TreeNode*> qRoute;GetPath(root, p, pRoute);GetPath(root, q, qRoute);//找路径相遇点while (pRoute.size() != qRoute.size()){if (pRoute.size() > qRoute.size())pRoute.pop();elseqRoute.pop();}while (pRoute.top() != qRoute.top()){pRoute.pop();qRoute.pop();}return pRoute.top();}
};

5.二叉搜索树与双向链表

二叉搜索树与双向链表
在这里插入图片描述
在这里插入图片描述

1.法一:递归:递归过程修正指针指向

class Solution
{
public: //中序遍历void InOrderConvert(TreeNode* cp, TreeNode*& prv){if (cp == nullptr)return;InOrderConvert(cp->left, prv);//一路向左 遇空返回上一层//前左指向前驱cp->left = prv;//left==prv即left指向prv所指向的结点//前驱非空 前结点的right指向后面那个结点if (prv)prv->right = cp;//更新prvprv = cp;//一路向右 遇空返回上一层InOrderConvert(cp->right, prv);}//==》当前层函数结束 返回上一层TreeNode* Convert(TreeNode* pRootOfTree){TreeNode* prev = nullptr;InOrderConvert(pRootOfTree, prev);TreeNode* head = pRootOfTree;//当传一颗空树 head在此就发挥了作用while (head && head->left)head = head->left;return head;}
};

2.数组:将二叉搜索树进行中序遍历可以得到由小到大的顺序排列

/*
struct TreeNode
{int val;struct TreeNode *left;struct TreeNode *right;TreeNode(int x) :val(x), left(NULL), right(NULL) {}
};
*/class Solution 
{
public:vector<TreeNode*> v;void inorder(TreeNode* root) {if (!root) return;inorder(root->left);v.push_back(root);inorder(root->right);}TreeNode* Convert(TreeNode* pRootOfTree) {if (!pRootOfTree) return pRootOfTree;inorder(pRootOfTree);for (int i = 0; i < v.size() - 1; i++) { v[i]->right = v[i + 1];v[i + 1]->left = v[i];}return v[0];}};

6.前序中序遍历序列构造二叉树

前序中序遍历序列构造二叉树
在这里插入图片描述

class Solution 
{
public:TreeNode* _buildTree(vector<int>& preorder, vector<int>& inorder, int& i, int begin, int end){if (begin > end) return nullptr;//遍历inorder 定位到根节点//[begin, x - 1] x [x + 1, end]int x = begin;for (x = begin; x <= end; ++x){if (inorder[x] == preorder[i])break;}TreeNode* root = new TreeNode(preorder[i++]);root->left = _buildTree(preorder, inorder, i, begin, x - 1);root->right = _buildTree(preorder, inorder, i, x + 1, end);return root;};TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder){int index = 0;//前序遍历数组第一个元素即根节点return _buildTree(preorder, inorder, index, 0, inorder.size() - 1);}
};

7.中序后序遍历序列构造二叉树

中序后序遍历序列构造二叉树
在这里插入图片描述

class Solution 
{
public:TreeNode* _buidTree(vector<int>& inorder, vector<int>& postorder, int& i,  int begin, int end){if (begin > end) return nullptr;int x = begin;for (x = begin; x <= end; ++x){if (inorder[x] == postorder[i])break;}TreeNode* root = new TreeNode(postorder[i--]);root->right = _buidTree(inorder, postorder, i, x + 1, end);root->left = _buidTree(inorder, postorder, i, begin, x - 1);return root;}TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {int index = postorder.size() - 1;return _buidTree(inorder, postorder, index, 0, inorder.size() - 1);}
};

8.二叉树的前序遍历【非递归】

二叉树的前序遍历
在这里插入图片描述
在这里插入图片描述

vector<int> preorderTraversal(TreeNode* root)
{vector<int> v;       //v存储遍历的数据stack<TreeNode*> st; //利用栈的特点 调整读取数据的顺序存入到v中TreeNode* cp = root;while (cp || !st.empty()){//左路结点while (cp){v.push_back(cp->val);st.push(cp);cp = cp->left;}//左路结点的右子树TreeNode* top = st.top();cp = top->right;st.pop();}return v;
}

9.二叉树的中序遍历【非递归】

二叉树的中序遍历
在这里插入图片描述

vector<int> inorderTraversal(TreeNode* root) 
{vector<int> v;stack<TreeNode*> st;TreeNode* cp = root;while (cp || !st.empty())   {while (cp){st.push(cp);cp = cp->left;}TreeNode* top = st.top();v.push_back(top->val);cp = top->right;st.pop();}return v;
};

10.二叉树的后序遍历【非递归】

二叉树的后序遍历
在这里插入图片描述

1.法一:栈模拟实现递归

vector<int> postorderTraversal(TreeNode* root)
{vector<int> v;stack<TreeNode*> st;TreeNode* cp = root;TreeNode* prv = nullptr;while (cp || !st.empty()){while (cp){st.push(cp);cp = cp->left;}TreeNode* top = st.top();if (top->right == nullptr || top->right == prv){v.push_back(top->val);prv = top;st.pop();}else{cp = top->right;}}return v;
};

2.法二:前序遍历修改

class Solution 
{
public:vector<int> postorderTraversal(TreeNode* root) {vector<int> v;stack<TreeNode*> st;st.push(root);while (!st.empty()){TreeNode* top = st.top();st.pop();if (top)v.push_back(top->val);elsecontinue;st.push(top->left);st.push(top->right);}reverse(v.begin(), v.end());return v;}
};
http://www.lryc.cn/news/168154.html

相关文章:

  • docker系列(1) - docker环境篇
  • web安全漏洞-SQL注入攻击实验
  • 直接插入排序(C++实现)
  • 【k8s】Pod 的钩子
  • MCU软核 3. Xilinx Artix7上运行cortex-m3软核
  • 基于SpringbootShiro实现的CAS单点登录
  • SocketTool V4.0 使用说明
  • Jenkins结合allure生成测试报告
  • 【Linux】缓冲区/回车换行
  • Java手写插入排序和算法案例拓展
  • Python Opencv实践 - 视频文件操作
  • HCS 中的一些概念(二)
  • Scanner类用法(学习笔记)
  • idea2021.1.3版本双击启动,没反应
  • MC-4/11/01/400 ELAU 软件允许用户完全访问相机设置
  • Error contacting service. It is probably not running.问题解决
  • 01_网络编程_传统IO
  • vue 检查指定路由是否存在
  • 自动化办公更简单了:新版python-office,有哪些更新?
  • windows flask服务卡死的问题
  • 项目上线部署--》服务器部署流程(一)
  • Python:函数调用的实参
  • 174. 地下城游戏 -- 动规
  • js实现websocket服务端和客户端
  • qt qml RadioButton如何设置字体颜色,style提示找不到怎么办?
  • Docker 的使用
  • 【无公网IP内网穿透】Java支付宝沙箱环境支付,SDK接口远程调试
  • axios 用formData的方式请求数据
  • Mapbox加载arcgis的底图
  • (20)线程安全问题:Lock,双锁问题,Monitor,死锁