二叉树的描述
相当于给树来个计划生育
二叉树的原理
二叉树只允许最多两个节点 二叉树节点最多有两个节点 并不是一定要有两个分支节点
如图所示:
-
在非空的二叉树里,具有i-1层的节点的总数不超过2的i-1次方 i>=1
-
深度为h-1的二叉树 最多有二的h次方 -1个结点 最少有h个结点
- 对任意一颗二叉树 若叶子节点的数量表示为N0 而度数为二的树数量 为表示为N2 则 N0=N2+1;
若像单传那样n2=0 n1表示单传 根节点 只有一个子节点
,若其中有一个有俩节点 则n2+1;
常见二叉树分类
完全二叉树
- 最后一层的最后一个节点 可有可无 其他的都是满的 才叫 完全二叉树:
- 叶子节点必须从左到右排列 右子树的叶子节点 必须右缺 不能左缺
错误的完全二叉树:
完全二叉树的应用:堆
满二叉树
- 也就是叶子结点全部都存在
- ,并且左子树和右子树都必须是满
平衡二叉树
- 树的两个子树的高度差绝对值不能超过1
- 而且还得看 左右子树的两个子树的高度差绝对值不能超过1
- 而且还得看 左右子树的两个子树的高度差绝对值不能超过1
二叉搜索树
- 二叉搜索树 也叫二叉排序树
- 若左子树不为空 左子树均小于或者等于根节点
- 若右子树不为空 右子树均大于或者等于根节点
红黑树
-
带有颜色属性的平衡二叉搜索树
- 节点的颜色属性是黑色或者红色
- 根节点是黑色
- 所有的叶子节点都是黑色
- 每个红色节点必须有两个黑色节点
- 黑色节点的子节点可红可黑
- 红色节点的子节点必须是黑色节点
注意:不允许红色节点拥有两个连续红色子节点
-
错误的红黑树
-
从任何非叶子节点到其每个叶子节点的所有简单路径都包含相同数目黑色节点
-
右子树比左子树 的数目多出两倍
-
不同的黑色节点 添加一个红色节点
为啥使用二叉搜索树
就像是电商里商品价格如下:
如果挨个去查找 9.9 元的 小零食效率很显然 ,现在很明显是在第2位置 如何大大的提高呢
先排序 价格 再来查找 你会发现不一样的美观 强迫症患者的福报,简直是
经过排序:
再用二分查找算法 怎么一查找就非常快 , 原理非常简单 就是从中间开始,如果 查找值 这个中间的比要小 那么排除中间+的数据 直接往左 直到找到 为止,否则往右查找
二叉搜索树 就是非常符合查找数据 而且 也是两个分支一个左,右分支
也非常复合人的特征 大脑分为左,右脑 ,手分为左,右手 脚分为左,右脚
二叉搜索树存储方式
那采用什么方式存储,如果是用顺序存储二叉树 那就是堆 ?
存储方式:链式存储
二叉搜索树节点
这个二叉搜索树和链表不一样 很明显 在这里LeftChild,RightChild 分别指向会 LeftChild,RightChild 分支 在二叉树的描述…
二叉搜索树算法
二叉搜索树的结构
using TreeKey = user defined;
// 树节点 = 二叉搜索树节点
using TreeNode = struct _BinarySearchTreeNode;
struct _BinarySearchTreeNode{
TreeKey value;//tree value
TreeNode* LeftChild;//左孩子
TreeNode* RightChild;//右孩子
};
//二叉搜索树
struct BinarySearchTree {
TreeNode* Root;//树的根节点
size_t size;// 二叉搜索树的节点个数
};
二叉搜索树算法声明
#ifndef __BINARY_SEARCH_TREE_H__
#define __BINARY_SEARCH_TREE_H__
using TreeKey = = user defined;;
using TreeNode = struct _BinarySearchTreeNode;
struct _BinarySearchTreeNode{
TreeKey value;
TreeNode* LeftChild;
TreeNode* RightChild;
};
struct BinarySearchTree {
TreeNode* Root;//树的根节点
size_t size;// 二叉搜索树的节点个数
};
//查找当前结点中最大或者最小值
struct FindCurrentNodeMaxOrMinValue{
TreeKey* MaxOrnMinValue;
bool isExist;
};
//查找二叉搜索树结点 类型
struct FindTreeNode_type {
TreeNode* Node;
bool isExist;
};
//查找二叉搜索树value类型
struct FindTreeValue_type {
TreeKey* value;
bool isExist;
};
//二叉搜索树删除算法类型
enum class BinarySearchTreeDeletionAlgorithmType{
Loop,//用循环来删除
Recursive, //用递归来删除
};
//二叉搜索树删除算法类型
using BSTDeleteAlgorithmType = BinarySearchTreeDeletionAlgorithmType;
//二叉搜索树查找算法类型
enum class BinarySearchTreeSearchAlgorithmType {
Loop,//用循环来查找
Recursive, //用递归来查找
};
//二叉搜索树查找算法类型
using BSTSearchAlgorithmType = BinarySearchTreeSearchAlgorithmType;
//二叉搜索树遍历算法类型
enum class BinarySearchTreeTraversalAlgorithmType {
Recursive,
NoRecursive
};
//二叉搜索树遍历算法类型
using BSTTraversalAlgorithmType = BinarySearchTreeTraversalAlgorithmType;
//初始化二叉搜索树
void InitBinarySearchTree(BinarySearchTree& Tree, TreeNode * const &InitRoot = nullptr);
//初始化二叉搜索树
void BinarySearchTree_Build(BinarySearchTree& Tree, const TreeKey* const array, int arraySize);
//插入数据到二叉搜索树
void BinarySearchTree_Insert(BinarySearchTree& tree, const TreeKey& value);
//从二叉搜索树中删除指定的元素
bool BinarySearchTree_Erase(BinarySearchTree& tree, const TreeKey& Key, BSTDeleteAlgorithmType Defaultdelete = BSTDeleteAlgorithmType::Loop);
//二叉搜索树搜索指定元素
FindTreeValue_type BinarySearchTree_Search(BinarySearchTree& tree, const TreeKey& Key, BSTSearchAlgorithmType DefaultSearch = BSTSearchAlgorithmType::Loop);
//先序遍历
void FirstOrderTraversal(BinarySearchTree& tree, BSTTraversalAlgorithmType DefaultTraversal= BSTTraversalAlgorithmType::NoRecursive);
//中序遍历
void InOrderTraversal(BinarySearchTree& tree, BSTTraversalAlgorithmType DefaultTraversal = BSTTraversalAlgorithmType::NoRecursive);
//后序遍历
void LastOrderTraversal(BinarySearchTree& tree, BSTTraversalAlgorithmType DefaultTraversal = BSTTraversalAlgorithmType::NoRecursive);
//层序遍历
void LevelOrderTraversal(BinarySearchTree& tree);
//销毁二叉搜索树
void DestroyBinarySearchTree(BinarySearchTree& tree);
//按照值查找节点
FindTreeNode_type BinarySearchTree_FindTreeNode(TreeNode*& RootNode, const TreeKey& Key);
//按照值查找当前节点的父节点
FindTreeNode_type BinarySearchTree_FindTreeParentNode(TreeNode*& RootNode, const TreeKey& Key);
// 查找当前节点最大值或者最小值
FindCurrentNodeMaxOrMinValue BinarySearchTree_FindMaxOrMinValue(TreeNode*& Currentnode);
#endif
二叉搜索树初始化
void InitBinarySearchTree(BinarySearchTree& Tree, TreeNode* const& InitRoot){
Tree.Root = InitRoot;
Tree.size = 0u;
}
二叉搜索树构建算法
void BinarySearchTree_Build(BinarySearchTree& Tree, const TreeKey *const array, int arraySize){
if (arraySize>0 && array) {
InitBinarySearchTree(Tree);
auto First = array;
auto Last = array + arraySize;
while (First!=Last){
auto &value = *First++;
BinarySearchTree_Insert(Tree, value);
}
}
}
二叉搜索树插入算法
思维导图
流程图
void BinarySearchTree_Insert(BinarySearchTree & tree, const TreeKey & value) {
//创建二叉树搜索树节点
TreeNode* newTreeNode = CreateBnarySearchTreeNode(value)