平衡二叉树的实现,python,
# -*- coding: UTF-8 -*-
#!/usr/bin/python
#from __future__ import print_function #python2.7不要注释这句
class AVLnode:
def __init__(self, d, h=0, l=None, r=None ):
self.data=d
self.lchild, self.rchild=l, r #左右孩子
self.tree_high=h #以该结点为根的树的高度,单结点树高度为1
#递归地把结点值和高度写入数组对应的位置
def __setL(p, L, i):
L[i]=(p.data, p.tree_high)
if(p.lchild is not None):
__setL(p.lchild, L, i*2)
if(p.rchild is not None):
__setL(p.rchild, L, i*2+1)
#按满编二叉树的形状打印 以p为根的树,空的叶子结点用(-1,-1)表示
def print1(p):
L=[(-1,-1)]*(2**p.tree_high)#初始化数组为全空结点,数组长度不会超过高为tree_high满编二叉树的所有结点个数
__setL(p, L, 1)
l=1
for i in range(1, 2**p.tree_high):#树的跟结点从对应数组从1开始
if(i==2**(l-1)):
l+=1
print('\n',end='')
print("(%d,%d) " % (L[i][0],L[i][1]),end='')
#中序遍历二叉搜索树,即按从小到大打印排序
def inOrder(p):
if(p is None):
return
inOrder(p.lchild)
print("(%d,%d)" % (p.data, p.tree_high),end='')
inOrder(p.rchild)
def height(p):
if p is None:
return 0
else:
return p.tree_high
#单次右旋
#传入树的根结点p,
#返回旋转后的树的根结点
def R_Rotate( p):
lc = p.lchild
p.lchild = lc.rchild
lc.rchild = p
lc.tree_high = max(height(lc.lchild), height(p))+1
p.tree_high = max(height(p.lchild), height(p.rchild))+1
return lc
#单次左旋
#传入树的根结点p,
#返回旋转后的树的根结点
def L_Rotate( p):
rc = p.rchild
p.rchild = rc.lchild
rc.lchild = p
rc.tree_high = max(height(rc.rchild), height(p))+1
p.tree_high = max(height(p.lchild), height(p.rchild))+1
return rc
#先左旋再右旋
def LR_Rotate(p):
p.lchild = L_Rotate(p.lchild)
return R_Rotate(p)
#先右旋再左旋
def RL_Rotate(p):
p.rchild = R_Rotate(p.rchild)
return L_Rotate(p)
#往根结点为p的AVL树中插入元素e
def InsertAVL(p, e):
if p is None:
p = AVLnode(e, 1, None, None)
elif (e < p.data):#元素e要往左孩子子树中找位置插入
p.lchild = InsertAVL(p.lchild, e)
if(height(p.lchild) - height(p.rchild) == 2):#元素e插入成功后如果左子树比右子树高2
if(e < p.lchild.data):
p=R_Rotate(p)
else:
p=LR_Rotate(p)
elif(e > p.data):
p.rchild = InsertAVL(p.rchild, e)
if(height(p.rchild) - height(p.lchild) == 2):
if(e>p.rchild.data):
p=L_Rotate(p)
else:
p=RL_Rotate(p)
p.tree_high = max(height(p.lchild),height(p.rchild))+1
return p
def main():
#a=[37, 54, 20, 40, 56, 41, 40, 42]
#a=[20,37,40,41,42,54,56]
a=[20,37, 60, 70, 80, 90]
t=AVLnode(45, 1, None, None)
#print("tree high=%d" % t.tree_high)
for x in a:
t=InsertAVL(t, x)
#print("tree high=%d" % t.tree_high)
print1(t)
print("\n---")
inOrder(t)#输出从小到大排序结果
main()
打印结果:(元素值,该结点高度)
(60,3)
(37,2) (80,2)
(20,1) (45,1) (70,1) (90,1)
---
(20,1)(37,2)(45,1)(60,3)(70,1)(80,2)(90,1)
C++, 参考https://www.cnblogs.com/sench/p/7786718.html
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
class AVLNode
{
public:
int key; //结点的值
int height; //结点的高度,根结点为0
AVLNode* left; //左孩子
AVLNode* right; //右孩子
/*构造函数*/
AVLNode(int k, AVLNode* left, AVLNode* right) :key(k), height(0), left(left), right(right) {}
};
class AVLTree
{
private:
AVLNode* root; //根节点
public:
/*构造函数*/
AVLTree() :root(NULL) {};
/*返回根节点*/
AVLNode* getRoot() { return root; }
/*先序遍历*/
void preOrder(AVLNode* root);
/*中序遍历*/
void inOrder(AVLNode* root);
/*后序遍历*/
void postOrder(AVLNode* root);
/*在AVL树root中查找值为key的结点并返回该结点*/
AVLNode* search(AVLNode* root, int key);
/*在AVL树中查找最小值结点并返回*/
AVLNode* minimus(AVLNode* node);
/*在AVL树中查找最大值结点并返回*/
AVLNode* maximus(AVLNode* node);
/*返回结点的高度*/
int height(AVLNode* node);
/*左左旋转*/
AVLNode* leftLeftRotate(AVLNode* root);
/*右右旋转*/
AVLNode* rightRightRotate(AVLNode* root);
/*左右旋转*/
AVLNode* leftRightRotate(AVLNode* root);
/*右左旋转*/
AVLNode* rightLeftRotate(AVLNode* root);
/*插入结点*/
AVLNode* insert(AVLNode* root, int key);
/*删除结点node*/
AVLNode* deleteNode(AVLNode* root, AVLNode* node);
/*销毁AVL树*/
void destroy(AVLNode* root);
};
/*先序遍历*/
void AVLTree::preOrder(AVLNode* root)
{
if (root == NULL)
return;
cout <<"(" <<root->key<<","<<height(root) << ") ";
preOrder(root->left);
preOrder(root->right);
}
/*中序遍历*/
void AVLTree::inOrder(AVLNode* root)
{
if (root == NULL)
return;
inOrder(root->left);
cout <<"(" <<root->key<<","<<height(root) << ") ";
inOrder(root->right);
}
/*后序遍历*/
void AVLTree::postOrder(AVLNode* root)
{
if (root == NULL)
return;
postOrder(root->left);
postOrder(root->right);
cout << root->key << " ";
}
/*在AVL树root中查找值为key的结点并返回该结点*/
AVLNode* AVLTree::search(AVLNode* root, int key)
{
if (root == NULL || root->key == key)
return root;
if (key < root->key)
search(root->left, key);
else search(root->right, key);
}
/*在AVL树中查找最小值结点并返回*/
AVLNode* AVLTree::minimus(AVLNode* node)
{
if (node->left == NULL)
return node;
return minimus(node->left);
}
/*在AVL树中查找最大值结点并返回*/
AVLNode* AVLTree::maximus(AVLNode* node)
{
if (node->right == NULL)
return node;
return maximus(node);
}
/*返回结点的高度*/
int AVLTree::height(AVLNode* node)
{
if (node != NULL)
return node->height;
return 0;
}
/*LL旋转,
* 参数:
* root : 失衡AVL树根节点
* 返回值 : 调整后的AVL树根节点
*/
AVLNode* AVLTree::leftLeftRotate(AVLNode* root)
{
AVLNode* lchild = root->left;
root->left = lchild->right;
lchild->right = root;
lchild->height = max(height(lchild->left), height(root)) + 1;
root->height = max(height(root->left), height(root->right)) + 1;
return lchild;
}
/*RR旋转
* 参数:
* root : 失衡AVL树根节点
* 返回值 : 调整后的AVL树根节点
*/
AVLNode* AVLTree::rightRightRotate(AVLNode* root)
{
AVLNode* rchild = root->right;
root->right = rchild->left;
rchild->left = root;
rchild->height = max(height(root), height(rchild->right)) + 1;
root->height = max(height(root->left), height(root->right)) + 1;
return rchild;
}
/*LR旋转
* 参数:
* root : 失衡AVL树根节点
* 返回值 : 调整后的AVL树根节点
*/
AVLNode* AVLTree::leftRightRotate(AVLNode* root)
{
root->left = rightRightRotate(root->left); //先对左子树右右旋转
return leftLeftRotate(root); //再对根结点左左旋转
}
/*RL旋转
* 参数:
* root : 失衡AVL树根节点
* 返回值 : 调整后的AVL树根节点
*/
AVLNode* AVLTree::rightLeftRotate(AVLNode* root)
{
root->right = leftLeftRotate(root->right);
return rightRightRotate(root);
}
/*
* 将结点插入到AVL树中,并返回根节点
*
* 参数说明:
* root 插入新结点前AVL树的根结点
* key 插入的结点的键值
* 返回值:
* 插入结点后AVL树的根节点
*/
AVLNode* AVLTree::insert(AVLNode* root, int key)
{
if (root == NULL)
root = new AVLNode(key, NULL, NULL);
else if (key < root->key) //插入左子树
{
root->left = insert(root->left, key);
if (height(root->left) - height(root->right) == 2) //插入二叉树导致失衡
{
if (key < root->left->key)
root = leftLeftRotate(root);
else root = leftRightRotate(root);
}
}
else if (key>root->key) //插入右子树
{
root->right = insert(root->right, key);
if (height(root->right) - height(root->left) == 2) //插入导致二叉树失衡
{
if (key > root->right->key)
root = rightRightRotate(root);
else root = rightLeftRotate(root);
}
}
root->height = max(height(root->left), height(root->right)) + 1;
return root;
}
/*
* 将结点插入到AVL树中,并返回根节点
*
* 参数说明:
* root 删除结点前AVL树的根结点
* node 要删除的结点
* 返回值:
* 删除结点node后AVL树的根节点
*/
AVLNode* AVLTree::deleteNode(AVLNode* root, AVLNode* node)
{
if (root == NULL)
return NULL;
if (node->key < root->key) //要删除的结点在左子树
{
root->left = deleteNode(root->left, node);
if (height(root->right) - height(root->left) == 2) //删除导致二叉树失衡
{
AVLNode* rightNode = root->right;
if (height(rightNode->left)>height(rightNode->right))
root = rightLeftRotate(root);
else root = rightRightRotate(root);
}
}
else if (node->key > root->key) //要删除的结点在右子树
{
root->right = deleteNode(root->right, node);
if (height(root->left) - height(root->right) == 2) //删除导致二叉树失衡
{
AVLNode* leftNode = root->left;
if (height(leftNode->left) > height(leftNode->right))
root = leftLeftRotate(root);
else root = leftRightRotate(root);
}
}
else //找到了要删除的结点
{
if (root->left != NULL&&root->right != NULL) //结点的左右子树均不为空
{
if (height(root->left) > height(root->right))
{
/*
* 如果tree的左子树比右子树高;
* 则(01)找出tree的左子树中的最大节点
* (02)将该最大节点的值赋值给tree。
* (03)删除该最大节点。
* 这类似于用"tree的左子树中最大节点"做"tree"的替身;
* 采用这种方式的好处是:删除"tree的左子树中最大节点"之后,AVL树仍然是平衡的。
*/
AVLNode* maxNode = maximus(root->left);
root->key = maxNode->key;
root->left = deleteNode(root->left, maxNode);
}
else
{
/*
* 如果tree的左子树不比右子树高(即它们相等,或右子树比左子树高1)
* 则(01)找出tree的右子树中的最小节点
* (02)将该最小节点的值赋值给tree。
* (03)删除该最小节点。
* 这类似于用"tree的右子树中最小节点"做"tree"的替身;
* 采用这种方式的好处是:删除"tree的右子树中最小节点"之后,AVL树仍然是平衡的。
*/
AVLNode* minNode = minimus(root->right);
root->key = minNode->key;
root->right = deleteNode(root->right, minNode);
}
}
else
{
AVLNode* tmp = root;
root = (root->left != NULL) ? root->left : root->right;
delete tmp;
}
}
return root;
}
/*销毁二叉树*/
void AVLTree::destroy(AVLNode* root)
{
if (root == NULL)
return;
destroy(root->left);
destroy(root->right);
delete root;
}
int main()
{
// int a[] = { 3,2,1,4,5,6,7,16,15,14,13,12,11,10,8,9 };
int a[] = { 45, 20, 37, 50, 60, 70};
int len = sizeof(a) / sizeof(a[0]);
AVLTree* avlTree = new AVLTree();
AVLNode* root = avlTree->getRoot();
for (int i = 0;i < len;i++)
root = avlTree->insert(root, a[i]);
// cout << "先序遍历:";
// avlTree->preOrder(root);
// cout << endl;
cout << "中序遍历:";
avlTree->inOrder(root);
cout << endl;
//
// cout << "后序遍历:";
// avlTree->postOrder(root);
// cout << endl;
//
// cout << "删除结点4" << endl;
// AVLNode* node = avlTree->search(root, 4);
// if (node != NULL)
// AVLNode* dnode = avlTree->deleteNode(root, node);
//
// cout << "删除结点4后先序遍历:";
// avlTree->preOrder(root);
// cout << endl;
// cout << "删除结点4后中序遍历:";
// avlTree->inOrder(root);
// cout << endl;
//
// cout << "销毁AVL树" << endl;
avlTree->destroy(root);
return 0;
}