二叉搜索树(BST)——基本概念及基本实现代码

1.二叉搜索树概念

二叉搜索树是以一棵二叉树来组织的。每个节点是一个对象,包含的属性有left,right,p和key,其中,left指向该节点的左孩子,right指向该节点的右孩子,p指向该节点的父节点,key是它的值,如果某节点的孩子节点或父节点不存在,则相应属性设置为NULL。根节点是树中唯一一个父节点为NULL的节点。

BST中的关键字有如下特征:
假设x为BST里的一个节点:
(1)如果y为x的左子树里的一个节点,那么y.key<=x.key;
(2)如果y为x的右子树里的一个节点,那么y.key>=x.key.

下面是一个二叉搜索树的例子:

2.二叉搜索树的几个实现函数

2.1 自定义二叉搜索树的数据结构

//树节点
typedef struct Treenode{int key;Treenode *p;Treenode *left;Treenode *right;Treenode(int val):key(val),left(NULL),right(NULL),p(NULL) {}
};//树
typedef struct Tree{Treenode* root; //指向根节点
};

2.2 查询二叉搜索树

输入一个指向树根的指针和一个关键字k,如果这个节点存在,则返回一个指向关键字为k的节点的指针;否则返回NULL。

Treenode* TREE_SEARCH(Treenode *x, int k) {if(x==NULL || x->key==k) {return x;}if(k < x->key) {TREE_SEARCH(x->left, k);}if(k > x->key) {TREE_SEARCH(x->right, k);}
}

2.3 查找最小关键字元素

要求:
给定一棵树的根节点,返回指向这棵树中最小元素的指针。

思路:
若一个节点X没有左子树,那么由于其右子树里的节点都比它大,因此该节点在以其为根节点的这棵树里是最小的;若节点X有左子树那么由于右子树里的关键字都大于或等于X.key,而左子树里的节点的关键字都小于等于X.key,所以这棵树的最小元素一定在以X.left为根节点的子树里。

Treenode* TREE_MINIMUM(Treenode *x) {if(x->left == NULL) {return x;}return TREE_MINIMUM(x->left);
}

2.4 查找最大关键字元素

要求
给定一棵树的根节点,返回指向这棵树中最大元素的指针。

思路:
与查找最小关键字元素的思路一样。

Treenode* TREE_MAXIMUM(Treenode *x) {if(x->right == NULL) {return x;}return TREE_MAXIMUM(x->right);
}

2.5 查找后继

要求:
给定一个节点x,若该节点的后继存在,则返回一棵二叉搜索树里的节点x的后继节点;若节点x是该树中的最大关键字节点,则返回NULL。

思路:
一个节点的后继节点是关键字比它大的节点,如果该节点的关键字是树中的最大关键字,则其没有后继;如果不是最大关键字,那它一定有后继节点,这时分2种情况来考虑:
(1)节点x有右子树,那么后继节点就是右子树中关键字最小的节点,可以通过调用TREE_MINIMUM(x->right)获得;
(2)节点x没有右子树,假设其后继节点为y,那么y一定是x的低层祖先,且x在y的左子树里。例如下面这个例子,节点3没有右子树,那就从它的父节点开始,一直找父节点,直到找到一个祖先节点,x在其左子树里,那么这个节点就是其后继节点。

Treenode* TREE_SUCCESSOR(Treenode *x) {if(x->right != NULL) {return TREE_MINIMUM(x->right);}Treenode* p = x->p;Treenode* y = x;while(p != NULL) {if(p->left == y) {break;}y = p;p = p->p;}return p;
}

2.6 查找前驱

查找前驱与查找后继是对称的。

Treenode* TREE_PREDECESSOR(Treenode *x) {if(x->left != NULL) {return TREE_MAXIMUM(x->left);}Treenode* p = x->p;Treenode* y = x;while(p != NULL) {if(p->right == y) {break;}y = p;p = p->p;}return p;
}

2.7 插入

要求:
给一颗树及一个新节点的key,将新节点插入到树里的相应位置。

void TREE_INSERT(Tree* t, int insert_number) {/*构造新节点*/Treenode* new_node = (Treenode*)malloc(sizeof(Treenode));new_node->key = insert_number;new_node->left = new_node->right = new_node->p = NULL;Treenode* temp = t->root;//如果是一棵空树if(temp == NULL) {t->root = new_node;return;}Treenode* temp1;while(temp != NULL) {temp1 = temp;if(temp->key > insert_number) {temp = temp->left;}else if(temp->key < insert_number) {temp = temp->right;}}new_node->p = temp1;if(new_node->key < temp1->key) {temp1->left = new_node;}else {temp1->right = new_node;}}

2.8 删除

要求:
从一棵二叉搜索树T中删除一个给定节点z。

思路:
要分一下几种情况考虑:
(1)z没有左孩子
此时,用z的右孩子来替换z,其右孩子可以是NULL,也可以不是。

(2)z只有一个孩子,且为左孩子节点
此时用z的左孩子来替换z。

(3)z既有一个左孩子节点,又有一个右孩子节点
此时应该查找z的后继节点y,并用y来替换z。在上面已经介绍过,后继节点y一定在z的右子树里,且y没有左孩子。
此时又要分2种情况:
1)y是z的右孩子
此时应该用y替换z,并留下y的右子树。

2)y不是z的右孩子
此时应该先用y的右孩子替换y,然后再用y来替换z。

实现:
(1)子树移动
在上面的分析中可以看到,实现过程中需要移动子树,因此需要先实现一个函数TREE_TRANSPARENT,该函数实现了用一棵子树来替换另一棵子树并成为其父节点的孩子节点。

void TREE_TRANSPARENT(Tree* t, Treenode* x, Treenode* y) {Treenode* p = x->p;if(p == NULL) {t->root = y;}if(p != NULL) {if(p->left == x) {p->left = y;}else {p->right = y;}}if(y != NULL) {y->p = x->p;}
}

(2)节点删除

void TREE_DELETE(Tree* t, Treenode* x) {if(x->left == NULL) {TREE_TRANSPARENT(t, x, x->right);}else if(x->right == NULL) {TREE_TRANSPARENT(t, x, x->left);}else {Treenode* temp;temp = TREE_MINIMUM(x->right);if(x->right != temp) {TREE_TRANSPARENT(t, temp, temp->right);temp->right = x->right;x->right->p = temp;}TREE_TRANSPARENT(t, x, temp);temp->left = x->left;x->left->p = temp;}
}

二叉搜索树(BST)——基本概念及基本实现代码相关推荐

  1. 二叉搜索树(BST的理论剖析+代码实现)

    二叉搜索树(BST树) 文章目录 二叉搜索树(BST树) 1.二叉搜索树的概念 2.二叉搜索树的结构定义 2.1 二叉搜索树结点模板的定义 2.2 二叉搜索树类模板的定义 3.二叉搜索树的效率 4.二 ...

  2. 五.树,二叉树,二叉搜索树(BST)和自平衡二叉搜索树(AVL)

    1.树 树是一种数据结构 比如:目录结构 树是一种可以递归定义的数据结构 树是由n个节点组成的集合: 如果 n=0, 那这是一颗空树 如果 n>0, 那存在1个节点作为树的根节点,其他节点可以分 ...

  3. 【数据结构与算法】3.二叉搜索树(BST)、c++代码

    二叉搜索树(BST).c++代码 参考 https://blog.csdn.net/c_living/article/details/81021510

  4. 看动画学算法之:二叉搜索树BST

    文章目录 简介 BST的基本性质 BST的构建 BST的搜索 BST的插入 BST的删除 看动画学算法之:二叉搜索树BST 简介 树是类似于链表的数据结构,和链表的线性结构不同的是,树是具有层次结构的 ...

  5. 阿里开发者招聘节 | 面试题02-04:给定一个二叉搜索树(BST),找到树中第K小的节点

    为帮助开发者们提升面试技能.有机会入职阿里,云栖社区特别制作了这个专辑--阿里巴巴资深技术专家们结合多年的工作.面试经验总结提炼而成的面试真题这一次将陆续放出(面试题官方参考答案将在专辑结束后统一汇总 ...

  6. 二叉搜索树 (BST)

    二叉搜索树 (BST : Binary Search Tree) 又名 二叉查找树 或 二叉排序树. 二叉搜索树: 左孩子的值 一定小于或等于 父结点的值 二叉搜索树: 右孩子的值 一定大于或等于 父 ...

  7. 二叉搜索树BST的学习

    文章目录 二叉搜索树BST 什么是BST? 用BST做什么? 一.BST的特性 BST的特性是什么? 1.[230. 二叉搜索树中第K小的元素](https://leetcode.cn/problem ...

  8. 真c++ 从二叉树到红黑树(3)之二叉搜索树BST

      此文章为从二叉树到红黑树系列文章的第三节,主要介绍介绍二叉搜索树BST,为AVL和RedBlack打下基础 文章目录 一.前面文章链接~(点击右边波浪线可以返回目录) 二.二叉搜索树BST的定义~ ...

  9. 二叉搜索树BST红黑树

    二叉搜索树基础知识 提起红黑树咱们肯定要先说说这个二叉搜索树(BST) 二叉搜索树又叫二叉查找树,二叉排序树:它具有以下特点: 如果它的左子树不为空,则左子树上结点的值都小于根结点. 如果它的右子树不 ...

  10. 二叉搜索树(BST)详解

    数据结构:二叉搜索树(BST) 今天咱们来聊聊二叉搜索树,先从字面上来理解,二叉,指的是有两个分支,左子树和右子树:搜索树,啥意思呢,搜索,是不是就是之前学过dfs和bfs那边学过,对啊,dfs就是深 ...

最新文章

  1. c++ 终止 超时_C++ 哪里超时了啊?
  2. Django 的缓存机制
  3. abaqus python二次开发攻略_Abaqus有限元分析常见问题解答与实用技巧 12天后上架...
  4. C++union 联合
  5. 使用 create-react-app 构建 react应用程序
  6. 最近准备学习下mongodb(一 Windows安装篇)
  7. Java 类的封装、继承、多态
  8. python深度神经网络量化_「深度神经网络」(deep neural network)具体是怎样工作的?...
  9. MyCms自媒体内容管理系统 v1.6.0.1
  10. PAT乙级 1003
  11. 【mysql union all limit的使用】
  12. Thunderspy: 7个硬件漏洞,影响9年来所有安装 Thunderbolt 的电脑
  13. mysql 索引 数据页_数据库索引数据页
  14. 图解设计模式 - Adapter 模式
  15. android Pbap下载手机电话簿协议介绍
  16. Java 拾遗补阙 ----- Switch case语句
  17. bilibili视频爬取与水印去除
  18. java动态写入ppt_使用POI操作PPT文档(插入文本、图片)转
  19. linux tc 限速,linux tc 限速
  20. 大学到底教会了我们什么?

热门文章

  1. foxmail国外只能收邮件,不能发邮件
  2. 用户数据报协议(UDP)
  3. php将ts文件输出,使用DOS命令合并TS流文件
  4. php什么框架,php快速开发用什么框架
  5. 开源分布式存储系统的对比
  6. AFN的简单介绍及使用
  7. 希尔排序|Golang
  8. NB-IOT与物联网
  9. 推荐!国外程序员整理的Java资源大全
  10. 什么是端口?要如何修改端口?