初学者实现了二叉查找树的实现:
实现的功能包括:
- 构造函数
- 西沟函数
- 判空函数
- 递归搜素
- 非递归搜索
- 删除元素
- 前序遍历
- 中序遍历
- 后续遍历
- 层遍历 ---没有实现
头文件:
BST.h
#include<iostream>
using namespace std;
#ifndef BST
#define BST
template <class T>
class bst{
private:
struct Node{
T data;
Node *lc;
Node *rc;
Node():lc(0),rc(0){};
Node(T item):data(item),lc(0),rc(0){};
};
Node *myroot;
//赋值函数
void BST_copy(Node**,Node*);
void inorderAux(ostream&,Node*) const;
void PostorderAux(ostream&,Node*) const;
void preorderAux(ostream&,Node*) const;
bool searchaux(Node*,T ) const;
void insertaux(Node**,T);
public:
bst();//初始化为一颗空树
bst(const bst<T> &);
~bst();
bst<T>& operator=(const bst<T>&);
bool empty() const;
bool search1(const T)const;//采用递归
bool search2(const T)const;//采用非递归
void insert1(T);//采用递归
void insert2(T);//采用非递归
bool remove(T);//分删除叶子节点和单个孩子节点 以及两个孩子的节点
void PreOrder(ostream &)const;
void InOrder(ostream &) const;
void PostOrder(ostream &)const;
void LayerOrder(ostream &)const;
void graph();
};
#endif // BST
BST.cpp
#include<iostream>
#include"BST.h"
using namespace std;
//实现BST的成员函数
//初始化
template<class T>
bst<T>::bst():myroot(0){};
//赋值函数--已经实现
template<class T>
bst<T>::bst(const bst<T>& BST_original){
if(!BST_original.empty()){
bst<T>::Node* original=BST_original.myroot;
BST_copy(&(myroot),original);
}
}
template<class T>
void bst<T>::BST_copy(bst<T>::Node **target,bst<T>::Node* orginal){
if(orginal!=0){
*target=new bst<T>::Node(orginal->data);
if(orginal->lc!=0)
BST_copy(&((*target)->lc),orginal->lc);
if(orginal->rc!=0)
BST_copy(&((*target)->rc),orginal->rc);
}
}
//析构函数 -----没有实现
template<class T>
bst<T>::~ bst(){
}
//赋值操作符 --已经实现
template<class T>
bst<T>& bst<T>::operator=(const bst<T>& BST_original){
if(!BST_original.empty()){
bst<T>::Node* original=BST_original.myroot;
BST_copy(&(myroot),original);
}
return *this;
}
//判空操作--已经实现
template<class T>
bool bst<T>::empty() const{
return 0==myroot;
}
//递归搜索---已经实现
template<class T>
bool bst<T>::search1(const T item) const{
if(empty())
return false;
else
return searchaux(myroot,item);
}
template<class T>
bool bst<T>::searchaux(bst<T>::Node* subroot,const T item) const{
if(subroot==0)
return false;//已经是空树了 没有找到
if(item>subroot->data)
return searchaux(subroot->rc,item);
else if(item<subroot->data)
return searchaux(subroot->lc,item);
else
return true;
}
//非递归搜索-已经实现
template<class T>
bool bst<T>::search2(const T item)const{
bool found=false;
bst<T>::Node* ptmp=myroot;
while(ptmp&&!found){
if(item<ptmp->data)
ptmp=ptmp->lc;
else if(item>ptmp->data)
ptmp=ptmp->rc;
else
found=true;
}
return found;
}
//采用递归
template<class T>
void bst<T>::insert1(T item){
insertaux(&myroot,item);
}
//递归插入实现函数
template<class T>
void bst<T>::insertaux(bst<T>::Node **subroot, T item){
if(*subroot==0){
*subroot=new bst<T>::Node(item);
}
else if(item>(*subroot)->data)
insertaux(&((*subroot)->rc),item);
else if(item<(*subroot)->data)
insertaux(&((*subroot)->lc),item);
else
cout<<"The data has already in the BST~~~"<<endl;
}
//非递归插入---已经实现
template<class T>
void bst<T>::insert2(T item){
if(empty()){
cout<<"empty bst,creat it~~`"<<endl;
myroot=new bst<T>::Node(item);
}else{
bst<T>::Node *parent=0;
bst<T>::Node *ptemp=myroot;
bool found=false;
while(!found&&ptemp!=0){
parent=ptemp;
if(item<ptemp->data)
ptemp=ptemp->lc;
else if(item>ptemp->data)
ptemp=ptemp->rc;
else
found=true;
}
if(!found){
if(item>parent->data)
parent->rc=new bst<T>::Node(item);
else if(item<parent->data)
parent->lc=new bst<T>::Node(item);
}
else{
cout<<"The data has existed:->"<<item<<endl;
}
}
}
//remove
template<class T>
bool bst<T>::remove(T item){
//首先需要确定这个值在不在树里面,然后确定这个节点有几个还在
//有一个孩子的情况下或者没有孩子的情况下,直接处理,
//要是有两个孩子需要处理后续连接的问题
if(empty())
{
cout<<"Empty BST, can not delete the item:->"<<item<<endl;
}
else
{
bst<T>::Node *ptemp=myroot;
bst<T>::Node *parent=0;
bool found=false;
while(ptemp&&!found){
if(item<ptemp->data){
parent=ptemp;
ptemp=ptemp->lc;}
else if (item>ptemp->data)
{parent=ptemp;
ptemp=ptemp->rc;}
else
found=!found;
}
if(!found){
cout<<"There is no item:->"<<item<<"in this BST"<<endl;
return 0;
}
else{
bst<T>::Node *pt;
if(ptemp->lc==0&&ptemp->rc==0)//叶子节点
{
if(ptemp==parent->lc) parent->lc=0;
else parent->rc=0;
delete ptemp;
}
else if(ptemp->lc==0 && ptemp->rc!=0){
if(ptemp==parent->lc) parent->lc=ptemp->rc;
else parent->rc=ptemp->rc;
delete ptemp;}
else if(ptemp->rc==0 && ptemp->lc!=0){
if(ptemp==parent->lc) parent->lc=ptemp->lc;
else parent->rc=ptemp->lc;
delete ptemp;}
else{
//含有左右孩子
bst<T>::Node *pt2=ptemp;
bst<T>::Node *parent2=ptemp;
while(pt2->lc!=0){
parent2=pt2;
pt2=pt2->lc;
}
ptemp->data=pt2->data;
if(pt2->rc!=0){
parent2->lc= pt2->rc;
}else{
parent2->lc=0;
}
delete pt2;
}
}
}
}
//先序遍历---已经实现
template<class T>
void bst<T>::PreOrder(ostream &out) const{
cout<<"先序遍历:"<<endl;
preorderAux(out,myroot);
}
template<class T>
void bst<T>::preorderAux(ostream& out,bst<T>::Node* p) const{
if(p!=0){
cout<< p->data<<" ";
preorderAux(out,p->lc);
preorderAux(out,p->rc);
}
}
//中序序遍历--已经实现
template<class T>
void bst<T>::InOrder(ostream &out) const
{
cout<<"中序遍历:"<<endl;
inorderAux(out,myroot);
}
template<class T>
void bst<T>::inorderAux(ostream& out,bst<T>::Node* p) const{
if(p!=0){
inorderAux(out,p->lc);
cout<< p->data<<" ";
inorderAux(out,p->rc);
}
}
//后序遍历---已经实现
template<class T>
void bst<T>::PostOrder(ostream &out) const
{
cout<<"后序遍历:"<<endl;
PostorderAux(out,myroot);
}
template<class T>
void bst<T>::PostorderAux(ostream& out,bst<T>::Node* p) const{
if(p!=0){
PostorderAux(out,p->lc);
PostorderAux(out,p->rc);
cout<< p->data<<" ";
}
}
template<class T>
void bst<T>::LayerOrder(ostream &)const{
}
template<class T>
void bst<T>::graph(){
}
测试文件:
#include <iostream>
#include<fstream>
#include"BST.cpp"
using namespace std;
int main()
{
ifstream file_stream("BST_in.txt");
ofstream ft_stream("BST_out.txt");
int i;
bst<int> intBST;
while(file_stream>>i)
intBST.insert2(i);
// intBST.InOrder(cout);
//intBST.PostOrder(cout);
intBST.PreOrder(cout);
bst<int> intBST2(intBST);
//intBST2.InOrder(cout);
//intBST2.PostOrder(cout);
// intBST2.PreOrder(cout);
bst<int> intBST3;
intBST3=intBST;
//intBST3.InOrder(cout);
// bool t1=intBST3.search1(12);
//cout<<t1<<endl;
//bool t2=intBST3.search2(100);
// cout<<t2<<endl;
//intBST.insert1(1000);
//intBST.InOrder(cout);
intBST.remove(6);
intBST.PreOrder(cout);
cin>>i;
return 0;
}
1.在编程中发现如下问题:
1.将一个空的指针传递给函数的时候,将不能实现改变指针所指的值 ,这个表现在insert函数上
2.头文件名为BST 然后将类的名字命名为BST的时候将出现错误,认为没有提供类的名称。
3.将输入写成文件流的形式将更好维护
4const函数只能调用返回const值的成员函数
5,文件流最好不能设置成const类型
有两个成员函数没有实现:层遍历() 和图形化输出函数 以及析构函数----折个 以后再加吧