Size Blanced Tree

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


介绍

Size Blanced Tree 是平衡二叉树的一种。每个结点所在子树的结点个数不小于其兄弟的两个孩子所在子树的结点个数,并且在插入时才会触发平衡调整。它还可以用来求第k小元素

一、自平衡条件

对于每个结点 tt,同时满足

size[right[t]]≥ max(size[left[left[t]]],size[right[left[t]]])
size[right[t]]≥max(size[left[left[t]]],size[right[left[t]]])

size[left[t]] ≥max(size[left[right[t]]],size[right[right[t]]])
size[left[t]]≥max(size[left[right[t]]],size[right[right[t]]])

其中 size[t]size[t] 表示 tt 结点所在子树的结点个数。

形象一点来说,就是每个结点所在子树的结点个数不小于其兄弟的两个孩子所在子树的结点个数。

比如对于这棵排序二叉树

在这里插入图片描述
对于结点 39 来说,就不满足 SBTree 的自平衡条件。

二、旋转操作

左旋和右旋,通过一系列左旋和右旋操作,将不平衡的树调整为平衡树。

左旋操作的演示如下:
在这里插入图片描述
通过进行左旋操作,使得原先的根 4变成了其左孩子2的右孩子,而 2 原先的左孩子 3变成了 4 的左孩子。

对应的,右旋操作的演示如下:
在这里插入图片描述
通过右旋操作,使得原先的根 5变成了其左孩子 3 的右孩子,而 3 原先的右孩子变成了 5 的左孩子。

多旋

AVL 树中还有两种复合旋转操作(即“多旋”),由两次单旋操作组合而成

第一种是左旋加右旋:
在这里插入图片描述
第二种是右旋加左旋:
在这里插入图片描述

三、旋转的触发

在调整过程中,一共有 4 种会触发旋转的情况:

LL 型:size[left[left[t]]] > size[right[t]]size[left[left[t]]]>size[right[t]]:首先对子树 tt 执行右旋操作,旋转以后对 tt 的右子树进行调整,之后再对子树 tt 进行调整。

LR 型:size[right[left[t]]] > size[right[t]]
size[right[left[t]]]>size[right[t]]:首先对 tt 的左子树执行左旋操作,再对 tt 进行右旋操作。之后分别调整结点 tt 的左右子树,最终对结点 tt进行调整。

RR 型:size[right[right[t]]] > size[left[t]]
size[right[right[t]]]>size[left[t]]:首先对 tt 执行左旋操作,旋转以后对 tt 的左子树进行调整,之后再对 tt 进行调整。

RL 型:size[left[right[t]]] > size[left[t]]
size[left[right[t]]]>size[left[t]]:首先对结点 tt 的右子树执行右旋操作,再对 tt 进行左旋操作。之后分别调整 tt 的左右子树,最终对 tt 进行调整。

通过递归的进行调整,我们可以最终让不平衡的 SBTree 恢复平衡状态。可以证明,调整操作的均摊时间复杂度为 O(1)O(1)。

和 AVL 不太一样的是,SBTree 只有在插入时才可能触发调整,而 不需要在删除结点以后进行调整。

四、代码

#include <iostream>

using std::cin;
using std::cout;
using std::endl;

template<typename Type>
class SBTNode {
public:
    Type data;
    int size;
    SBTNode<Type> *lchild, *rchild, *father;
    SBTNode(Type init_data, int init_size = 0, SBTNode<Type> *init_father = NULL);
    ~SBTNode();

    void insert(Type value);
    SBTNode<Type>* search(Type value);
    SBTNode<Type>* predecessor();
    SBTNode<Type>* successor();
    void remove_node(SBTNode<Type> *delete_node);
    bool remove(Type value);
    void print();
};

template<typename Type>
class BinaryTree {
private:
    SBTNode<Type>* root;
public:
    BinaryTree();
    ~BinaryTree();
    void insert(Type value);
    bool find(Type value);
    bool remove(Type value);
    void print_();
};

SBTNode<int> ZERO(0);
SBTNode<int>* NIL = &ZERO;

template <typename Type>
SBTNode<Type>::SBTNode(Type init_data, int init_size, SBTNode<Type>* init_father) {
    data = init_data;
    size = init_size;
    lchild = NIL;
    rchild = NIL;
    father = init_father;
}

template <typename Type>
SBTNode<Type>::~SBTNode() {
    if (lchild != NIL) {
        delete lchild;
    }
    if (rchild != NIL) {
        delete rchild;
    }
}

//左旋
template <typename Type>
SBTNode<Type>* left_rotate(SBTNode<Type>* node) {
    SBTNode<Type>* temp = node->rchild;
    node->rchild = temp->lchild;
    temp->lchild->father = node;
    temp->lchild = node;
    temp->father = node->father;
    node->father = temp;
    temp->size = node->size;
    node->size = node->lchild->size + node->rchild->size + 1;
    return temp;
}

//右旋
template <typename Type>
SBTNode<Type>* right_rotate(SBTNode<Type>* node) {
    SBTNode<Type>* temp = node->lchild;
    node->lchild = temp->rchild;
    temp->rchild->father = node;
    temp->rchild = node;
    temp->father = node->father;
    node->father = temp;
    temp->size = node->size;
    node->size = node->lchild->size + node->rchild->size + 1;
    return temp;
}

//调整
template <typename Type>
SBTNode<Type>* maintain(SBTNode<Type>* node, bool flag) {
    //左子树更高的情况
    if (flag == false) {
        if (node->lchild->lchild->size > node->rchild->size) { //LL
        	node = right_rotate(node);
        } else if (node->lchild->rchild->size > node->rchild->size){ //LR
        	node->lchild = left_rotate(node->lchild);
            node = right_rotate(node);
        } else {
        	return node;
        }
    } 
    //右子树更高的情况
    else {
    	if (node->rchild->rchild->size > node->lchild->size) { //RR
        	node = left_rotate(node);
        }  else if (node->rchild->lchild->size > node->lchild->size) { //RL
        	node->rchild = right_rotate(node->rchild);
            node = left_rotate(node);
        } else {
        	return node;
        }
    }
    node->lchild = maintain(node->lchild,false);
    node->rchild = maintain(node->rchild,true);
    node = maintain(node,false);
    node = maintain(node,true);
    return node;
}

template <typename Type>
SBTNode<Type>* insert(SBTNode<Type>* node, Type value) {
    node->size++;
    if (value > node->data) {
        if (node->rchild == NIL) {
            node->rchild = new SBTNode<Type>(value, 1, node);
        } else {
            node->rchild = insert(node->rchild, value);
        }
    } else {
        if (node->lchild == NIL) {
            node->lchild = new SBTNode<Type>(value, 1, node);
        } else {
            node->lchild = insert(node->lchild, value);
        }
    }
    return maintain(node, value > node->data);
}

template <typename Type>
SBTNode<Type>* SBTNode<Type>::search(Type value) {
    if (data == value) {
        return this;
    } else if (value > data) {
        if (rchild == NIL) {
            return NIL;
        } else {
            return rchild->search(value);
        }
    } else {
        if (lchild == NIL) {
            return NIL;
        } else {
            return lchild->search(value);
        }
    }
}

//寻找节点的前驱(前驱:比此节点小的最大的节点)
template <typename Type>
SBTNode<Type>* SBTNode<Type>::predecessor() {
    SBTNode<Type>* temp = lchild;
    while (temp != NIL && temp->rchild != NIL) {
        temp = temp->rchild;
    }
    return temp;
}

//寻找节点的后继(后继:比此节点大的最小的节点)
template <typename Type>
SBTNode<Type>* SBTNode<Type>::successor() {
    SBTNode<Type>* temp = rchild;
    while (temp != NIL && temp->lchild != NIL) {
        temp = temp->lchild;
    }
    return temp;
}

template <typename Type>
void SBTNode<Type>::remove_node(SBTNode<Type>* delete_node) {
    SBTNode<Type>* temp = NIL;
    if (delete_node->lchild != NIL) {
        temp = delete_node->lchild;
        temp->father = delete_node->father;
        delete_node->lchild = NIL;
    }
    if (delete_node->rchild != NIL) {
        temp = delete_node->rchild;
        temp->father = delete_node->father;
        delete_node->rchild = NIL;
    }
    if (delete_node->father->lchild == delete_node) {
        delete_node->father->lchild = temp;
    } else {
        delete_node->father->rchild = temp;
    }
    temp = delete_node;
    while (temp != NULL) {
        temp->size--;
        temp = temp->father;
    }
    delete delete_node;
}

template <typename Type>
bool SBTNode<Type>::remove(Type value) {
    SBTNode<Type> * delete_node, * current_node;
    current_node = search(value);
    if (current_node == NIL) {
        return false;
    }
    if (current_node->lchild != NIL) {
        delete_node = current_node->predecessor();
    } else if (current_node->rchild != NIL) {
        delete_node = current_node->successor();
    } else {
        delete_node = current_node;
    }
    current_node->data = delete_node->data;
    remove_node(delete_node);
    return true;
}
// 可在以下添加 SBTNode 的遍历方法
template <typename Type>
void SBTNode<Type>::print(){
    if (lchild != NIL) {
        lchild->print();
    }
     cout << data << " ";
    if (rchild != NIL) {
        rchild->print();
    }
}

template <typename Type>
BinaryTree<Type>::BinaryTree() {
    root = NULL;
}

template <typename Type>
BinaryTree<Type>::~BinaryTree() {
    delete root;
}

template <typename Type>
void BinaryTree<Type>::insert(Type value) {
    if (root == NULL) {
        root = new SBTNode<Type>(value, 1);
    } else if (root->search(value) == NIL) {
        root = ::insert(root, value);
    }
}

template <typename Type>
bool BinaryTree<Type>::find(Type value) {
    if (root->search(value) == NIL) {
        return false;
    } else {
       return true;
    }
}

template <typename Type>
bool BinaryTree<Type>::remove(Type value) {
    return root->remove(value);
}
// 可在以下添加 BinaryTree 遍历方法
template <typename Type>
void BinaryTree<Type>::print_() {
    if (root == NULL) {
        return;
    } else {
        root->print();
    }
}

int main() {
    BinaryTree<int> binarytree;
    int n;
    cin >> n;
    while (n--) {
        int val;
        cin >> val;
        binarytree.insert(val);
    }
    cin >> n;
    while (n--) {
        int val;
        cin >> val;
       if (binarytree.remove(val)) {
           cout << "delete success!" << endl;
       } else {
           cout << "delete failed!" << endl;
       }
    }
    binarytree.print_();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值