树由节点和边组成。整棵树有一个最上端的节点,称为根节点(root)。每个节点可以拥有具方向性的边,用来和其他节点相连。相连节点之中,在上者称为父节点,在下者称为子节点。无子节点者称为叶节点。根节点至任何节点之间有唯一的路径,路径所经过的边数我们称作路径长度。根节点至任一节点的路径长度我们称作该节点的深度。根节点的深度永远是0。某节点至其最深的子节点的路径长度,我们称为该节点的高度。
子节点如果最多拥有两个子节点,即所谓的二叉树。二叉树的应用极为广泛,比如语法树,编译器的表达树,哈夫曼编码树等等。
二叉树查找树(二叉搜索树或者静态二叉查找树)可以提供对数时间的元素插入和删除的操作。二叉树查找树的任何节点的键值一定大于其左子树中任意节点的键值,一定小于其右子树中任意节点的键值。
二叉查找树的实现如下:
#include<iostream>
#include<vector>
typedef int ElemType;
typedef struct BstTreeNode* TreeNode;
struct BstTreeNode {
ElemType value;
TreeNode rchild;
TreeNode lchild;
public:
BstTreeNode(const ElemType _value) :value(_value) {};
BstTreeNode() {};
};
class BstTree {
public:
BstTree() :root(nullptr) {};
~BstTree() {
if (root!=nullptr) {
delete root;
}
}
public:
TreeNode Find(const ElemType key);
TreeNode GetParentNode(const ElemType key);
TreeNode FindMin()const;
TreeNode FindMax()const;
void Insert(const ElemType key);
void Delete(const ElemType key);
void Display();
private:
TreeNode root;
private:
TreeNode _Find(TreeNode& node, const ElemType key)const;
TreeNode _GetParentNode(TreeNode& node, const ElemType key)const;
void _Insert(TreeNode& node, const ElemType key);
void _Delete(TreeNode& node, const ElemType key);
void _Display(TreeNode& node);
TreeNode _FindMin(TreeNode& node)const;
TreeNode _FindMax(TreeNode& node)const;
};
TreeNode BstTree::Find(const ElemType key) {
return _Find(root, key);
}
TreeNode BstTree::GetParentNode(const ElemType key) {
return _GetParentNode(root, key);
}
TreeNode BstTree::FindMin()const {
TreeNode p = root;
if (p != nullptr) {
while (p->lchild != nullptr)
p = p->lchild;
}
return p;
}
TreeNode BstTree::FindMax()const {
TreeNode p = root;
if (p != nullptr) {
while (p->rchild != nullptr) {
p = p->rchild;
}
}
return p;
}
void BstTree::Insert(const ElemType key) {
_Insert(root, key);
}
void BstTree::Delete(const ElemType key) {
_Delete(root, key);
}
void BstTree::Display() {
_Display(root);
}
TreeNode BstTree::_Find(TreeNode& node, const ElemType key)const {
if (node->value < key)
_Find(node->rchild, key);
else if (node->value > key)
_Find(node->lchild, key);
else
return node;
}
TreeNode BstTree::_GetParentNode(TreeNode& node, const ElemType key)const {
TreeNode parent = nullptr;
if (node->lchild != nullptr || node->rchild != nullptr) {
if (node->lchild->value == key || node->rchild->value == key) {
parent = node;
return parent;
}
_GetParentNode(node->lchild, key);
_GetParentNode(node->rchild, key);
}
}
void BstTree::_Insert(TreeNode& node, const ElemType key) {
if (node == nullptr) {
node = new BstTreeNode(key);
node->lchild = nullptr;
node->rchild = nullptr;
}
else {
if (node->value > key)
_Insert(node->lchild, key);
else if (node->value < key)
_Insert(node->rchild, key);
else
return;
}
}
void BstTree::_Delete(TreeNode& node, const ElemType key) {
TreeNode temp = new BstTreeNode();
if (node == nullptr)
throw std::out_of_range("BstTree is empty");
else if (node->value > key)
_Delete(node->lchild, key);
else if (node->value < key)
_Delete(node->rchild, key);
else {
if (node->lchild!=nullptr && node->rchild!=nullptr) {
temp = _FindMin(node->rchild);
node->value = temp->value;
_Delete(node->rchild, node->value);
}
else {
temp = node;
if (node->lchild == nullptr)
node = node->rchild;
else if (node->rchild == nullptr)
node = node->lchild;
else
delete temp;
}
}
}
void BstTree::_Display(TreeNode& node) {
if (node == nullptr)
return;
else {
std::cout << node->value << std::endl;
_Display(node->lchild);
_Display(node->rchild);
}
}
TreeNode BstTree::_FindMin(TreeNode& node)const {
if (node == nullptr)
return nullptr;
else {
while (node->lchild != nullptr)
node = node->lchild;
}
return node;
}
TreeNode BstTree::_FindMax(TreeNode& node)const {
if (node == nullptr)
return nullptr;
else {
while (node->rchild != nullptr)
node = node->rchild;
}
return node;
}
int main(void)
{
BstTree bsttree;
std::vector<int>vec{ 9,5,3,56,12,78,54,1 };
for (const auto& x : vec) {
bsttree.Insert(x);
}
bsttree.Display();
std::cout << std::endl;
std::cout << "Delete a elem :1" << std::endl;
bsttree.Delete(1);
bsttree.Display();
return 0;
}