python平衡搜索二叉树

3 篇文章 0 订阅
1 篇文章 0 订阅

平衡二叉树的实现,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;
 }

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值