树的定义
一棵树是由n(n>0)个元素组成的有限集合,其中:
(1)每个元素称为结点(node)
(2)有一个特定的结点,称为根结点或树根(root)
(3)除根节点外,其余节点能分成m(m>=0)个互不相交的有限集合 T(0)-T(m-1)。其中的每一个子集都是一个树,这些集合被称为这棵树的子树。
如下图是一棵树:

树的基本概念
A. 树是由递归定义的
B. 一棵树中至少有1个结点。这个节点就是根节点,他没有前驱,其余每个节点都有且只有一个前驱节点。每个节点可以有任意个后继结点。因此,树是非线性结构,但也是有序结构。
C. 一个节点的子树个数称为这个结点的度,例如上图根节点的度为2。度为0的结点被称为叶结点;度不为0的结点被称为分支结点,根以外的分支节点称为内部结点,树中各节点的度的最大值称为这棵树的度。
D. 在用图形表示的树形结构中,对两个用线段(我们称为树枝)连接的相关联的结点,称上端结点为下端节点的父节点,反之为子节点。
E. 定义一棵树的根的层次为1,其他结点的层次等于他的父节点的层次加一。一棵树中所有节点的层次的最大值称为这棵树的深度。
F. 对于树中任意两个不同的结点,从一个结点出发一定能到达另一个结点。
G.m(m>=0)棵树的结合称为森林。
树的遍历
在解决问题时,常常要按照某种次序来获取树中全部节点的信息,这种操作叫做树的遍历。
A. 先序遍历 先访问根节点,然后按照左右先后顺序遍历各子树(根左右)
B. 中序遍历 先访问左子树,然后访问根,最后访问右子树(左根右)
C. 层次遍历 按层次的大笑从小到大遍历,同一层次按照从左到右的顺序。
二叉树基本概念
二叉树(binary tree,简称BT),是一种特殊的树,它的度是2。一个节点有两个子节点,其中左边的是左子节点,右边的是右子节点。左边的叫左子树,右边的叫右子树。
二叉树的性质
(1)在二叉树的第 i 层上最多有 个结点(i>=1)
(2)深度为 k 的二叉树至多有 个结点(k>=1)
特别的,深度为 k ,且有 个结点的二叉树称为满二叉树。
(3)对于任意一棵二叉树,如果其叶子结点数为 ,度为 2 的结点数为
,那么
。
(4)具有 n 个结点的完全二叉树的深度为 。
二叉树的实现
上面我们介绍了树和二叉树,那么我们现在研究一下二叉树的实现,注意,这里默认你有一些 C++ 基础。
首先我们来创建一个二叉树结点类 BSTNode,然后在类中创建几个 BSTNode 类型的变量,值,左子节点,右子节点,父节点。
int _key;
BSTNode *_left; //左子节点
BSTNode *_right; //右子节点
BSTNode *_parent; //父节点
然后我们初始化,这里使用列表初始化。
BSTNode(int k = 0, BSTNode *l = NULL, BSTNode *r = NULL, BSTNode *p = NULL) : _key(k), _left(l), _right(r), _parent(p) {};
接下来,我们来创建一个二叉树类 BinaryTree ,来写二叉树的各种操作函数。
我们先声明函数
void insert(int _key); //将_key节点插入到二叉树中
void PreOrder(); //前序二叉树遍历
void InOrder(); //中序二叉树遍历
void PostOrder(); //后序二叉树遍历BSTNode *search(int _key); //递归实现,在二叉树中查找_key节点
BSTNode *IteratorSearch(int _key); //迭代实现,在二叉树中查找_key节点BSTNode *successor(BSTNode *x); //找节点(x)的后继节点。即,查找"二叉树中数据值大于该节点"的"最小节点"
BSTNode *predecessor(BSTNode *x); //找节点(x)的前驱节点。即,查找"二叉树中数据值小于该节点"的"最大节点"void remove(int _key); //删除_key节点void destroy(); //销毁二叉树
这里包括了二叉树的基本操作。
类的private部分:
BSTNode *_root; //根节点
void PreOrder(BSTNode *tree); //前序二叉树遍历
void InOrder(BSTNode *tree); //中序二叉树遍历
void PostOrder(BSTNode *tree); //后序二叉树遍历BSTNode *search(BSTNode *x, int _key); //递归实现,在”二叉树x“中查找_key节点
BSTNode *IteratorSearch(BSTNode *x, int _key); //迭代实现,在“二叉树x”中查找_key节点BSTNode *minimum(BSTNode *tree); //查找最小节点:返回tree为根节点的二叉树的最小节点
BSTNode *maximum(BSTNode *tree); //查找最大节点:返回tree为根节点的二叉树的最大节点void insert(BSTNode *&tree, BSTNode *z); // 将节点(z)插入到二叉树(tree)中BSTNode *remove(BSTNode *tree, BSTNode *z); // 删除二叉树(tree)中的节点(z),并返回被删除的节点void destroy(BSTNode *&tree); //销毁二叉树
也是声明了一些函数。
插入元素
void BinaryTree::insert(int _key) //将_key节点插入到二叉树中
{BSTNode *z = new BSTNode(_key, NULL, NULL, NULL);if (z == NULL){return; }insert(_root, z);
}
void BinaryTree::insert(BSTNode *&tree, BSTNode *z) // 将节点(z)插入到二叉树(tree)中
{BSTNode *y = NULL;BSTNode *x = tree;while (x != NULL) {y = x;if (z->_key < x->_key){x = x->_left;}else{x = x->_right;}}z->_parent = y;if (y == NULL){tree = z;}elseif (z->_key < y->_key){y->_left = z;}else{y->_right = z;}
}
首先创建一个结点,如果节点的值(key)是空(NULL)的话就结束函数,如果不为空的话就执行insert函数。insert函数的内容是循环树只要不为空,按照树的顺序找到合适的位置插入元素。
删除结点
BSTNode *BinaryTree::remove(BSTNode *tree, BSTNode *z) // 删除二叉树(tree)中的节点(z),并返回被删除的节点
{BSTNode *x = NULL;BSTNode *y = NULL;if (z->_left == NULL || z->_right == NULL){y = z;}else{y = successor(z);}if (y->_left != NULL){x = y->_left;}else{x = y->_right;}if (x != NULL){x->_parent = y->_parent;}if (y->_parent == NULL){tree = x;}elseif (y == y->_parent->_left){y->_parent->_left = x;}else{y->_parent->_right = x;}if (y != z){z->_key = y->_key;}return y;
}
void BinaryTree::remove(int _key) // 删除二叉树(tree)中的节点(z),并返回被删除的节点
{BSTNode *z, *node;z = IteratorSearch(_root, _key); if (z == _root){cout<<"Root can't be delete!"<<endl;}if (z != NULL && z->_parent != NULL && z != _root){node = remove(_root, z); if (node != NULL){delete node;}}
}
销毁二叉树
void BinaryTree::destroy(BSTNode *&tree) //销毁二叉树
{if (tree == NULL){return; }if (tree->_left != NULL){return destroy(tree->_left);}if (tree->_right != NULL){return destroy(tree->_right);}delete tree;tree = NULL;
}void BinaryTree::destroy() //销毁二叉树
{destroy(_root);
}
完整代码
/*文件创建者: 112233-星澜-imimbert创建日期: 2023.1.12 12:33功能: 二叉树
*/
#include <iostream>
using namespace std;class BSTNode
{
public:int _key; BSTNode *_left; //左子节点BSTNode *_right; //右子节点BSTNode *_parent; //父节点BSTNode(int k = 0, BSTNode *l = NULL, BSTNode *r = NULL, BSTNode *p = NULL) : _key(k), _left(l), _right(r), _parent(p) {}; //初始化列表
};class BinaryTree
{
/***** @author 112233-imimbert-星澜* @since -verson: 1.0.0* @date 2021-01-12* @pre 二叉树已经创建* @include iostream
****/
public:BinaryTree(); ~BinaryTree(); void insert(int _key); //将_key节点插入到二叉树中void PreOrder(); //前序二叉树遍历void InOrder(); //中序二叉树遍历void PostOrder(); //后序二叉树遍历BSTNode *search(int _key); //递归实现,在二叉树中查找_key节点BSTNode *IteratorSearch(int _key); //迭代实现,在二叉树中查找_key节点BSTNode *successor(BSTNode *x); //找节点(x)的后继节点。即,查找"二叉树中数据值大于该节点"的"最小节点"BSTNode *predecessor(BSTNode *x); //找节点(x)的前驱节点。即,查找"二叉树中数据值小于该节点"的"最大节点"void remove(int _key); //删除_key节点void destroy(); //销毁二叉树private:BSTNode *_root; //根节点void PreOrder(BSTNode *tree); //前序二叉树遍历void InOrder(BSTNode *tree); //中序二叉树遍历void PostOrder(BSTNode *tree); //后序二叉树遍历BSTNode *search(BSTNode *x, int _key); //递归实现,在”二叉树x“中查找_key节点BSTNode *IteratorSearch(BSTNode *x, int _key); //迭代实现,在“二叉树x”中查找_key节点BSTNode *minimum(BSTNode *tree); //查找最小节点:返回tree为根节点的二叉树的最小节点BSTNode *maximum(BSTNode *tree); //查找最大节点:返回tree为根节点的二叉树的最大节点void insert(BSTNode *&tree, BSTNode *z); // 将节点(z)插入到二叉树(tree)中BSTNode *remove(BSTNode *tree, BSTNode *z); // 删除二叉树(tree)中的节点(z),并返回被删除的节点void destroy(BSTNode *&tree); //销毁二叉树
};BinaryTree::BinaryTree() :_root(NULL) {}; BinaryTree::~BinaryTree()
{destroy();
}void BinaryTree::insert(int _key) //将_key节点插入到二叉树中
{BSTNode *z = new BSTNode(_key, NULL, NULL, NULL);if (z == NULL){return; }insert(_root, z);
}void BinaryTree::PreOrder(BSTNode *tree) //前序二叉树遍历
{if (tree != NULL){cout << tree->_key << " ";PreOrder(tree->_left);PreOrder(tree->_right);}
}
void BinaryTree::PreOrder()
{PreOrder(_root);
}void BinaryTree::InOrder(BSTNode *tree) //中序二叉树遍历
{if (tree != NULL){InOrder(tree->_left);cout << tree->_key << " ";InOrder(tree->_right);}
}
void BinaryTree::InOrder()
{InOrder(_root);
}
void BinaryTree::PostOrder(BSTNode *tree) //后序二叉树遍历
{if (tree != NULL){PostOrder(tree->_left);PostOrder(tree->_right);cout << tree->_key << " ";}
}
void BinaryTree::PostOrder()
{PostOrder(_root);
}
BSTNode *BinaryTree::search(BSTNode *x, int _key) //递归实现,在”二叉树x“中查找_key节点
{if (x == NULL || _key == x->_key){return x;}if (_key < x->_key){return search(x->_left, _key);}else{return search(x->_right, _key);}
}
BSTNode *BinaryTree::search(int _key)
{return search(_root, _key);
}
BSTNode *BinaryTree::IteratorSearch(BSTNode *x, int _key) //迭代实现,在“二叉树x”中查找_key节点
{while (x != NULL && _key != x->_key){if (_key < x->_key){x = x->_left;}else{x = x->_right;}}return x;
}
BSTNode *BinaryTree::IteratorSearch(int _key)
{return IteratorSearch(_root, _key); //传入根节点和待查找的关键字_key
}
BSTNode *BinaryTree::minimum(BSTNode *tree) //查找最小节点:返回tree为根节点的二叉树的最小节点。
{if (tree == NULL){return NULL;}while (tree->_left != NULL){tree = tree->_left;}return tree;
}BSTNode *BinaryTree::maximum(BSTNode *tree) //查找最大节点:返回tree为根节点的二叉树的最大节点。
{while (tree->_right != NULL){tree = tree->_right;}return tree;
}
BSTNode *BinaryTree::successor(BSTNode *x) //找节点(x)的后继节点,也就是该节点的右子树中的最小节点
{BSTNode *y = NULL;if (x->_right != NULL){return minimum(x->_right); }y = x->_parent;while (y != NULL && x == y->_right){x = y;y = y->_parent;}return y;
}BSTNode *BinaryTree::predecessor(BSTNode *x) //找节点(x)的前驱节点是该节点的左子树中的最大节点。
{BSTNode *y = NULL;if (x->_left != NULL){return maximum(x->_left);}y = x->_parent;while (y != NULL && x == y->_left){x = y;y = y->_parent;}return y;
}void BinaryTree::insert(BSTNode *&tree, BSTNode *z) // 将节点(z)插入到二叉树(tree)中
{BSTNode *y = NULL;BSTNode *x = tree;while (x != NULL) {y = x;if (z->_key < x->_key){x = x->_left;}else{x = x->_right;}}z->_parent = y;if (y == NULL){tree = z;}elseif (z->_key < y->_key){y->_left = z;}else{y->_right = z;}
}BSTNode *BinaryTree::remove(BSTNode *tree, BSTNode *z) // 删除二叉树(tree)中的节点(z),并返回被删除的节点
{BSTNode *x = NULL;BSTNode *y = NULL;if (z->_left == NULL || z->_right == NULL){y = z;}else{y = successor(z);}if (y->_left != NULL){x = y->_left;}else{x = y->_right;}if (x != NULL){x->_parent = y->_parent;}if (y->_parent == NULL){tree = x;}elseif (y == y->_parent->_left){y->_parent->_left = x;}else{y->_parent->_right = x;}if (y != z){z->_key = y->_key;}return y;
}void BinaryTree::remove(int _key) // 删除二叉树(tree)中的节点(z),并返回被删除的节点
{BSTNode *z, *node;z = IteratorSearch(_root, _key); if (z == _root){cout<<"Root can't be delete!"<<endl;}if (z != NULL && z->_parent != NULL && z != _root){node = remove(_root, z); if (node != NULL){delete node;}}
}void BinaryTree::destroy(BSTNode *&tree) //销毁二叉树
{if (tree == NULL){return; }if (tree->_left != NULL){return destroy(tree->_left);}if (tree->_right != NULL){return destroy(tree->_right);}delete tree;tree = NULL;
}void BinaryTree::destroy() //销毁二叉树
{destroy(_root);
}int main()
{/************************//* 插入/************************/BinaryTree *tree = new BinaryTree();int array[6] = {12, 33, 18, 24, 44, 66};cout << "二叉树数值:" << endl;for (int i = 0; i < 6; i++){cout << array[i] << " ";tree->insert(array[i]); //调用插入函数,生成二叉查找树}cout << endl << endl;/************************//* 遍历 /************************/cout << "前序遍历:";tree->PreOrder();cout << endl;cout << "中序遍历:";tree->InOrder();cout << endl;cout << "后序遍历:";tree->PostOrder();cout << endl << endl;/************************//* 查找 /************************/int _keyword; //查找节点的关键字cout << "请输入要查找的节点:";cin >> _keyword;cout << endl;BSTNode *node = tree->IteratorSearch(_keyword); //获取数值的地址if (node) //判断有没有地址{cout << "关键字为“" << _keyword << "”的节点,存在。" << endl ;}else{cout << "关键字为“" << _keyword << "”的节点,不存在。" << endl;}cout << endl << endl;/************************//* 删除/************************/int DelNode; //要删除的节点cout << "请输入要删除的节点:";cin >> DelNode;tree->remove(DelNode);cout << endl;cout << "删除操作后,(前序)遍历:";tree->PreOrder();cout << endl;cout << "删除操作后,(中序)遍历:";tree->InOrder();cout << endl;cout << "删除操作后,(后序)遍历:";tree->PostOrder();cout << endl << endl;/************************//* 销毁/************************/tree->destroy();system("pause");return 0;
}