您的位置:首页 > 编程语言 > C语言/C++

二叉搜索树BST的C++实现

2016-11-05 17:58 761 查看
BST

包含的功能:插入,删除,查找,查找某一结点的后续和前驱,中序遍历和前序遍历

这里,用于实验的二叉树:



//二叉搜索树BST
#include <iostream>
#include <vector>
using namespace std;
class TreeNode{
public:
int key;
TreeNode* left;
TreeNode* right;
TreeNode* p;//指向父节点
public:
TreeNode();
TreeNode(int val);

};
TreeNode::TreeNode()
{
key=0;
left=right=p=NULL;
}
TreeNode::TreeNode(int val)
{
key=val;
left=right=p=NULL;
}
void inorder_tree_walk(TreeNode* x)
{
if(x!=NULL)
{
inorder_tree_walk(x->left);
cout<<x->key<<" ";
inorder_tree_walk(x->right);
}else
return;
}
void preorder_tree_walk(TreeNode*x)
{
if(x)
{
cout<<x->key<<" ";
preorder_tree_walk(x->left);
preorder_tree_walk(x->right);
}
}
TreeNode* tree_search(TreeNode* x, int k)
{
if(x==NULL||k==x->key)
return x;
if(k<x->key)
return tree_search(x->left,k);
else return tree_search(x->right,k);
}
TreeNode* tree_minmum(TreeNode* x)
{
while(x->left!=NULL)
x=x->left;
return x;
}
TreeNode* tree_maxmum(TreeNode* x)
{
while(x->right!=NULL)
x=x->right;
return x;
}
TreeNode* tree_successor(TreeNode* x)//大于x.key的最小关键字的节点为后继
{
if(x->right)
return tree_minmum(x->right);
TreeNode* y=x->p;
while(y&& x==y->right)
{
x=y;
y=y->p;
}
return y;
}
TreeNode* tree_predecessor(TreeNode* x)//小于x.key的最大关键字的节点为前驱
{
if(x->left)
return tree_maxmum(x->left);
TreeNode* y=x->p;
while(y&& x==y->left)
{
x=y;
y=y->p;
}
return y;
}
//c插入
void tree_insert(TreeNode* T, TreeNode* z) //T是现在的BST的树根
{
TreeNode * y,*x=T;
while(x)
{
y=x;
if(z->key<x->key)
x=x->left;
else x=x->right;
}
z->p=y;
if(!y)
T=z;//T是颗空树
else if(z->key<y->key)
y->left=z;
else y->right=z;
//	 return T;
}
//删除节点
void transplant(TreeNode* T, TreeNode* u,TreeNode* v)//用一颗子树代v替另一个子树u
{
if(u->p==NULL)
T=v;
else if(u==u->p->left)
u->p->left=v;
else u->p->right=v;
if(v)
v->p=u->p;
}
void tree_delete(TreeNode* T, TreeNode* z)
{
if(!z->left)
transplant(T,z,z->right);
else if(!z->right)
transplant(T,z,z->left);
else {
TreeNode* y=tree_minmum(z->right);
if(y->p!=z)
{
transplant(T,y,y->right);
y->right=z->right;
y->right->p=y;
}
transplant(T,z,y);
y->left=z->left;
y->left->p=y;
}
}
int main(){
TreeNode* T=new TreeNode(15);
//inorder_tree_walk(T);
int a[10]={6,18,3,7,17,20,2,4,13,9};
for(int i=0;i<10;i++)
{	TreeNode* z=new TreeNode(a[i]);
tree_insert(T,z);
}
inorder_tree_walk(T);cout<<endl;
preorder_tree_walk(T);
TreeNode* min=tree_minmum(T);
TreeNode* max=tree_maxmum(T);cout<<endl;
cout<<"最大值:"<<max->key<<"  最小值:"<<min->key<<endl;
cout<<"查找z=13的节点:";
TreeNode* z=tree_search(T,13);cout<<z->key<<endl;
TreeNode* prez=tree_predecessor(z);
TreeNode* sucz=tree_successor(z);
cout<<"z的前驱:"<<prez->key<<" "<<"z的后继:"<<sucz->key<<endl;
tree_delete(T,z);
cout<<"删除z之后:";
inorder_tree_walk(T);cout<<endl;
}


说明:第一行是中序遍历,第二行是先序遍历。



====================================================================================================

下面是各种遍历的非递归实现

//下面使用非递归的方式实现不同的遍历
void  inorder(TreeNode* root)
{
TreeNode* p = root;
stack<TreeNode*> s;
while (p != nullptr || !s.empty())
{
while (p != nullptr)//遍历左子树
{
s.push(p); //把遍历的节点全部入栈
p = p->left;
}
if (!s.empty())
{
printf("%d ", (p=s.top())->key);
s.pop();
p = p->right;//指向右子节点,下一次中序遍历右子树
}
}
printf("\n");
}
//非递归方法实现先序
void preorder(TreeNode* root)
{
TreeNode* p = root;
stack<TreeNode* > s;
while(p != nullptr || !s.empty())
{
while (p != nullptr)
{
printf("%d ", p->key);
s.push(p);
p = p->left;
}
if (!s.empty())
{
p = s.top();
s.pop();
p = p->right;
}
}
printf("\n");
}
//下面是实现后序
struct NewTreeNode {
TreeNode* node;
int tag;
NewTreeNode(TreeNode* t)
{
node = t;
tag = 0;
}
};
//先访问左子树,再访问右子树,访问根节点
//首先将T和tag=0入栈
void postorder(TreeNode* root)
{
stack<NewTreeNode*> s;
TreeNode* p = root;
NewTreeNode* t = nullptr;
while (p != nullptr || !s.empty())
{
while (p != nullptr)
{
s.push(new NewTreeNode(p));
p = p->left;
}
if (!s.empty())
{
t = s.top();
p = t->node;

if (t->tag)//已经遍历完右子树了
{
printf("%d ", p->key);
s.pop();
p = nullptr;
}
else
{
t->tag = 1;
p = p->right;
}
}
}
printf("\n");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: