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

#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;
}

复制代码



本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2008/07/21/1247762.html,如需转载请自行联系原作者

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/539738.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Oracle 创建 DBLink 的方法

原文出处&#xff1a;http://blog.csdn.net/davidhsing/article/details/6408770 ------------------- 1、如果需要创建全局 DBLink&#xff0c;则需要先确定用户有创建 dblink 的权限&#xff1a; [c-sharp] view plaincopy print?select * from user_sys_privs where privi…

eclipse init 配置

--设置最大的堆和最小堆大小.两者一样表示固定大小.这样可以防止老年代内存扩展造成额外的gc.当然也会多占一些内存.系统内存不足的慎用 -Xms512m -Xmx512m --加大年轻代内存.减少minor gc -Xmn164m --这个是永久代大小.默认是64M,增加到96M.固定大小,减少扩展造成的gc -XX:Per…

Oracle对表空间操作的sql

管理员给用户增加不限制表空间权限 grant unlimited tablespace to 用户; 查看表空间使用情况 SELECT a.tablespace_name "表空间名", total "表空间大小", free "表空间剩余大小", (total - free) "表空间使用大小", total / (…

IPKISS Tutorials------线路仿真

IPKISS------线路仿真 推荐阅读引言正文示例1------PDK中集成好的器件示例2------使用 i3.Circuit 框架示例3------i3.PCell 框架推荐阅读 Matplotlib ------ 纵坐标科学计数法含义 引言 我们知道,想要在 IPKISS 中进行仿真,首先需要对线路进行定义,但是我们知道,在 IPK…

Oracle Database 11g Express Edition使用限制,与其他版本的区别

Oracle Database 11g Express Edition是 Oracle 数据库的免费版本&#xff0c;支持标准版的大部分功能&#xff0c;11g Express Edition 提供 Windows 和 Linux 版本。 做为免费的 Oracle 数据库版本&#xff0c;Express Edition的限制是&#xff1a; 1&#xff09;最大数据库大…

c++ 复制构造函数_C++学习刷题8--复制构造函数和赋值运算符重载函数

一、前言本部分为C语言刷题系列中的第8节&#xff0c;主要讲解这几个知识点&#xff1a;复制构造函数和赋值运算符重载函数。欢迎大家提出意见、指出错误或提供更好的题目&#xff01;二、知识点讲解知识点1&#xff1a;复制构造函数1、当依据一个已存对象创建一个新对象时&…

ORACLE使用WITH AS和HINT MATERIALIZE优化SQL解决FILTER效率低下

原文&#xff1a;http://blog.csdn.net/liangweiwei130/article/details/37882503 ------------------------------------------------- 在做项目的过程中&#xff0c;一个页面使用类似如下的SQL查询数据&#xff0c;为了保密和使用方便&#xff0c;我把项目中有关的表名和字段…

面试题333

2019独角兽企业重金招聘Python工程师标准>>> 面试题333 博客分类&#xff1a; java 1、spring的缓存,mybatis缓存2、介绍下dubbo。A服务调用B服务&#xff0c;B服务又调用C服务,这种情况怎么办3、JVM监控工具有哪些&#xff0c;区别又是什么&#xff08;如能追上各个…

mysql vfp_用 VFP 连接 MYSQL 数据库

今天试了一下用 Visual FoxPro 连接 MySQL 数据库。首先在自己机子上架设 MySQL 数据库&#xff0c;就不多说了&#xff0c;我是直接用 XAMPP 架设的服务器。然后在 VFP 里输入命令&#xff1a;sqlhandle SQLSTRINGCONNECT("driver{MySQL ODBC 5.1 Driver};server127.0.0…

oracle中with的用法及用处

原文出处&#xff1a;http://blog.csdn.net/chenjinlin1/article/details/6572401 ---------------------------------------------------------------- WITH 用于一个语句中某些中间结果放在临时表空间的SQL语句 如 WITH channel_summary AS ( SELECT channels.channel_de…

xpath选择当前结点的子节点

2019独角兽企业重金招聘Python工程师标准>>> xpath选择当前结点的子节点 博客分类&#xff1a; 搜索引擎&#xff0c;爬虫 在通过selenium使用xpath选择节点的时候&#xff0c;可能会遇到这么一种情况&#xff1a;在指定的当前节点下搜索满足要求的节点。 node dri…

mysql中主从复制配置文件_MySQL主从复制 配置文件实例

1、主服务器配置文件# For advice on how to change settings please see# http://dev.mysql.com/doc/refman/5.6/en/server-configuration-defaults.html[mysqld]# Remove leading # and set to the amount of RAM for the most important data# cache in MySQL. Start at 70%…

SQL中,where 与 having 的性能比较

原文&#xff1a;http://blog.csdn.net/showshore/article/details/7263115 --------------------------------------------------------- 在做项目的过程中&#xff0c;使用sql语句时&#xff0c;很多时候会用到where或having。 看到国外一个论坛上有人提到两者性能比较的这个…

Spark 独立部署模式

2019独角兽企业重金招聘Python工程师标准>>> Spark 独立部署模式 博客分类&#xff1a; spark 除了在 Mesos 或 YARN 集群上运行之外, Spark 还提供一个简单的独立部署的模块。你通过手动开始master和workers 来启动一个独立的集群。你也可以利用我们提供的脚本 .…

mysql数据库的链接地址_常用数据库连接URL地址大全

1、Oracle8/8i/9i数据库(thin模式) Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); String url="jdbc:oracle:thin:@localhost:1521:orcl"; //orcl为数据库的SID String user="test"; String password="test"; Con…

数据库中where与having区别~~~

1、where和having的执行级别不同 在查询过程中聚合语句(sum,min,max,avg,count)要比having子句优先执行.而where子句在查询过程中执行优先级别优先于聚合语句(sum,min,max,avg,count)。 having就是来弥补where在分组数据判断时的不足。因为where执行优先级别要快于聚合语句。…

spring boot 1.5.4 定时任务和异步调用(十)

1 Spring Boot定时任务和异步调用 我们在编写Spring Boot应用中经常会遇到这样的场景&#xff0c;比如&#xff1a;我需要定时地发送一些短信、邮件之类的操作&#xff0c;也可能会定时地检查和监控一些标志、参数等。 spring boot定时任务spring-boot-jsp项目源码&#…

ORA-04063: view DAILY.TMP_TBX_100_0_S4 有错误

执行&#xff1a; CREATE TABLE TMP_TBX_100_0_S3 AS SELECT t.* FROM (select t1.*,NULL AS sdate, NULL AS report_id from TMP_TBX_100_0_S4_1 t1 union all select t2.* from TMP_TBX_100_0_S4_2 t2) t 报错&#xff1a; ORA-00955: name is already used by an exis…

MySQL左连接还有过滤条件_MySQL左连接问题,右表做筛选,左表列依然在?

问 题原料两张表&#xff0c;一张user表&#xff0c;一张user_log表(这个例子举的不好)CREATE TABLE user (id int(11) NOT NULL AUTO_INCREMENT,name varchar(20) DEFAULT NULL,PRIMARY KEY (id)) ENGINEInnoDB DEFAULT CHARSETutf8;CREATE TABLE user_log (id int(10) NOT NU…

2017工作总结

静儿总结自己的职业生涯分为三个阶段。第一个阶段为期十年&#xff0c;是纯技术阶段&#xff0c;是人生的积累期。第二个阶段是管理阶段&#xff0c;是综合能力整合期。第三个阶段是突破阶段&#xff0c;打造自己独特的核心竞争力。 第一阶段 刚毕业的同学可能会觉得技术高大上…