# SBTree的左旋右旋以及各种调整操作的基本实现(包含查找第k大的数值)

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

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

LL 型：右旋 tt。
LR 型：左旋 tt 的左子树，再右旋 tt。

RR 型：左旋 tt。
RL 型：右旋 tt 的右子树，再左旋 tt。

#include <iostream>

using namespace std;

class SBTNode {
public:
int data, size, value;
SBTNode * lchild, * rchild, * father;
SBTNode(int init_data, int init_size = 0, SBTNode * init_father = NULL);
~SBTNode();

void insert(int value);
SBTNode * search(int value);
SBTNode * predecessor();
SBTNode * successor();
void remove_node(SBTNode * delete_node);
bool remove(int value);
int select(int k);
};

class BinaryTree {
private:
SBTNode * root;
public:
BinaryTree();
~BinaryTree();
void insert(int value);
bool find(int value);
bool remove(int value);
int select(int k);
};

SBTNode ZERO(0);
SBTNode * ZPTR = &ZERO;

SBTNode::SBTNode(int init_data, int init_size, SBTNode * init_father) {
data = init_data;
size = init_size;
lchild = ZPTR;
rchild = ZPTR;
father = init_father;
}

SBTNode::~SBTNode() {
if (lchild != ZPTR) {
delete lchild;
}
if (rchild != ZPTR) {
delete rchild;
}
}

SBTNode * left_rotate(SBTNode * node) {
SBTNode * 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;
}

SBTNode * right_rotate(SBTNode * node) {
SBTNode * 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;
}

SBTNode * maintain(SBTNode * node, bool flag) {
if (flag == false) {
if (node->lchild->lchild->size > node->rchild->size) {
node = right_rotate(node);
} else if (node->lchild->rchild->size > node->rchild->size) {
node->lchild = left_rotate(node->lchild);
node = right_rotate(node);
} else {
return node;
}
} else {
if (node->rchild->rchild->size > node->lchild->size) {
node = left_rotate(node);
} else if (node->rchild->lchild->size > node->lchild->size) {
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;
}

SBTNode * insert(SBTNode * node, int value) {
if (value == node->data) {
return node;
} else {
node->size++;
if (value > node->data) {
if (node->rchild == ZPTR) {
node->rchild = new SBTNode(value, 1, node);
} else {
node->rchild = insert(node->rchild, value);
}
} else {
if (node->lchild == ZPTR) {
node->lchild = new SBTNode(value, 1, node);
} else {
node->lchild = insert(node->lchild, value);
}
}
}
return maintain(node, value > node->data);
}

SBTNode * SBTNode::search(int value) {
if (data == value) {
return this;
} else if (value > data) {
if (rchild == ZPTR) {
return ZPTR;
} else {
return rchild->search(value);
}
} else {
if (lchild == ZPTR) {
return ZPTR;
} else {
return lchild->search(value);
}
}
}

SBTNode * SBTNode::predecessor() {
SBTNode * temp = lchild;
while (temp != ZPTR && temp->rchild != ZPTR) {
temp = temp->rchild;
}
return temp;
}

SBTNode * SBTNode::successor() {
SBTNode * temp = rchild;
while (temp != ZPTR && temp->lchild != ZPTR) {
temp = temp->lchild;
}
return temp;
}

void SBTNode::remove_node(SBTNode * delete_node) {
SBTNode * temp = ZPTR;
if (delete_node->lchild != ZPTR) {
temp = delete_node->lchild;
temp->father = delete_node->father;
delete_node->lchild = ZPTR;
}

if (delete_node->rchild != ZPTR) {
temp = delete_node->rchild;
temp->father = delete_node->father;
delete_node->rchild = ZPTR;
}
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;
}

bool SBTNode::remove(int value) {
SBTNode * delete_node, * current_node;
current_node = search(value);
if (current_node == ZPTR) {
return false;
}
size--;
if (current_node->lchild != ZPTR) {
delete_node = current_node->predecessor();
} else if (current_node->rchild != ZPTR) {
delete_node = current_node->successor();
} else {
delete_node = current_node;
}
current_node->data = delete_node->data;
remove_node(delete_node);
return true;
}

int SBTNode::select(int k) {
int rank=lchild->size+1;
if(rank==k){
return data;
}
else if(k<rank){
return lchild->select(k);
}else{
return rchild->select(k-rank);
}
}

BinaryTree::BinaryTree() {
root = NULL;
}

BinaryTree::~BinaryTree() {
if (root != NULL) {
delete root;
}
}

void BinaryTree::insert(int value) {
if (root == NULL) {
root = new SBTNode(value, 1);
} else {
root = ::insert(root, value);
}
}

bool BinaryTree::find(int value) {
if (root->search(value) == NULL) {
return false;
} else {
return true;
}
}

bool BinaryTree::remove(int value) {
return root->remove(value);
}

int BinaryTree::select(int k) {
return root->select(k);
}

int main() {
BinaryTree binarytree;
int arr[10] = { 8, 9, 10, 3, 2, 1, 6, 4, 7, 5 };
for (int i = 0; i < 10; i++) {
binarytree.insert(arr[i]);
}
int k;
cin >> k;
cout << binarytree.select(k) << endl;
return 0;
}

• 本文已收录于以下专栏：

## avl树左旋右旋的理解

• u012361418
• 2015年06月17日 16:32
• 1946

## 二叉树的左旋和右旋

• tuhuolong
• 2011年10月05日 10:31
• 7778

## AVL树的旋转操作 图解 最详细

AVL树的旋转操作 图解 最详细 各大教课书上讲的都是左旋与右旋，其实这样很容易理解错误，我们换一种叫法。 我们称呼左旋为：逆进针旋转。 我们称呼右旋为：顺进针旋转。...
• collonn
• 2014年02月28日 11:47
• 40897

## 树的左旋与右旋

• chuchus
• 2014年10月09日 16:47
• 2039

## 平衡二叉树(AVL树)一图一步骤代码实现左旋右旋，左右平衡操作

/** * 类说明:AVL树 */ public class AVLTreeE extends ComparableE>> { NodeE> root; int size = ...
• qq_35295155
• 2017年11月22日 10:36
• 97

## 左旋字符串

• qq_39412582
• 2018年02月01日 11:39
• 41

## 红黑树的理解与学习&左旋与右旋操作

http://zh.wikipedia.org/wiki/%E7%BA%A2%E9%BB%91%E6%A0%91#.E7.94.A8.E9.80.94.E5.92.8C.E5.A5.BD.E5.A4....
• fuqiaoyimeng
• 2014年10月08日 15:36
• 978

## 二叉树左旋右旋

• bright_light_in_dark
• 2016年05月14日 19:31
• 1110

## AVL树的左旋右旋理解

AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为一，所以它也被称为高度平衡树。查找、插入和删除在平均和最坏情况下都是O（log n）。增加和删除可能需要通过一次或多...
• gongweijiao
• 2012年11月22日 19:38
• 3690

## BFPRT算法查找第k大元素

• wuxiushu
• 2016年08月01日 11:38
• 1020

举报原因： 您举报文章：SBTree的左旋右旋以及各种调整操作的基本实现(包含查找第k大的数值) 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)