二叉搜索树(BST树)的简单实现

本文介绍了一个二叉搜索树的模板实现,包括插入、删除、查找等核心操作,并提供了一个简单的测试示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#include<stdlib.h>
template
<typenameT>
classCBinSTree;

template
<typenameT>
classCTreeNode
ExpandedBlockStart.gifContractedBlock.gif
{//树节点类
public:
CTreeNode(
constT&item,CTreeNode<T>*lptr=NULL,CTreeNode<T>*rptr=NULL):data(item),left(lptr),right(rptr)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
}

CTreeNode
<T>*Left(void)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
returnleft;
}

CTreeNode
<T>*Right(void)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
returnright;
}

friend
classCBinSTree<T>;
public:
Tdata;
//数据
private:
CTreeNode
<T>*left;//左子树
CTreeNode<T>*right;//右子树
}
;

template
<typenameT>
classCBinSTree
ExpandedBlockStart.gifContractedBlock.gif
{//二叉搜索树类
public:
CBinSTree();
virtual~CBinSTree();
CBinSTree(
constCBinSTree<T>&tree);
CBinSTree
<T>&operator=(constCBinSTree<T>&rhs);
CTreeNode
<T>*FindNode(constT&item,CTreeNode<T>*&parent)const;//寻找节点
voidPrintTree();//前序遍历树(非递归)
voidClearTree();//清空树
voidInsert(constT&item);//插入数据
voidDelete(constT&item);//删除数据
boolContains(constT&item);//是否包含数据
CTreeNode<T>*FindMin()const;//找最小值
CTreeNode<T>*FindMax()const;//找最大值

protected:
//辅助函数区
CTreeNode<T>*GetTreeNode(constT&item,CTreeNode<T>*lptr=NULL,CTreeNode<T>*rptr=NULL);//分配树节点
voidFreeTreeNode(CTreeNode<T>*p);//释放树节点
voidDeleteTree(CTreeNode<T>*t);//删除树
CTreeNode<T>*CopyTree(CTreeNode<T>*t);//拷贝树
private:
CTreeNode
<T>*root;//二叉搜索树树根
intsize;//树节点个数
}
;

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#include"stdafx.h"
#include
"BinSTree.h"
#include
<iostream>
#include
<stack>
usingnamespacestd;

ExpandedBlockStart.gifContractedBlock.gif
/**///////////////////////////////////////////////////////////////////////
//Construction/Destruction
ExpandedBlockStart.gifContractedBlock.gif
/**///////////////////////////////////////////////////////////////////////
template<typenameT>
CBinSTree
<T>::CBinSTree()
ExpandedBlockStart.gifContractedBlock.gif
{
this->root=NULL;
this->size=0;
}

template
<typenameT>
CBinSTree
<T>::CBinSTree(constCBinSTree<T>&tree)
ExpandedBlockStart.gifContractedBlock.gif
{
root
=this->CopyTree(tree.root);
this->size=tree.size;
}

template
<typenameT>
CBinSTree
<T>::~CBinSTree()
ExpandedBlockStart.gifContractedBlock.gif
{
this->ClearTree();
}

template
<typenameT>
CBinSTree
<T>&CBinSTree<T>::operator=(constCBinSTree<T>&rhs)
ExpandedBlockStart.gifContractedBlock.gif
{
if(this==&rhs)
return*this;
this->ClearTree();
root
=this->CopyTree(rhs.root);
size
=rhs.size;
return*this;
}

template
<typenameT>
CTreeNode
<T>*CBinSTree<T>::GetTreeNode(constT&item,CTreeNode<T>*lptr,CTreeNode<T>*rptr)
ExpandedBlockStart.gifContractedBlock.gif
{
CTreeNode
<T>*p;
p
=newCTreeNode<T>(item,lptr,rptr);
if(p==NULL)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
cerr
<<"分配内存失败!"<<endl;
exit(
1);
}

returnp;
}

template
<typenameT>
CTreeNode
<T>*CBinSTree<T>::FindMin()const
ExpandedBlockStart.gifContractedBlock.gif
{
CTreeNode
<T>*t=root;
while(t->left!=NULL)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
t
=t->left;
}

returnt;
}

template
<typenameT>
CTreeNode
<T>*CBinSTree<T>::FindMax()const
ExpandedBlockStart.gifContractedBlock.gif
{
CTreeNode
<T>*t=root;
while(t->right!=NULL)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
t
=t->right;
}

returnt;
}

template
<typenameT>
boolCBinSTree<T>::Contains(constT&item)
ExpandedBlockStart.gifContractedBlock.gif
{
CTreeNode
<T>*p;
return(this->FindNode(item,p)!=NULL);
}

template
<typenameT>
CTreeNode
<T>*CBinSTree<T>::CopyTree(CTreeNode<T>*t)
ExpandedBlockStart.gifContractedBlock.gif
{
CTreeNode
<T>*newnode,*newlptr,*newrptr;
if(t==NULL)
returnNULL;
if(t->Left()!=NULL)
newlptr
=CopyTree(t->Left());
else
newlptr
=NULL;
if(t->Right()!=NULL)
newrptr
=CopyTree(t->Right());
else
newrptr
=NULL;
newnode
=GetTreeNode(t->data,newlptr,newrptr);
returnnewnode;
}

template
<typenameT>
voidCBinSTree<T>::FreeTreeNode(CTreeNode<T>*p)
ExpandedBlockStart.gifContractedBlock.gif
{
deletep;
p
=NULL;
}

template
<typenameT>
voidCBinSTree<T>::DeleteTree(CTreeNode<T>*t)
ExpandedBlockStart.gifContractedBlock.gif
{
if(t!=NULL)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
DeleteTree(t
->Left());
DeleteTree(t
->Right());
FreeTreeNode(t);
}

}

template
<typenameT>
voidCBinSTree<T>::ClearTree()
ExpandedBlockStart.gifContractedBlock.gif
{
DeleteTree(root);
root
=NULL;
}

template
<typenameT>
CTreeNode
<T>*CBinSTree<T>::FindNode(constT&item,CTreeNode<T>*&parent)const
ExpandedBlockStart.gifContractedBlock.gif
{
CTreeNode
<T>*t=root;
parent
=NULL;
while(t!=NULL)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
if(item==t->data)
break;
else
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
parent
=t;
if(item<t->data)
t
=t->Left();
else
t
=t->Right();
}

}

returnt;
}

template
<typenameT>
voidCBinSTree<T>::Insert(constT&item)
ExpandedBlockStart.gifContractedBlock.gif
{
CTreeNode
<T>*t=root,*parent=NULL,*newnode;
while(t!=NULL)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
parent
=t;
if(item<t->data)
t
=t->Left();
else
t
=t->Right();
}

newnode
=this->GetTreeNode(item);
if(parent==NULL)
root
=newnode;
elseif(item<parent->data)
parent
->left=newnode;
else
parent
->right=newnode;
size
++;
}

template
<typenameT>
voidCBinSTree<T>::Delete(constT&item)
ExpandedBlockStart.gifContractedBlock.gif
{
CTreeNode
<T>*pDNode,*pRNode,*pParNode;
if((pDNode=this->FindNode(item,pParNode))==NULL)
return;
if(pDNode->left==NULL)
pRNode
=pDNode->right;
elseif(pDNode->right==NULL)
pRNode
=pDNode->left;
else
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
CTreeNode
<T>*pParOfRNode=pDNode;
pRNode
=pDNode->left;
while(pRNode->right!=NULL)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
pParOfRNode
=pRNode;
pRNode
=pRNode->right;
}

if(pParOfRNode==pDNode)
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
pRNode
->right=pDNode->right;
}

else
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
pParOfRNode
->right=pRNode->left;
pRNode
->left=pDNode->left;
pRNode
->right=pDNode->right;
}

}

if(pParNode==NULL)
root
=pRNode;
elseif(pDNode->data<pParNode->data)
pParNode
->left=pRNode;
else
pParNode
->right=pRNode;
this->FreeTreeNode(pDNode);
this->size--;

}

template
<typenameT>
voidCBinSTree<T>::PrintTree()
ExpandedBlockStart.gifContractedBlock.gif
{
stack
<CTreeNode<T>*>s;
CTreeNode
<T>*p=root;
while(p!=NULL||!s.empty())
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
while(p!=NULL)//遍历左子树
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
cout
<<p->data<<endl;
s.push(p);
p
=p->Left();
}
//endwhile

if(!s.empty())
ExpandedSubBlockStart.gifContractedSubBlock.gif
{
p
=s.top();
s.pop();
p
=p->Right();//通过下一次循环实现右子树遍历
}
//endif
}

}

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->//test.cpp:Definestheentrypointfortheconsoleapplication.
//

#include
"stdafx.h"
#include
"BinSTree.cpp"
#include
<iostream>
usingnamespacestd;

CBinSTree
<int>*MakeSampleTree()
ExpandedBlockStart.gifContractedBlock.gif
{//示例BST树
CBinSTree<int>*tree1=newCBinSTree<int>();
inta=5;
tree1
->Insert(a);
tree1
->Insert(30);
tree1
->Insert(65);
tree1
->Insert(25);
tree1
->Insert(35);
tree1
->Insert(50);
tree1
->Insert(10);
tree1
->Insert(28);
tree1
->Insert(26);
tree1
->Insert(33);
returntree1;
}


intmain(intargc,char*argv[])
ExpandedBlockStart.gifContractedBlock.gif
{
CBinSTree
<int>*tree1=MakeSampleTree();
tree1
->PrintTree();
std::cout
<<"删除节点30:"<<endl;
tree1
->Delete(30);
tree1
->PrintTree();
cout
<<tree1->Contains(40)<<endl;
CTreeNode
<int>*p=tree1->FindMin();
cout
<<p->data<<endl;
return0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值