二叉树
这里的二叉树类型分别包含关键字key,left、right、parent、指针分别指向左孩子、右孩子、双亲。若对应节点不存在就用nullptr空指针代替。这里的二叉搜索树,对于任何节点x,其左子数的关键字最大不超过x->key,其右子树的关键字不低于x->key。二叉树遍历有中序,先序,后序三种遍历方式,根据输出的根关键字在其左右子树间的位置来命名,这边里的函数是中序遍历。
这边要注意的是插入与删除函数,插入函数是先遍历指针找到插入元素可以所在的位置插入。而删除函数略微复杂分四种情况讨论如图所示:
删除函数有用到转移节点的函数和寻找后继的函数,下面的代码中都有些到。
#include <iostream>
using namespace std;
struct tree
{
int key;
tree*left,*right,*parent;
};
void insert_tree(tree*&T,int d)
{
tree*x=T,*y=nullptr,*z=new tree;
z->left=nullptr;
z->right=nullptr;
z->parent=nullptr;
z->key=d;
while (x!=nullptr)
{
y=x;
if(d<x->key)
x=x->left;
else x=x->right;
}
z->parent=y;
if (y==nullptr)
T=z;
else if(z->key<y->key)
y->left=z;
else y->right=z;
}
void inorder_tree(tree*x)
{
if (x->left!=nullptr)
inorder_tree(x->left);
cout<<x->key<<" ";
if(x->right!=nullptr)
inorder_tree(x->right);
}
tree* tree_search(tree*x,int k)
{
if (k==x->key)
return x;
if (k<x->key)
return tree_search(x->left,k);
else return tree_search(x->right,k);
}
void transplant(tree *&T,tree*&u,tree*&v)
{
if(u->parent==nullptr)
T=v;
else if(u==u->parent->left)
u->parent->left=v;
else u->parent->right=v;
if (v!=nullptr)
v->parent=u->parent;
}
tree* tree_min(tree*x)
{
while(x->left!=nullptr)
x=x->left;
return x;
}
tree* tree_delete(tree*T,tree*z)
{
tree*y;
if(z->left==nullptr)
transplant(T,z,z->right);
else if(z->right==nullptr)
transplant(T,z,z->left);
else {y=tree_min(z->right);
if(y->parent!=z)
{
transplant(T,y,y->right);
y->right=z->right;
y->right->parent=y;
}
transplant(T,z,y);
y->left=z->left;
y->left->parent=y;}
return T;
}
int main()
{
tree *T=new tree;
T->left=nullptr;
T->right=nullptr;
T->parent=nullptr;
int d,n;
cin>>n;
cin>>T->key;
for(int i=1;i<n;i++)
{
cin>>d;
insert_tree(T,d);
}
inorder_tree(T);
tree*x=T;
x=x->left;
T=tree_delete(T,T);
cout<<endl;
inorder_tree(T);
return 0;
}
建立二叉树插入节点遍历节点输出和删除根的结果图: