#include <stdlib.h>
template<typename T>
class CBinSTree;

template <typename T>
class CTreeNode


{//树节点类
public:
CTreeNode(const T& item,CTreeNode<T>* lptr = NULL,CTreeNode<T>* rptr = NULL):data(item),left(lptr),right(rptr)

{
}
CTreeNode<T>* Left(void)

{
return left;
}
CTreeNode<T>* Right(void)

{
return right;
}
friend class CBinSTree<T>;
public:
T data;//数据
private:
CTreeNode<T>* left;//左子树
CTreeNode<T>* right;//右子树
};

template<typename T>
class CBinSTree


{//二叉搜索树类
public:
CBinSTree();
virtual ~CBinSTree();
CBinSTree(const CBinSTree<T>& tree);
CBinSTree<T>& operator = (const CBinSTree<T>& rhs);
CTreeNode<T>* FindNode(const T& item,CTreeNode<T>* &parent)const;//寻找节点
void PrintTree();//前序遍历树(非递归)
void ClearTree();//清空树
void Insert(const T& item);//插入数据
void Delete(const T& item);//删除数据
bool Contains(const T& item);//是否包含数据
CTreeNode<T>* FindMin()const;//找最小值
CTreeNode<T>* FindMax()const;//找最大值

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


#include "stdafx.h"
#include "BinSTree.h"
#include <iostream>
#include <stack>
using namespace std;


/**///////////////////////////////////////////////////////////////////////
// Construction/Destruction

/**///////////////////////////////////////////////////////////////////////
template<typename T>
CBinSTree<T>::CBinSTree()


{
this->root = NULL;
this->size = 0;
}
template<typename T>
CBinSTree<T>::CBinSTree(const CBinSTree<T>& tree)


{
root = this->CopyTree(tree.root);
this->size = tree.size;
}
template<typename T>
CBinSTree<T>::~CBinSTree()


{
this->ClearTree();
}
template<typename T>
CBinSTree<T>& CBinSTree<T>::operator = (const CBinSTree<T>& rhs)


{
if(this==&rhs)
return *this;
this->ClearTree();
root = this->CopyTree(rhs.root);
size = rhs.size;
return *this;
}
template<typename T>
CTreeNode<T>* CBinSTree<T>::GetTreeNode(const T& item,CTreeNode<T>* lptr,CTreeNode<T>* rptr)


{
CTreeNode<T>* p;
p = new CTreeNode<T>(item,lptr,rptr);
if(p==NULL)

{
cerr<<"分配内存失败!"<<endl;
exit(1);
}
return p;
}
template<typename T>
CTreeNode<T>* CBinSTree<T>::FindMin()const


{
CTreeNode<T> *t = root;
while(t->left!=NULL)

{
t = t->left;
}
return t;
}
template<typename T>
CTreeNode<T>* CBinSTree<T>::FindMax()const


{
CTreeNode<T> *t = root;
while(t->right!=NULL)

{
t = t->right;
}
return t;
}
template<typename T>
bool CBinSTree<T>::Contains(const T& item)


{
CTreeNode<T> *p;
return (this->FindNode(item,p)!=NULL);
}
template<typename T>
CTreeNode<T>* CBinSTree<T>::CopyTree(CTreeNode<T>* t)


{
CTreeNode<T> *newnode,*newlptr,*newrptr;
if(t==NULL)
return NULL;
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);
return newnode;
}
template<typename T>
void CBinSTree<T>::FreeTreeNode(CTreeNode<T>* p)


{
delete p;
p = NULL;
}
template<typename T>
void CBinSTree<T>::DeleteTree(CTreeNode<T>* t)


{
if(t!=NULL)

{
DeleteTree(t->Left());
DeleteTree(t->Right());
FreeTreeNode(t);
}
}
template<typename T>
void CBinSTree<T>::ClearTree()


{
DeleteTree(root);
root = NULL;
}
template<typename T>
CTreeNode<T>* CBinSTree<T>::FindNode(const T& item,CTreeNode<T>* &parent)const


{
CTreeNode<T> *t = root;
parent = NULL;
while(t!=NULL)

{
if(item==t->data)
break;
else

{
parent = t;
if(item<t->data)
t = t->Left();
else
t = t->Right();
}
}
return t;
}
template<typename T>
void CBinSTree<T>::Insert(const T& item)


{
CTreeNode<T>* t = root,*parent = NULL,*newnode;
while(t!=NULL)

{
parent = t;
if(item<t->data)
t = t->Left();
else
t = t->Right();
}
newnode = this->GetTreeNode(item);
if(parent==NULL)
root = newnode;
else if(item<parent->data)
parent->left = newnode;
else
parent->right = newnode;
size++;
}
template<typename T>
void CBinSTree<T>::Delete(const T& item)


{
CTreeNode<T> *pDNode,*pRNode,*pParNode;
if((pDNode = this->FindNode(item,pParNode))==NULL)
return;
if(pDNode->left==NULL)
pRNode = pDNode->right;
else if(pDNode->right==NULL)
pRNode = pDNode->left;
else

{
CTreeNode<T> *pParOfRNode = pDNode;
pRNode = pDNode->left;
while(pRNode->right!=NULL)

{
pParOfRNode = pRNode;
pRNode = pRNode->right;
}
if(pParOfRNode==pDNode)

{
pRNode->right = pDNode->right;
}
else

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

}
template<typename T>
void CBinSTree<T>::PrintTree()


{
stack<CTreeNode<T>* > s;
CTreeNode<T>* p = root;
while (p!=NULL || !s.empty())

{
while (p!=NULL) //遍历左子树

{
cout<<p->data<<endl;
s.push(p);
p=p->Left();
}//endwhile
if (!s.empty())

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

// test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "BinSTree.cpp"
#include <iostream>
using namespace std;

CBinSTree<int>* MakeSampleTree()


{//示例BST树
CBinSTree<int> *tree1 = new CBinSTree<int>();
int a = 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);
return tree1;
}

int main(int argc, char* argv[])


{
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;
return 0;
}

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述