news 2026/4/16 11:50:38

二叉排序树(Binary Search Tree, BST)是一种重要的数据结构,具有良好的查找、插入和删除性能

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
二叉排序树(Binary Search Tree, BST)是一种重要的数据结构,具有良好的查找、插入和删除性能

二叉排序树(Binary Search Tree, BST)是一种重要的数据结构,具有良好的查找、插入和删除性能。以下是针对你提出的问题的详细解答:


1. 二叉排序树的查找算法(SearchBST)

// 定义二叉树节点结构typedefstructBSTNode{intdata;structBSTNode*left,*right;}BSTNode,*BSTree;/** * 在二叉排序树中查找关键字 key * @param T: 当前树根节点 * @param key: 要查找的关键字 * @param father: 记录查找路径中的父节点(用于插入时定位) * @return: 找到返回该节点,否则返回 NULL */BSTNode*SearchBST(BSTree T,intkey,BSTNode*father){if(T==NULL)returnNULL;// 空树则未找到if(key==T->data)returnT;// 找到目标节点elseif(key<T->data)returnSearchBST(T->left,key,T);// 向左子树查找,当前节点成为潜在父亲elsereturnSearchBST(T->right,key,T);// 向右子树查找,当前节点成为潜在父亲}

说明father参数通过递归传递,记录最后访问的非空节点(即插入位置的父节点),便于后续插入操作。


2. 二叉排序树的构造过程

构造基于逐个插入元素的过程,遵循以下规则:

  • 若树为空,则第一个节点为根;
  • 对每个新元素,从根开始比较:
    • 小于当前节点 → 进入左子树;
    • 大于当前节点 → 进入右子树;
    • 直到遇到空指针位置进行插入。
示例:{46, 25, 54, 13, 29, 91}
插入顺序操作
46创建根节点
2525 < 46 → 插入 46 的左子树
5454 > 46 → 插入 46 的右子树
1313 < 46 → 左;13 < 25 → 插入 25 的左子树
2929 < 46 → 左;29 > 25 → 插入 25 的右子树
9191 > 46 → 右;91 > 54 → 插入 54 的右子树

最终形成的树结构如下(缩进表示层次):

46 / \ 25 54 / \ \ 13 29 91

3. 二叉排序树的插入算法(InsertBST)

/** * 插入新关键字 newkey 到二叉排序树 * @param root: 指向根节点的指针(可能需要修改根) * @param newkey: 新的关键字 * @return: 成功返回 0,已存在返回 -1 */intInsertBST(BSTree*root,intnewkey){BSTNode*parent=NULL;BSTNode*found=SearchBST(*root,newkey,NULL);if(found!=NULL)return-1;// 关键字已存在,不允许重复// 创建新节点BSTNode*newNode=(BSTNode*)malloc(sizeof(BSTNode));if(!newNode)return-1;// 内存分配失败newNode->data=newkey;newNode->left=newNode->right=NULL;// 查找插入位置及其父节点BSTNode*current=*root;parent=NULL;while(current!=NULL){parent=current;if(newkey<current->data)current=current->left;elsecurrent=current->right;}// 插入新节点if(parent==NULL){*root=newNode;// 树为空,新节点作为根}elseif(newkey<parent->data){parent->left=newNode;}else{parent->right=newNode;}return0;// 插入成功}

注意:使用双重指针BSTree* root是为了在根为空时能正确修改根节点。


二叉排序树的特点总结

特性说明
有序性中序遍历可得有序序列,支持高效查找
平均时间复杂度查找/插入/删除:O(log n)(平衡情况下)
最坏情况当输入有序时,退化为链表,时间复杂度变为 O(n)
结构依赖插入顺序不同插入顺序生成不同形状的树,影响效率
优化方向使用平衡二叉树(如 AVL、红黑树)避免退化

要验证一棵二叉树是否为二叉排序树(BST),最有效的方法是利用其核心性质:中序遍历的结果必须是一个严格递增的序列


✅ 验证方法:基于中序遍历

我们可以通过中序遍历二叉树,并在访问节点时检查当前节点的值是否大于前一个访问的节点值。如果是,则继续;否则不是 BST。

使用非递归或递归方式均可,但关键是要维护“前驱节点”的值进行比较。


🟩 方法一:递归 + 引用前驱值(推荐)
#include<stdio.h>#include<stdlib.h>#include<limits.h>// 二叉树节点定义typedefstructTreeNode{intval;structTreeNode*left;structTreeNode*right;}TreeNode;// 辅助函数:判断是否为BSTboolisValidBSTHelper(TreeNode*root,long*prev){if(root==NULL)returntrue;// 左子树必须是BSTif(!isValidBSTHelper(root->left,prev))returnfalse;// 当前节点必须大于前一个节点值if(root->val<=*prev)returnfalse;*prev=root->val;// 更新前驱值// 右子树必须是BSTreturnisValidBSTHelper(root->right,prev);}/** * 判断是否为二叉排序树 * @param root: 根节点 * @return: 是返回 true,否则返回 false */boolisValidBST(TreeNode*root){longprev=LONG_MIN;// 初始化为最小长整型,避免越界returnisValidBSTHelper(root,&prev);}

说明

  • 使用long类型防止int最小值被误判。
  • prev记录中序遍历过程中上一个访问节点的值。
  • 所有节点必须满足当前值 > prev,即严格递增

🟨 方法二:中序遍历存数组后判断有序性(简单直观)
voidinorder(TreeNode*root,int*arr,int*idx){if(root==NULL)return;inorder(root->left,arr,idx);arr[(*idx)++]=root->val;inorder(root->right,arr,idx);}boolisSorted(int*arr,intn){for(inti=1;i<n;i++)if(arr[i]<=arr[i-1])returnfalse;returntrue;}boolisValidBST_Array(TreeNode*root){intarr[10000],idx=0;inorder(root,arr,&idx);returnisSorted(arr,idx);}

缺点:需要额外 O(n) 空间,效率较低,适合教学理解。


⚠️ 注意事项

  1. 必须是“严格递增”:不允许相等(除非题目允许重复元素且规定右子树 ≥ 根)。
  2. 不能只比较父子关系:例如:
    5 / \ 3 8 / \ 2 6 / 4
    虽然每个父节点与子节点满足大小关系,但左子树中的4 < 5却出现在右分支中 —— 实际上这棵树仍是合法的?不!此例需具体分析路径上下界!

👉 更高级写法可用带上下界的递归来处理跨层约束。


🔍 带上下界的递归验证法(更严谨)

boolvalidate(TreeNode*node,longminVal,longmaxVal){if(node==NULL)returntrue;if(node->val<=minVal||node->val>=maxVal)returnfalse;returnvalidate(node->left,minVal,node->val)&&validate(node->right,node->val,maxVal);}boolisValidBST_Bound(TreeNode*root){returnvalidate(root,LONG_MIN,LONG_MAX);}

此方法可防止某些“局部满足但全局违反”的情况。


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 14:35:51

Markdown编写技术文档利器:记录lora-scripts项目全过程

lora-scripts&#xff1a;让LoRA微调像写文档一样简单 在AIGC&#xff08;AI生成内容&#xff09;爆发的今天&#xff0c;越来越多个人开发者和小型团队希望基于Stable Diffusion或大语言模型定制专属风格——比如训练一个“专属动漫角色”、打造一种“赛博朋克画风”&#xff…

作者头像 李华
网站建设 2026/4/16 13:35:16

CSDN官网热议:腾讯最新OCR模型到底强在哪里?

腾讯HunyuanOCR为何引爆技术圈&#xff1f;一文看懂其背后的技术革新 在文档数字化浪潮席卷各行各业的今天&#xff0c;一个看似不起眼但影响深远的问题始终困扰着开发者和企业&#xff1a;如何让OCR&#xff08;光学字符识别&#xff09;真正“好用”&#xff1f; 传统OCR方案…

作者头像 李华
网站建设 2026/4/16 12:42:04

C#调用Python服务?在.NET环境中集成HunyuanOCR的方法

C#调用Python服务&#xff1f;在.NET环境中集成HunyuanOCR的方法 在企业级系统开发中&#xff0c;我们常常面临这样一个现实&#xff1a;业务逻辑稳定、架构成熟&#xff0c;但一旦涉及AI能力——比如图像识别或自然语言处理&#xff0c;就显得力不从心。尤其是以C#为主导的.NE…

作者头像 李华
网站建设 2026/4/12 20:47:04

适配多种任务类型:lora-scripts对LLaMA 2、ChatGLM等LLM的支持

适配多种任务类型&#xff1a;lora-scripts对LLaMA 2、ChatGLM等LLM的支持 在大模型时代&#xff0c;一个现实问题始终困扰着开发者&#xff1a;如何用有限的算力资源&#xff0c;让通用语言模型真正“懂”某个专业领域&#xff1f;比如&#xff0c;你手握一个70亿参数的LLaMA …

作者头像 李华
网站建设 2026/4/16 12:46:42

消费级显卡也能跑!lora-scripts支持RTX3090/4090低资源训练LoRA

消费级显卡也能跑&#xff01;lora-scripts支持RTX3090/4090低资源训练LoRA 在生成式AI席卷创意与产业的今天&#xff0c;一个曾经遥不可及的梦想正变得触手可及&#xff1a;普通人用一张家用显卡&#xff0c;也能训练出属于自己的专属AI模型。这不再是实验室里的专利&#xff…

作者头像 李华
网站建设 2026/4/16 12:42:19

仓库货物智能检测:从YOLOv11模型训练到UI界面开发,一站式搞定仓储自动化检测方案

文章目录 仓库货物智能检测:从YOLOv11模型训练到UI界面开发,一站式搞定仓储自动化检测方案 一、项目背景:为什么要做仓库货物智能检测? 二、核心技术:YOLOv11为何是仓储检测的优选? (1)YOLOv11的核心优势 三、数据集准备:让模型“见多识广”的关键一步 (1)数据集选择…

作者头像 李华