首先小鱼介绍一下几类树的区别及性质:
树:既是一种递归结构,也是一种层次结构。
二叉树:n个节点的有限集合,或为空树,或为由一个根节点及两棵(左右子树)互不相交的二叉树组成。
满二叉树:绝对的三角形,最后一层全为叶子结点
节点数与深度的关系:n=(2^k)-1
第i层的节点数:2^(i-1)
同时可以通过编号的序号来确定该节点的位置
eg:编号13的父节点为13/2=6;
且13编号的节点为编号6的右节点(奇数为右节点,偶数为左节点);
编号13的左节点为13*2;
编号13的右节点为13*2+1
正因为满二叉树的这一特点,所以一般采用顺序结构而不是链式结构存储满二叉树。
完全二叉树:特殊的满二叉树,因为其最后一层不要求完整
eg:堆为典型的完全二叉树
具有n个节点的完全二叉树深度为:log n +1(因为n=(2^k)-1)
二叉查找树(BST)(又称二叉排序树,二叉搜索树):构造二叉查找树的目的不是为了排序,而是为了提高查找和插入及删除的速度。
二叉平衡树:为一种二叉排序树,左子树和右子树都为平衡二叉树,且左子树和右子树的高度差的绝对值不会超过1。
BST的各项操作:节点插入、节点删除、节点值的查找:查找max,min及特定节点的前驱和后继
#include<stdio.h>
#include<stdlib.h>
using namespace std;
template<class T>
struct TreeNode
{
T element;
TreeNode<T> *parent, *lnode, *rnode;
TreeNode() { parent = lnode = rnode = NULL };
TreeNode(const T &key)
{
element = key;
parent = lnode = rnode = NULL;
}
};
template<class T>
class Bstree
{
public:
Bstree():root(NULL){}
//获取根节点
TreeNode<T> *Getroot() { return root; }
//中序遍历
void Inorder(TreeNode<T> *node);
//递归查找
TreeNode<T> *TreeSearch(TreeNode<T> *node, T key);
//迭代查找
TreeNode<T> *IterativeTreeSearch(TreeNode<T> *node, T key);
//插入元素
void TreeInsert(T key);
//最大值
TreeNode<T> *TreeMax(TreeNode<T> *node);
//最小值
TreeNode<T> *TreeMin(TreeNode<T> *node);
//查找前驱节点
TreeNode<T> *TreePredecessor(T key);
//查找后继节点
TreeNode<T> *TreeSuccessor(T key);
//用节点M代替节点N
void TransPlant(TreeNode<T>*nodeM, TreeNode<T>*nodeN);
//删除节点是key的元素
void Delete(T key);
private:
TreeNode<T>* root;
};
//中序遍历
template<class T>
void Bstree<T>::Inorder(TreeNode<T> *node)
{
if (node==NULL)
{
return;
}
else
{
Inorder(node->lnode);
cout << node->element << " ";
Inorder(node->rnode);
}
}
//递归查找
template<class T>
TreeNode<T>* Bstree<T>::TreeSearch(TreeNode<T> *node, T key)
{
if (node==NULL||key==node->element)
{
if (node==NULL)
{
cout << "not exist" << endl;
}
else
{
cout << "exist" << endl;
}
return node;
}
if (key>node->element)
{
return TreeSearch(node->rnode, key);
}
else
{
return TreeSearch(node->lnode, key);
}
}
//迭代查找
template<class T>
TreeNode<T>* Bstree<T>::IterativeTreeSearch(TreeNode<T> *node, T key)
{
while (node!=NULL&&key!=node->element)
{
if (key<node->element)
{
node = node->lnode;
}
else
{
node = node->rnode;
}
}
if (node==NULL)
{
cout << "not exist" << endl;
}
else
{
cout << "exist" << endl;
}
return node;
}
//插入元素
template<class T>
void Bstree<T>::TreeInsert(T key)
{
TreeNode<T>* y = NULL;
TreeNode<T>* x = root;
TreeNode<T>* z = new TreeNode<T>(key);//将要插入的元素放入创建的新节点中
while (x!=NULL)//找到要插入位置的双亲节点
{
y = x;
if (z->element<x->element)
{
x = x->lnode;
}
else
{
x = x->rnode;
}
}
z->parent = y;
if (y==NULL)//判断要插入的是左还是右节点
{
root = z;
}
else if(z->element>y->element)
{
y->rnode = z;
}
else
{
y->lnode = z;
}
}
//最大值(即一直遍历到节点的右子树)
template<class T>
TreeNode<T>* Bstree<T>::TreeMax(TreeNode<T> *node)
{
while (node->rnode!=NULL)
{
node = node->rnode;
}
cout << "max is: " << node->element << endl;
return node;
}
//最小值(即一直遍历到节点的左子树)
template<class T>
TreeNode<T>* Bstree<T>::TreeMin(TreeNode<T> *node)
{
while (node!=NULL)
{
node = node->lnode;
}
cout << "min is:" << node->element << endl;
return node;
}
//查找前驱节点
template<class T>
TreeNode<T>* Bstree<T>::TreePredecessor(T key)
{
TreeNode<T>* x = TreeSearch(root, key);//查找关键字key对应的节点
if (x->lnode!=NULL)
{
return TreeMax(x->lnode)//若x的左子树不为空,则返回左子树的最右边数
}
TreeNode<T>* y = x->parent;
while (y!=NULL&&x==y->lnode)
{
x = y;
y = y->lnode;//用while循环,一直到最左边
}
return y;
}
//查找前驱节点
template<class T>
TreeNode<T>* Bstree<T>::TreeSuccessor(T key)
{
TreeNode<T>* x = TreeSearch(root, key);
if (x->rnode!=NULL)
{
return TreeMin(x->rnode);
}
//若不存在右节点
//1、if(x==x->parent->lnode),则x的后继为x的双亲节点
//2、if(x==x->parent->rnode),则x的双亲都小于x,直到x的某一祖先yn为左节点时,yn的双亲为x的后继
TreeNode<T>* y=x->parent;
while (y!=NULL&&x==y->rnode)
{
x = y;
y = y->parent;
}
return y;
}
//用结点 m 替换结点 n,不包括v的左右子树的更新
template<class T>
void Bstree<T>::TransPlant(TreeNode<T>* nodeM, TreeNode<T>* nodeN)
{
if (nodeN->parent == NULL)
root = nodeM;
else if (nodeN == nodeN->parent->lnode) // nodeN 是左结点,更新nodeN->parent 的左结点
nodeN->parent->lnode = nodeM;
else
nodeN->parent->rnode = nodeM;
if (nodeM != NULL)
nodeM->parent = nodeN->parent;
}
//删除节点是key的元素
template<class T>
void Bstree<T>::Delete(T key)
{
TreeNode<T>* z = IterativeTreeSearch(root, key);//z为要删除的节点
if(z->lnode==NULL)
{
TransPlant(z->rnode, z);
}
else if (z->rnode==NULL)
{
TransPlant(z->lnode, z);
}
else
{
//找要删除结点的后继元素
TreeNode<T>* y = TreeMin(z->rnode);//类的成员函数在调用成员函数(模板)时,直接写函数名,不需要<T>
if (y->psrent != z)
{
TransPlant(y->rnode, y); //用 y 的右结点替代 y
y->rnode = z->rnode; //y的右结点 = z的右结点
y->rnode->parent = y;
}
TransPlant(y, z); //用 y替代z
y->lnode = z->lnode;
y->lnode->parent = y;
}
}
int main()
{
return 0;
}
该代码参考:二叉排序树的各项操作
有问题请留言,小鱼会尽快回答的,一起加油,喜欢请点个赞哦