目录

二叉排序树(二叉搜索树)定义:

二叉排序树的性质:

二叉排序树的操作:

c语言实现二叉排序树:

C++实现二叉排序树:


二叉排序树(二叉搜索树)定义:

 

 二叉排序树的性质:

(1)二叉排序树的中序遍历序列是递增的

推论:只给出二叉排序树的后序/前序序列,可以唯一确定二叉排序树

(2)根最左下节点值最小,根最右下节点值最大

 二叉排序树的操作:

1在二叉排序树中查找一个元素k:

过程类似于二分查找:如果mid=k,返回mid;如果mid>k,向左区间中查找;如果mid<k,向右区间中查找

时间复杂度:O(log2n)

①递归出口:如果根节点为空,或者根节点值等于待查找的元素,返回根节点

②如果根节点的值<k,向左子树中查找

③如果根节点的值>k,向右子树中查找

伪代码:

search(root,k):
if root==null or k==root的值return root
if root的值>k递归调用函数search(root->left,k)
if  root的值<k递归调用函数search(root->right,k)

 2 在二叉排序树中插入一个值为k元素

在二叉排序树中插入一个关键字为k的节点要保证插入后仍满足二叉排序树有序的性质

时间复杂度:O(log2n)

伪代码:

insert(root,k):
if root==NULL新建一个值为k的nodereturn node
if k==root的值无需插入
if k<root的值//k插入到左子树 insert(root->left,k)
else//k插入到右子树insert(root->right,k)

3 由一个数组创建一个二叉排序树

创建二叉排序树的根节点,扫描数组,并逐个插入到二叉排序树中

create(root,int a[])
{ 为root申请内存空间for(i:a)insert(root,a[i])
}

4在二叉排序树中删除一个元素k

递归实现:

递归调用:①如果k<根节点的值,向左子树中删除k

递归调用:②如果k>根节点的值,向右子树删除k

递归出口:③如果k=根节点的值,分三种情况讨论

Ⅰ根节点既有左子树又有右子树,用根节点的中序后继节点替代根节点

在二叉排序树中, 根节点的中序后继节点为根节点右子树的最左下节点(因为该节点的值是右子树中大于根节点的最小的值)

Ⅱ根节点左子树为空,用右子树替代根节点,即返回右子树

Ⅲ根节点右子树为空,用左子树替代根节点,即返回左子树

Ⅳ根节点左右子树均为空即根节点是叶子节点,返回空

例:

5.判定一棵树是否是二叉排序树

利用二叉排序中序遍历递增的性质:中序遍历该树,判断该中序序列是否是递增序列

c语言实现:

声明二叉排序树结点类型

typedef struct node
{KeyType key;                   //关键字项InfoType data;                    //其他数据域struct node *lchild,*rchild; //左右孩子指针
} BSTNode;                          //二叉排序树结点类型

二叉排序树的插入:

bool InsertBST(BSTNode *&bt,KeyType k)
//在二叉排序树bt中插入一个关键字为k的结点。插入成功返回真,否则返回假
{   if (bt==NULL)                     //原树为空,新插入的结点为根结点{   bt=(BSTNode *)malloc(sizeof(BSTNode));bt->key=k; bt->lchild=bt->rchild=NULL;return true;}else if (k==bt->key)                 //树中存在相同关键字的结点,返回假return false;else if (k<bt->key) return InsertBST(bt->lchild,k);  //插入到左子树中elsereturn InsertBST(bt->rchild,k); //插入到右子树中
}

二叉排序树的建立:

BSTNode *CreateBST(KeyType A[],int n)        //创建二叉排序树
//返回BST树根结点指针
{   BSTNode *bt=NULL;              //初始时bt为空树int i=0;while (i<n){  InsertBST(bt,A[i]);         //将关键字A[i]插入二叉排序树bt中i++;}return bt;                       //返回建立的二叉排序树的根指针
}

二叉排序树的查找:

STNode *SearchBST(BSTNode *bt,KeyType k)
{ if (bt==NULL || bt->key==k)        //递归终结条件return bt;if (k<bt->key)return SearchBST(bt->lchild,k);  //在左子树中递归查找elsereturn SearchBST(bt->rchild,k);  //在右子树中递归查找
}

二叉排序树的删除:

void Delete1(BSTNode *p,BSTNode *&r)  //当被删p结点有左右子树时的删除过程
{BSTNode *q;if (r->rchild!=NULL)Delete1(p,r->rchild);    //递归找最右下结点r,r结点的值是p结点的中序后缀结点else                        //找到了最右下结点r{    p->key=r->key;           //将*结点的值赋给结点pq=r;                  r=r->lchild;            //直接将其左子树的根结点放在被删结点的位置上free(q);             //释放原结点r的空间}
}
void Delete(BSTNode *&p)        //从二叉排序树中删除p结点
{BSTNode *q;if (p->rchild==NULL)       //p结点没有右子树的情况{q=p;p=p->lchild;         //直接将其右子树的根结点放在被删结点的位置上free(q);  }else if (p->lchild==NULL)    //p结点没有左子树的情况{q=p;p=p->rchild;         //将p结点的右子树作为双亲结点的相应子树free(q);  }else Delete1(p,p->lchild);   //p结点既没有左子树又没有右子树的情况
}
int DeleteBST(BSTNode *&bt,KeyType k)   //在bt中删除关键字为k的结点
{if (bt==NULL) return 0;              //空树删除失败else {  if (k<bt->key) return DeleteBST(bt->lchild,k); //递归在左子树中删除为k的结点else if (k>bt->key) return DeleteBST(bt->rchild,k);    //递归在右子树中删除为k的结点else {Delete(bt);       //调用Delete(bt)函数删除*bt结点return 1;}}
}

C++实现二叉排序树:

声明节点类型

struct TreeNode {int val;//结点值TreeNode *left;//左孩子结点TreeNode *right;//右孩子节点TreeNode() : val(0), left(nullptr), right(nullptr) {}//构造函数1TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}//构造函数2TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}//构造函数3
};

二叉排序树的插入:

class Solution {
public:TreeNode* insertIntoBST(TreeNode* root, int val) {
//如果根节点为空,返回以val创建的根节点
if(root==NULL)
{TreeNode *node=new TreeNode(val);return node;
}
//如果根节点的值小于val,val插入到右子树,
if(root->val<val)
{TreeNode*r=insertIntoBST(root->right,val);//返回插入后右子树的根节点root->right=r;return root;
}
//如果根节点的值大于Val,val插入到左子树,
else
{TreeNode*l=insertIntoBST(root->left,val);//返回插入后左子树的根节点root->left=l;return root;
}}
};

二叉排序树的查找:

class Solution {
public:TreeNode* searchBST(TreeNode* root, int val) {
if(root==NULL)
return NULL;
if(root->val==val)
return root;
if(root->val<val)
{return searchBST(root->right,val);
}
else
{return searchBST(root->left,val);
}}
};

二叉排序树的删除:

/*** Definition for a binary tree node.* 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 *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:TreeNode* deleteNode(TreeNode* root, int key) {
//如果根节点为空,没有节点可以删除,返回空
if(root==NULL)
{return NULL;
}
//如果key<根节点的值,在左子树中删除
if(key<root->val)
{//递归调用函数删除左子树中的key,返回左子树的根节点root->left=deleteNode(root->left,key);
}
//如果key>根节点的值,在右子树中删除
else if(key>root->val)
{//递归调用函数删除右子树中的Key,返回右子树的根节点root->right=deleteNode(root->right,key);
}
//找到了待删除的节点
else{
//如果该节点既有左孩子节点又有右孩子节点,则寻找当前节点的中序后继节点,即右子树中最左下节点
if(root->left&&root->right)
{
TreeNode *pre=root;
TreeNode *next=root->right;
while(next->left!=NULL)
{pre=next;next=next->left;
}
//pre为右子树最左下节点的前一个节点,next为右子树的最左下节点//如果右子树的最左下节点为本身
if(pre==root)
{pre->right=next->right;
}else{pre->left=next->right;
}
root->val=next->val;}
//左子树为空(以保证左右子树至少有一个为空)
else if(root->left==NULL)
{return root->right;
}else{return root->left;
}}
return root;}
};

判定二叉搜索树:

class Solution {
public:vector<int>vec;
//将树的中序遍历存放在vec数组中void inorder(TreeNode *root){if(root==NULL)return;inorder(root->left);vec.push_back(root->val);inorder(root->right);}bool isValidBST(TreeNode* root) {inorder(root);
//判断数组是否递增
for(int i=0;i<vec.size()-1;i++)
{if(vec[i]>=vec[i+1])return false;
}
return true;}
};

【数据结构和算法笔记】用c和c++分别实现二叉搜索树相关推荐

  1. 数据结构与算法--求1~n能组成的所有二叉搜索树的排列

    给定一个整数n,生成并返回所有N个节点组成并且节点值从1到n互不相同的不同二叉树,可以按照任意顺序 二叉树文章列表: 数据结构与算法–面试必问AVL树原理及实现 数据结构与算法–二叉树的深度问题 数据 ...

  2. 【数据结构与算法】之深入解析“序列化和反序列化二叉搜索树”的求解思路与算法示例

    一.题目要求 序列化是将数据结构或对象转换为一系列位的过程,以便它可以存储在文件或内存缓冲区中,或通过网络连接链路传输,以便稍后在同一个或另一个计算机环境中重建. 设计一个算法来序列化和反序列化 二叉 ...

  3. 【数据结构笔记27】树习题:完全二叉搜索树(Complete Binary Search Tree)

    本次笔记内容: 树习题-CBST. 1 数据结构的选择 树习题-CBST. 2 核心算法 树习题-CBST. 3 计算左子树的规模 文章目录 题意理解 分析:用链表还是数组表示树 核心算法 核心递归算 ...

  4. 数据结构与算法实验 实验6:二叉树ADT的二叉链式实现 (由完全前序序列创建二叉树 / 求二叉树的节点数/树高/叶子节点数 /先序中序后序层序遍历)

    假设二叉数的数据元素为字符,采用二叉链式存储结构.请编码实现二叉树ADT,其中包括创建二叉树.遍历二叉树(深度.广度).求二叉树的深度(高度).计算二叉树的元素个数.计算二叉树的叶子数.二叉树的格式输 ...

  5. 【LeetCode笔记】剑指 Offer 68 - I. 二叉搜索树的最近公共祖先(Java、二叉树、dfs)

    文章目录 思路 & 代码 代码 & 思路 二刷 思路 & 代码 应该在二叉树的最近公共祖先之前写= = 需要用到二叉搜索树的特性- 代码 & 思路 分成四种情况即可,具 ...

  6. 九章基础算法04:二叉搜索树与哈希表

    目录 1. 什么是二叉搜索树 1.1 二叉搜索树结构 1.2 二叉搜索树特性应用 2. 二叉搜索树基础实现 2.1 BST类型与构造函数 2.2 插入操作 2.2.1 思路分析 2.2.2 递归实现 ...

  7. 数据结构与算法笔记 - 绪论

    数据结构与算法笔记 - 绪论 1. 什么是计算 2. 评判DSA优劣的参照(直尺) 3. 度量DSA性能的尺度(刻度) 4. DSA的性能度量的方法 5. DSA性能的设计及其优化 x1. 理论模型与 ...

  8. 数据结构与算法笔记(十六)—— 二叉搜索树

    一.二叉搜索树定义 二叉搜索树(Binary Search Tree),又名二叉排序树(Binary Sort Tree). 二叉搜索树是具有有以下性质的二叉树: 若左子树不为空,则左子树上所有节点的 ...

  9. 数据结构与算法笔记(十五)—— 散列(哈希表)

    一.前沿 1.1.直接寻址表 当关键字的全域U比较小时,直接寻址是一种简单而有效的技术.假设某应用要用到一个动态集合,其中每个元素都有一个取自全域U={0,1,-,m-1)的关键字,此处m是一个不很大 ...

  10. 明翰数据结构与算法笔记V0.8(持续更新)

    文章目录 前言 数据结构 `线性表` `数组` `链表` `栈与队列` [串/字符串] 树 并查集 `二叉树` [二叉排序树/二叉搜索树] `红黑树` 红黑树操作 霍夫曼树 `堆` [大/小]根堆 可 ...

最新文章

  1. ajax连mysql数据库_AJAX调用mysql数据库简单例子
  2. .NET6之MiniAPI(二十七):Metrics
  3. C++类和new、delete操作符和堆和栈内存的分配
  4. 紧急通知,三星未收购智能家居公司
  5. php 虚类,减伤、虚弱类技能汇总 - 游戏服务区 - 《洛克王国》官方论坛 - Powered by Discuz!...
  6. java ArrayListLinkList
  7. firefox使用掘金插件_谷歌浏览器常用插件
  8. 重定向,用户管理,密码管理,权限管理
  9. cd linux如何连接wifi,cdlinux万能无线系统使用教程
  10. 我的管理成长与思考 - 那些领导的真相,理解和思考
  11. Java练习——小游戏 模拟雷电
  12. 厉害了!28岁程序员期权过亿,彪悍从字节退休!
  13. linux 查看裸设备与lv,LINUX 如何查看裸设备
  14. Java 8 reduce 是什么
  15. 左手画方右手画圆代码
  16. 1.3-聊天机器人的模块和框架
  17. 网易魔兽怀旧服服务器型号,魔兽世界所有怀旧服服务器名称已出,你觉得哪些名称更好听呢?...
  18. 迅雷Bolt的ClipSubBindBitmap函数特别说明
  19. HEC-RAS水动力模型的一维二维及耦合建模
  20. 2008.06.02 读华为前执行副总裁李玉琢的《我与商业领袖的合作与冲突》有感(三)

热门文章

  1. CCF201803-4 棋局评估(100分)【博弈+DFS】
  2. UVA11040 Add bricks in the wall【数学】
  3. CCF NOI1136 单词分类
  4. CCF201604-4 游戏(100分)
  5. 字面量(literal)与 C 语言复合字面量(compound literals)
  6. Xavier Initialization 的理解与推导(及实现)
  7. matplotlib tricks(一)—— 多类别数据的 scatter(cmap)
  8. negative binomial(Pascal) distribution —— 负二项式分布(帕斯卡分布)
  9. windows 使用 tricks
  10. C Tricks(二)—— 按块访问二维数组