【代码随想录】【算法训练营】【第22天】 [235]二叉搜索树的最近公共祖先 [701]二叉搜索树中的插入操作 [450]删除二叉搜索树中的节点

server/2024/9/29 5:26:45/

前言

思路及算法思维,指路 代码随想录。
题目来自 LeetCode。

day 22,难熬的周三~

题目详情

[235] 二叉搜索树的最近公共祖先

题目描述

235 二叉搜索树的最近公共祖先
235 二叉搜索树的最近公共祖先

解题思路

前提:二叉搜索树,且p、q均存在于二叉树上
思路:后序遍历,判断是否同处于某结点的左右子树上,因二叉搜索树有序性,可以判断结点在左子树还是右子树。
重点:有可能p、q为左右子树上,也有可能p为q的祖先。

代码实现

C语言
普通二叉树的最近公共祖先解法
/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     struct TreeNode *left;*     struct TreeNode *right;* };*/struct TreeNode *traversal(struct TreeNode *root, struct TreeNode *p, struct TreeNode *q)
{// 判空if ((root == NULL) || (p == NULL) || (q == NULL)){return NULL;}// 判断该结点if ((root == p) || (root == q)){return root;}// 左子树struct TreeNode *leftNode = traversal(root->left, p, q);// 右子树struct TreeNode *rightNode = traversal(root->right, p, q);// 判断是否找到最近公共祖先if ((leftNode != NULL) &&(rightNode != NULL)){return root;}else if ((leftNode != NULL) &&(rightNode == NULL)){return leftNode;}else if ((leftNode == NULL) &&(rightNode != NULL)){return rightNode;}return NULL;
}struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) {return traversal(root, p, q);
}
二叉搜索树的有序性解法
/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     struct TreeNode *left;*     struct TreeNode *right;* };*/struct TreeNode *traversal(struct TreeNode *root, struct TreeNode *p, struct TreeNode *q)
{// 判空if ((root == NULL) || (p == NULL) || (q == NULL)){return NULL;}// p、q结点均在左子树上if ((root->val > p->val) && (root->val > q->val)){return traversal(root->left, p, q);}// p、q结点均在右子树上if ((root->val < p->val) && (root->val < q->val)){return traversal(root->right, p, q);}// p、q一左一右或者一左一根或者一根一右,此时root均为最近公共祖先return root;
}struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) {return traversal(root, p, q);
}

[701] 二叉搜索树中的插入操作

题目描述

701 二叉搜索树中的插入操作
701 二叉搜索树中的插入操作

解题思路

前提:二叉搜索树
思路:由于二叉搜索树的有序性,插入的结点在对应叶子结点的左节点或右节点即可。
重点:二叉搜索树的有序性。

代码实现

C语言
递归
/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     struct TreeNode *left;*     struct TreeNode *right;* };*/void traversal(struct TreeNode **root, int val)
{// 判空if (*root == NULL){*root = (struct TreeNode *)malloc(sizeof(struct TreeNode));(*root)->val = val;(*root)->left = NULL;(*root)->right = NULL;return ;}// 判断元素插入位置if ((*root)->val > val){traversal(&((*root)->left), val);}else if ((*root)->val < val){traversal(&((*root)->right), val);}return ;
}struct TreeNode* insertIntoBST(struct TreeNode* root, int val) {traversal(&root, val);return root;
}
迭代
/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     struct TreeNode *left;*     struct TreeNode *right;* };*/struct TreeNode* insertIntoBST(struct TreeNode* root, int val) {// 判空if (root == NULL){root = (struct TreeNode *)malloc(sizeof(struct TreeNode));root->val = val;root->left = NULL;root->right = NULL;return root;}// 原树非空struct TreeNode *pre = NULL;struct TreeNode *cur = root;// 遍历至叶子结点位置while (cur){// 保存当前结点位置pre = cur;if (cur->val > val){cur = cur->left;}else if (cur->val < val){cur = cur->right;}}// 插入节点if (pre->val > val){pre->left = (struct TreeNode *)malloc(sizeof(struct TreeNode));pre->left->val = val;pre->left->left = NULL;pre->left->right = NULL;}else if (pre->val < val){pre->right = (struct TreeNode *)malloc(sizeof(struct TreeNode));pre->right->val = val;pre->right->left = NULL;pre->right->right = NULL;}return root;
}

[450] 删除二叉搜索树中的节点

题目描述

450 删除二叉搜索树中的节点
450 删除二叉搜索树中的节点

解题思路

前提:二叉搜索树
思路:由于二叉搜索树的有序性,删除的结点比较容易遍历到,主要是处理该删除结点的左右子树的处理。
重点:该删除结点的左右子树的处理,如果左右子树有一为NULL时,则该子树代替删除结点的位置;如果左右子树均不为NULL时,则需要将左子树挂在右子树的最左侧叶子结点的左结点上,或者将右子树挂在左子树最右侧叶子结点的右节点上。

代码实现

C语言
二叉搜索树递归
/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     struct TreeNode *left;*     struct TreeNode *right;* };*/
struct TreeNode* deleteNode(struct TreeNode* root, int key){// 判空if (root == NULL){return root;}// 判断是否为删除结点if (root->val == key){// 如果该结点的左右子树至少一空if (root->left == NULL){return root->right;}else if (root->right == NULL){return root->left;}else{// 寻找左侧子树的最右侧结点,放置该结点的右子树struct TreeNode *pre = root;struct TreeNode *cur = root->left;while (cur){pre = cur;cur = cur->right;}pre->right = root->right;root = root->left;return root;}}if (root->val > key){root->left = deleteNode(root->left, key);}if (root->val < key){root->right = deleteNode(root->right, key);}return root;
}
二叉搜索树迭代
/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     struct TreeNode *left;*     struct TreeNode *right;* };*/
struct TreeNode *deleteOneNode(struct TreeNode *root)
{// 判空if (root == NULL){return root;}// 删除结点if (root->left == NULL){return root->right;}if (root->right == NULL){return root->left;}// 该结点两子树均不为空时,寻找左子树的最右叶子结点的右子树位置,指向原结点的右子树struct TreeNode *cur = root->left;while (cur->right){cur = cur->right;}cur->right = root->right;return root->left;
}struct TreeNode* deleteNode(struct TreeNode* root, int key){// 判空if (root == NULL){return root;}// 查找删除结点struct TreeNode *pre = NULL;struct TreeNode *cur = root;while (cur){if (cur->val == key){break;}pre = cur;if (cur->val > key){cur = cur->left;}else if (cur->val < key){cur = cur->right;}}// 删除结点为根节点情况if (pre == NULL){return deleteOneNode(root);}// 判断删除结点为左子树,还是右子树if ((pre->left) && (pre->left->val == key)){pre->left = deleteOneNode(pre->left);}if ((pre->right) && (pre->right->val == key)){pre->right = deleteOneNode(pre->right);}return root;
}
普通二叉树删除方式:通过交换节点,然后删除叶子结点实现
/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     struct TreeNode *left;*     struct TreeNode *right;* };*/
struct TreeNode* deleteNode(struct TreeNode* root, int key){// 判空if (root == NULL){return root;}// 判断是否为删除结点if (root->val == key){// 如果该结点的左右子树至少一空,此时删除该结点if (root->left == NULL){return root->right;}else if (root->right == NULL){return root->left;}else{// 寻找该结点的左侧子树的最右侧结点,放置该结点的右子树,并交换两节点值struct TreeNode *pre = root;struct TreeNode *cur = root->left;while (cur){pre = cur;cur = cur->right;}int tmp = root->val;root->val = pre->val;pre->val = tmp;}}root->left = deleteNode(root->left, key);root->right = deleteNode(root->right, key);return root;
}

今日收获

  1. 二叉搜索树的相关实现。

http://www.ppmy.cn/server/45006.html

相关文章

kubernetes-PV与PVC

一、PV和PVC详解 当前&#xff0c;存储的方式和种类有很多&#xff0c;并且各种存储的参数也需要非常专业的技术人员才能够了解。在Kubernetes集群中&#xff0c;放了方便我们的使用和管理&#xff0c;Kubernetes提出了PV和PVC的概念&#xff0c;这样Kubernetes集群的管理人员就…

AJAX基础知识

定义 Ajax 异步 JavaScript 和 XML &#xff08; async javascript and xml &#xff09;&#xff0c;使用 Ajax 技术网页应用能够快速地将数据更新呈现在用户界面上&#xff0c;而不需要重载&#xff08;刷新&#xff09;整个页面&#xff0c;这使得程序能够更快地回应用户的操…

Spark基础笔记之启动命令顺序

系统环境&#xff08;三台虚拟机&#xff09; node1 192.168.32.101&#xff08;主&#xff09; node2 192.168.32.102 node3 192.168.32.103 1、启动hdfs、yarn、historyserver&#xff08;hadoop用户启动&#xff09; # 启动dfs&#xff0c;启动后的服务名&#xff1a; Da…

python 删除pdf 空白页

环境 python 3.10 PyPDF2 3.0.1 安装 pip install PyPDF2流程 将空白页和内容页读取出来&#xff0c;看看内部结构有什么不同以此为依据&#xff0c;遍历整个PDF 文件&#xff0c;标记处有内容的页面&#xff0c;写入到另外一个PDF文件。 python 代码 # 每一个页都是一个…

Godot引擎小白入门指南

哈喽&#xff0c;大家好呀&#xff0c;淼淼有来和大家见面啦&#xff0c;前几期和大家讲了Godot引擎的优势&#xff0c;Godot引擎是一款开源的跨平台游戏引擎&#xff0c;具有易学易用、功能强大、社区活跃等特点&#xff0c;因此备受开发者青睐。对于初学者来说&#xff0c;掌…

网页中的音视频裁剪拼接合并

一、需求描述 项目中有一个配音需求&#xff1a; 1&#xff09;首先&#xff0c;前台会拿到一个英语视频&#xff0c;视频的内容是A和B用英语交流&#xff1b; 2&#xff09;然后&#xff0c;用户可以选择为某一个角色配音&#xff0c;假如选择为A配音&#xff0c;那么视频在播…

【全开源】知识库文档系统源码(ThinkPHP+FastAdmin)

知识库文档系统源码&#xff1a;构建智慧知识库的基石 引言 在当今信息爆炸的时代&#xff0c;知识的有效管理和利用对于企业和个人来说至关重要。知识库文档系统源码正是为了满足这一需求而诞生的&#xff0c;它提供了一个高效、便捷的平台&#xff0c;帮助用户构建、管理、…

本地开发正常 线上CI/CD构建项目过程报错文件未能正确引用

问题快照 原因分析&#xff1a; 一般遇到这样的错误就是 文件路径或者文件名称未能正确匹配 或者文件不存在 会报这样的错误 以为很好解决 但这次 都排查 了 就是 没发现原因 不管怎么说还是要感谢 GPT的能力(分析问题的能力) 先上图 当我看到 第四步的时候 我立马 去仓库里查…