C++二叉查找树:Binary Search tree
二叉查找树默认左子树的值都比根节点小,右子树都比根节点大,这个定义排除了树中存在值相同节点的可能性。这便是二叉查找树称为一个用关键值KEY快速查找的工具。
二叉树类:
class bst
{
struct Node
{
T data;
Node* L;
Node* R;
Node(const T& d):data(d),L(),R(){}
Node(const T& d,Node* L,Node* R):data(d),L(L),R(R){}
};
typedef Node* tree;
Node* rp;//指向根节点指针
int n;//记录节点个数
};
1.插入一个节点; void(tree& t,Node* p)//在一棵树树中插入一个节点
if(空树),作为根结点插入
if(大于根节点值),插入右子树
else 插入左子树
void myinsert(tree& t,Node* p)//在一棵树中插入一个节点
{
if(t == NULL)
t = p;
else if(p->data < t->data)
myinsert(t->L,p);
else
myinsert(t->R,p);
}
if(t==NULL) return t;
if(t->data==d) return t;
if(d < t->data) return 左子树中查找
else return右子树查找
tree& myfind(tree& t,const T& d)//返回以d为根节点的子树的根指针
{
if(t==NULL)
return t;
else if(d==t->data) return t;//没找到
else if(d<t->data) return myfind(t->L,d);//return 一定要带上
else return myfind(t->R,d);
}
void tr
特殊:
叶子节点----->直接delete
单子节点---->让父节点指向子节点,delete
双子节点---->左右子树合并
1.找到这个节点,即返回指向这个节点的指针pn
2.备份一份指针p=pn
3.左右子树合并(左子树插入到右子树 或者 右子树插入到左子树)
4.Delete 节点
5.节点数-1
bool dele(const T& d){//返回那个节点的根指针,另存一份
//左右子树合并,根指针指向右子树,释放节点
tree& t = myfind(d);
if(t == NULL) return false;
Node* p = t;
if(t->L!=NULL) myinsert(t->R,t->L);
t = t->R;
delete p;
--n;
return true;
}
1,删掉这个节点
2.插入一个节点
void update(const T& olddata,const T& newdata)
{
dele(olddata);
myinsert(newdata);
}
5.遍历二叉树 //中根遍历
遍历左子树
遍历根节点
遍历右子树
void travel(const tree& t)const
{
if(t != NULL)
{
travel(t->L);
cout << t->data <<' ';
travel(t->R);
}
}
6.清空一棵树
先清左子树
在清右子树
delete根节点
void clean(tree& t)//清空一棵树
{
if(t!=NULL)
{
clean(t->L);
clean(t->R);
delete t;t=NULL;
}
}
7.求树的深度
int high(tree& t)const//求一棵树的高度
{
if(t == NULL) return 0;
int lh=high(t->L);
int rh=high(t->R);
return 1+std::max(lh,rh);
}
1.如果是空树,over
2.创建队列,根节点进队
3 只要队列不为空,
3.1 出队一个元素
3.2访问其中数据
3.3左右非空子树入队
void prin(tree& t)
{
if(!t) return;
deque<tree> di;
di.push_back(t);
while(!di.empty())
{
tree& t=di.front();
cout << t->data << ' ';
if(t->L)
di.push_back(t->L);
if(t->R)
di.push_back(t->R);
}
}
加换行符,每层遍历加一个换行
1.如果是空树,over
2.创建队列,根节点进队,NULL进队
3 只要队列size>1,
3.1 出队一个元素
3.2如果是NULL,换行,NULL进队尾。continue
3.2访问其中数据
3.3左右非空子树入队
void print(tree& t )
{
if(t==NULL)
return;
deque<tree> di;//创建队列
di.push_back(t);//根节点入队
di.push_back(NULL);
while(di.size()!=1)//只要非空
{
tree& t=di.front();//取出一个元素
if(t==NULL)
{
cout << endl;
di.pop_front();
di.push_back(NULL);
continue;
}
cout << t->data << ' ';//访问数据
di.pop_front();
if(t->L)
di.push_back(t->L);//左右子树非空节点入队
if(t->R)
di.push_back(t->R);
}
}