这里实现了平衡二叉树的删除 插入 搜索 遍历
节点类
class Node{
public:
int data;
Node *r; //右节点
Node *l; //左节点
int h; //节点的深度
Node(int data){ //构造函数
h = -1;
this->data = data;
r = l = NULL;
}
~Node(){ //析构
delete r, l;
}
};
*Tree类
class Tree{
private:
int max(int a, int b); //返回较大值
int height(Node *p); //获取p节点的深度
void singleright(Node* &p); //单右旋
void singleleft(Node *&p); //单左旋
void doubleright(Node *&p); //双右旋
void doubleleft(Node *&p); //双左旋
void insert(Node *&p, int data); //插入函数
void preprint(Node *p){ //前序遍历,,中后序略
void removes(Node *p,int data); //删除函数
if (p){
cout <<p->data << endl;
preprint(p->l);
preprint(p->r);
}
}
public:
Node *root;
Tree(){
root = NULL;
}
void insertnode(int data){
insert(root,data);
}
void prePrint(){
preprint(root);
}
void remove(int data){
removes(root,data);
}
~Tree(){
delete root;
}
};
下面是具体的实现:
int Tree::max(int a, int b){ //返回较大值
return a > b ? a : b;
}
//
int Tree::height(Node *p){ //获取某个节点的深度
if (p)return p->h; //p不为空,则返回深度
return -1;
}
//右旋函数
void Tree::singleright(Node* &p){ //右旋转 .. p的left节点旋转到p的位置
Node *pl = p->l;
p->l = pl->r;
pl->r = p;
//修改深度
p->h = max(height(p->l), height(p->r)) + 1;
//旋转后需要更新节点的h值; (h==p节点的深度)p旋转到了右边,p的h (深度)应为其左右孩子节点深度中的最大值加1
pl->h = max(p->h, height(pl->l)) + 1;
//pl旋转到了原来p的位置,它的深度是其左孩子和右孩子(p)的深度达较大者+1
p = pl;
}
///左旋函数
void Tree::singleleft(Node *&p){ //左旋转 .. p的right节点旋转到p的位置
Node *pr = p->r;
p->r = pr->l;
pr->l = p;
p->h = max(height(p->l), height(p->r)) + 1;
//p旋转到了左边,p的深度(h)应为其左右孩子节点深度中的最大值加1
pr->h = max(p->h, height(pr->r)); //pr旋转到了原来p的位置,它的深度应该为它的左孩子(p)和有孩子的深度的较大者+1
p = pr;
}
void Tree::doubleright(Node *&p){ //双右旋
singleleft(p->l);
singleright(p);
}
void Tree::doubleleft(Node *&p){ //双左旋
singleright(p->r);
singleleft(p);
}
//插入函数
void Tree::insert(Node *&p, int data){
if (p == NULL){ //节点为空,则在p处插入新节点
Node *node = new Node(data);
p = node;
p->h = 0;
}
//待插入值大于p的键值,则插入p的右子树
else if (data>p->data){
insert(p->l, data);
if (2 == height(p->l) - height(p->r)){ //如果平衡被打破就进行调整
if (data>p->l->data){ //如果是左左树,右旋转p
singleright(p);
}
else doubleright(p); //如果是左右树 双右旋
}
}
//待插入值小于p的键值,则插入p的左子树
if (data < p->data){
insert(p->r, data);
if (2 == height(p->r) - height(p->l)){ //平衡被打破就进行调整
if (data<p->r->data){ //如果是右右树,左旋
singleleft(p);
}
else doubleleft(p); //如果是右左树,双左旋p
}
}
else return;
p->h = max(height(p->r), height(p->l)) + 1;
//为新插入节点的深度赋值,递归的更新其他节点的深度
}
//删除函数
void Tree::removes(Node *&p, int data){
if (!p)return;
if (data>p->data){ //如果待删除的值大于p的键值 在p的左子树中查找data
removes(p->l,data);
if (2==height(p->r)-height(p->l)){ //找到并且删除data后,修改树的平衡
if (p->r->l && height(p->r->l) > height(p->r->r))doubleleft(p); //左树减少了一个元素,判断是右左树还是右右树
else singleleft(p);
}
}
else if (data < p->data ){ //如果待删除的值小于p的键值,在p的右子树中搜索data
removes(p->r,data);
//删除后修改树的平衡 判断树是否平衡
if (2 == height(p->l) - height(p->r)){
//右树减少了一个元素,判断p为首的树是左右树还是左左树
if (p->l->r && height(p->l->r)>height(p->l->l))doubleright(p);
else singleright(p);
}
}
else {
//如果节点有左右孩子, 在左树中找出最小值取代p的键值,然后删除最小值
if (p->r && p->l){
Node *temp = p->l;
while (temp->r)temp = temp->r;
p->data = temp->data;
removes(p->l,temp->data); //删除最小值
if (2==height(p->r)-height(p->l)){//删除后判断树是否还是平衡的
//由于删除了左树中的值,p树转变成右右树,或者右左树
if (p->r->l && height(p->r->l) > height(p->r->r)) doubleleft(p); //双左旋
else singleleft(p);//单左旋
}
}
else { //只有一子个节点或者没有孩子节点的情况
Node * t = p;
if (!p->r)p = p->l;
else if (!p->l)p = p->r;
delete t;
t = NULL;
}
}
if (!p)return; //如果p节点已经被删除了就 return
p->h = max(height(p->l),height(p->r))+1; //p节点没有被删除(p一定是有左右孩子的节点)则修改p节点的深度
}
///主函数
int main(){
Tree *t=new Tree();
t->insertnode(5);
t->insertnode(60);
t->insertnode(2);
t->insertnode(9);
t->insertnode(12);
t->insertnode(4);
t->insertnode(52);
t->insertnode(5);
t->prePrint();
cout << t->root->h<< endl;
delete t;
system(“pause”);
return 0;
}
“`