BinTreeSearch And AVL

一.平衡二叉树 VS 搜扫二叉树

 1. 平衡二叉树:解决在树的结构搜扫的时候,防止搜扫数据呈现出斜二叉树的数据结构,因此在节点插入和删除的时候,自动的调节树的数据结构,让树搜索速度达到log(N)的时间复杂度。

下面二叉搜索树的构造和其各种运用Delete,Insert

对于二叉搜索树删除:1.度为2节点删除,要么从左子树选择最大节点代替此删除节点,或者从右子树中选择最小的节点代替此节点。2.度不大于1的节点:将左节点或者右节点覆盖此为位置T=T->Left。

#include<iostream>
using namespace std;
#define  ElementType int
//对二叉搜扫树各种功能模拟

typedef struct TreeNode{
    ElementType Data;
    struct TreeNode *LeftNode;
    struct TreeNode *RightNode;
}*BinTree,BinTreeNode;

BinTree CreateBinSearch()
{
    BinTree root=new BinTreeNode,ptr,Rear;
    root->LeftNode=NULL;root->RightNode=NULL;root->Data=NULL;
    int num=100;
    cout<<"输出-1值表示停止"<<endl;
    
    
    while(true)
    {
        cin>>num;
        ptr=root;
        if(num==-1)  break;
        if(ptr->Data==NULL)
        {
            ptr->Data=num;//空树
        }
        else
        {
            Rear=new BinTreeNode;
            Rear->Data=num;Rear->LeftNode=NULL;Rear->RightNode=NULL;

            while(ptr)
            {
                if(num<ptr->Data)
                {
                    if(ptr->LeftNode==NULL)
                    {    ptr->LeftNode=Rear; break;}
                    else
                             ptr=ptr->RightNode;
                }
                else{
                    if (ptr->RightNode==NULL)
                        
                    {
                        {ptr->RightNode=Rear;break;}
                    }else
                    {
                        ptr=ptr->RightNode;
                    }
                
                }            
        
            }

        }
    }

    return root;
}
BinTree Insert(BinTree Rear,int X)
{
    //采用递归的形式对新输入的值进行插入,不断对值递归调用直到最后进行
    
    if(!Rear) 
    {        //最后递归找到插入位置最后对位置进行插入
            cout<<"这个是一颗空树"<<endl;
            Rear->Data=X;Rear->LeftNode=NULL;Rear->RightNode=NULL;
    }
    //使用尾部递归方式
    else{
                if(Rear->Data>X)
                    Insert(Rear->LeftNode,X);
                else
                    Insert(Rear->RightNode,X);

    }
    return Rear;

}
BinTree FindMin(BinTree Rear)
{
    /*while(Rear->LeftNode)
        Rear=Rear->LeftNode;
    return Rear;*/
    //采用递归的话
    if(!Rear) return NULL;
    else if(!Rear->LeftNode)
        return Rear;
    else
        FindMin(Rear->LeftNode);
}
BinTree Delete(BinTree Rear,int delete_value)
{
    //对于删除节点分为两种情况,节点度=2,只能从此节点的左子树中找一个最大值代替此删除点
    //度=1,删除此点,将其单个子节点填补其位置就行

    if(!Rear)
        cout<<"删除的点没有找到"<<endl ;
    //开始寻找要删除点->Data=delete_value;
    if(delete_value>Rear->Data)
        Delete(Rear->RightNode,delete_value);
    else if(Rear->Data<delete_value)
        Delete(Rear->LeftNode,delete_value);
    else
    {
        //刚好找到其位置
        BinTree tmp;
        if(Rear->LeftNode && Rear->RightNode)
        {
            tmp=FindMin(Rear->RightNode);
            Rear->Data=tmp->Data;
            //在从右子树中删除最小的节点,是一个叶子节点
            Delete(Rear->RightNode,tmp->Data);
        }
        else{
            //最多只有一个节点
            if(Rear->LeftNode)
                Rear=Rear->LeftNode;
            else
                Rear=Rear->RightNode;
        }
    }
}
int main()
{
    BinTree rootNode;
    rootNode=CreateBinSearch();
    cout<<"********向二叉搜扫树中插入值************"<<endl;
    int Insert_numbel;
    cin>>Insert_numbel;
    rootNode=Insert(rootNode,Insert_numbel);

    cout<<"********向二叉搜扫树中删除值************"<<endl;
    int Y;
    cin>>Y;
    Delete(rootNode,Y);
    return 0;
}

2. 在调节树的数据结构的,通过平衡因子BF调节其结构;BF=h(x-Right)-h(x-left)---节点X的右子树高度减去左子树高度

3.根据插入和删除的节点不同,将造成不平衡节点分为4种方式,LL,RR,LR,RL 四种格式

 规则:调整之后必须要保持其是二叉搜索树的特性

LL: 由于B节点左子树插入节点导致A点失去平衡:以B节点为轴心,A节点顺时针循转到B的右子树中,B原来的右子树变为A的左子树

 

LR:B节点右子插入新的节点导致A节点失去平衡,插入在被破坏者May的左子树的右子树上,因此做LR循转

Mar调整到根节点上,A-B-C:调整为C-B-A。C是B的右子树节点。

 判断其是单旋 Vs双旋  插入B节点的后面

比较 破坏者C,被破坏者A,A>B>C(A<B<C):A的左子树左子树上LL(右子树右子树RR);

如果C节点在中间A>C>B(A<C<B): 做双旋转,A的左子树右子树上LR旋转(A 的右子树左子树上RL旋转)。

#include<iostream>
#include<queue>
using namespace std;

#define  ElementType int

typedef struct AVLTree{
    ElementType Data;
    int Height;//计算单个节点上的树的高度
    AVLTree  *LeftNode;
    AVLTree *RightNode;
    //构造函数初始化
    AVLTree():Data( NULL),Height(NULL),LeftNode(NULL),RightNode(NULL){}
}*AvlTree,AvlTreeNode;
int max(int a,int b)
{
    return a>b?a:b;
}
int GetHeight(AvlTree T)
{
    if (!T)
        return -1;
    else
        return T->Height;

    if (!T)
        return 0;
    else
        return max(GetHeight(T->LeftNode),GetHeight(T->RightNode))+1;

}
AvlTree SigngleRoatedWithLeft(AvlTree T)
{
    //左单旋
    AvlTree T1;
    T1=T->LeftNode;
    T->LeftNode=T1->RightNode;
    T1->RightNode=T;
    //更新新的矩阵值,高的指树的高度
    T->Height=max(GetHeight(T->LeftNode),GetHeight(T->RightNode))+1;
    T1->Height=max(GetHeight(T1->LeftNode),T->Height)+1;
    return T1;

}

AvlTree SigngleRoatedWithRight(AvlTree T)
{//右单旋
    AvlTree T1;
    T1=T->RightNode;
    T->RightNode=T1->LeftNode;
    T1->LeftNode=T;
    //更新新的矩阵值,高的指树的高度
    T->Height=max(GetHeight(T->LeftNode),GetHeight(T->RightNode))+1;
    T1->Height=max(GetHeight(T1->LeftNode),T->Height)+1;
    return T1;

}
AvlTree DoubleRoatedLeftandRight(AvlTree A)
{
    //双旋,左右双旋,先做右旋修改A->left
    //A 节点右一个左节点B,B有一个右节点C
    A->LeftNode=SigngleRoatedWithRight(A->LeftNode);
    //对A做左旋
    return  SigngleRoatedWithLeft(A);


}
AvlTree DoubleRoatedRightandLeft(AvlTree A)
{
    //双旋,左右双旋,先做右旋修改A->left
    //A 节点右一个左节点B,B有一个右节点C
    //对A-.right做左旋
    A->RightNode=SigngleRoatedWithLeft(A->RightNode);
    //对A做左旋
    return  SigngleRoatedWithRight(A);


}


AvlTree Insert(ElementType X,AvlTree T)
{
    if(!T)//判断其是否是空树
    {//t通过递归建立树
        T=new AvlTreeNode;
        T->Data=X;
        T->Height=0;

    }
    else if(X<T->Data)
    {
        /*插入到左子树中*/
        T->LeftNode=Insert(X,T->LeftNode);
        if(GetHeight(T->LeftNode)-GetHeight(T->RightNode)==2)
        {        
            if(X<T->LeftNode->Data)
                    {
                        T=SigngleRoatedWithLeft(T);//左单旋
                      }
                else{
                        T=DoubleRoatedLeftandRight(T);//左右单旋
                        }
                }
        }
    else if(X>T->Data)
    {
        T->RightNode=Insert(X,T->RightNode);
        if(GetHeight(T->LeftNode)-GetHeight(T->RightNode)==-2)
        {
            if(X>T->RightNode->Data)
            {
                T=SigngleRoatedWithRight(T);//左单旋
            }
            else
            {
                //右左双旋
                T=DoubleRoatedRightandLeft(T);
            }
        }
    }

    T->Height=max(GetHeight(T->LeftNode),GetHeight(T->RightNode))+1;
    return T;
}
void Pre_order(AvlTree T)
{
    if(T)
    {
        cout<<T->Data<<"  ";
        Pre_order(T->LeftNode);
        Pre_order(T->RightNode);
    
    }
    else
    {
        cout<<"#"<<"  ";
    }

}
void Level_order(AvlTree T)
{//使用队列对层次遍历
    queue<AvlTree>Q;
    Q.push(T);
    while(T && !Q.empty())
    {
        T=Q.front();
        cout<<T->Data<<" ";
        if(T->LeftNode) Q.push(T->LeftNode);
        if(T->RightNode) Q.push(T->RightNode);
        Q.pop();
    }
}
int main()
{
    AvlTree Avl=new AvlTreeNode;
    
    //通过插入建立AVL平衡树,通过斜插;
    for(int i=1;i<=7;i++)
    {
        Avl=Insert(i,Avl);
    }
    //前序遍历输出
     Pre_order(Avl);
     cout<<endl;
     cout<<"层次遍历"<<endl;
     Level_order(Avl);
    return 0;
}

二叉平衡树采用java中泛型数据,其中加入对数据的remove处理

package Tree;

import java.util.LinkedList;

//12.1采用数据进行测试



public class AVLTree <AnyType> {
    
    private static class AvlNode<AnyType>
    {
            AnyType element;
            AvlNode<AnyType> left;
            AvlNode<AnyType>right;
            int height;//AvlTree Hegiht
            
         
            public AvlNode(AnyType E)
            {
                this.element=E;
                this.left=null;
                this.right=null;
                this.height=-1;
            }
            public AvlNode(AnyType thiselement,AvlNode<AnyType>lt,AvlNode<AnyType>rt,int h)
            {
                this.element=thiselement;
                this.left=lt;
                this.right=rt;
                this.height=h;
            }
    }
    public static AvlNode  Avltree;
    
    //通过插入AVlTree
    private AvlNode<AnyType> insert(AnyType x,AvlNode<AnyType>t)
    {
        if(t==null)
            return new AvlNode(x);
        int compareResult=((Comparable<AnyType>) x).compareTo(t.element);
        
        if(compareResult>0)
            t.right=insert(x,t.right);
        else if(compareResult<=0)
                t.left=insert(x,t.left);
        //最后对插入树进行调整,通过遍历其中每个树的高度
        return balance(t);
}
    private int height(AvlNode<AnyType>p)
    {
        return p==null?-1:p.height;
    }
    private AvlNode<AnyType>roatedWithLeftChild(AvlNode <AnyType>k2)
    {
        //k2 平衡性被破坏的点
        AvlNode<AnyType> k1=k2.left;
        k2.left=k1.right;
        k1.right=k2;
        
        //更新所在的的高度,k1上升,k2下降
        k2.height=Math.max(height(k2.left),height(k2.right))+1;
        k1.height=Math.max(height(k1.left),k2.height)+1;
        return k1;
    }
    private AvlNode<AnyType>roatedWithRightChild(AvlNode <AnyType>k2)
    {
        //k2 平衡性被破坏的点
        AvlNode<AnyType> k1=k2.right;
        k2.right=k1.left;
        k1.left=k2;
        
        //更新所在的的高度,k1上升,k2下降
        k2.height=Math.max(height(k2.left),height(k2.right))+1;
        k1.height=Math.max(height(k1.right),k2.height)+1;
        return k1;
    }
    
    private AvlNode<AnyType>doubleWithLeftChild(AvlNode<AnyType>k3)
    {
        k3.left=roatedWithRightChild(k3.left);
        return roatedWithLeftChild(k3);
    }
    private AvlNode<AnyType>doubleWithRightChild(AvlNode<AnyType>k3)
    {
        k3.right=roatedWithLeftChild(k3.right);
        return roatedWithRightChild(k3);
    }
    
    private AvlNode<AnyType > balance (AvlNode<AnyType> t)
    {
        if(t==null)
            return t;
        
        if(height(t.left)-height(t.right)>1)
        {
            if(height(t.left.left)>=height(t.left.right))
                //这里等于号,说明t的左树左子孙 =左子树的右子孙;这样树调整只需要进行单步的旋转就可以解决问题
                t=roatedWithLeftChild(t);
            else
                t=doubleWithLeftChild(t);
        }
        else
        {
            if(height(t.right)-height(t.left)>1)
                if(height(t.right.right)>=height(t.right.left))
                    t=roatedWithRightChild(t);
                else
                    t=doubleWithRightChild(t);
        }
        t.height=Math.max(height(t.left),height(t.right))+1;
        return t;
    }
    
    //数据点删除
    private AvlNode<AnyType> findMin(AvlNode<AnyType>t)
    {
        if(t==null)
            return null;
        if(t.left==null)
            return t;
        return findMin(t.left);
    }
    private AvlNode <AnyType> remove (AnyType x,AvlNode <AnyType>t)
    {  boolean flag=false;
        if(t==null)
            return null;
        @SuppressWarnings("unchecked")
        int compareResult=((Comparable<AnyType>) x).compareTo(t.element);
        AvlNode <AnyType> tmp=null;
        if(compareResult<0)
        {
            remove(x,t.left);
        }
        else if(compareResult>0)
            {  remove(x,t.right);}
        else
        {//刚好找到其位置
            flag=true;
            if(t.left!=null && t.right!=null)
            {    
                 tmp=findMin(t.right);
                 t.element=tmp.element;
                 t.right=remove(tmp.element,t.right);
            }
            else
            {
                //度是1
                if(t.left!=null)
                    t=t.left;
                else
                    t=t.right;
                                    
            }
            
        }
        System.out.println("Flag: "+flag);
        return balance(t);
    }
    public static void PreOrder(AvlNode P)
    {
        if(P!=null)
        {
            System.out.print("["+P.element+"]");
            PreOrder(P.left);
            PreOrder(P.right);
        }
    }
    public static void leveOrder (AvlNode P)
    {
        //使用层次遍历,使用队列
        LinkedList <AvlNode>queue=new LinkedList<AvlNode>();
        queue.add(P);
        while((P!=null) &&(!queue.isEmpty()))
        {
            P=queue.element();
            System.out.print("["+P.element+"]");
            if(P.left!=null) queue.add(P.left);
            if(P.right!=null) queue.add(P.right);
            queue.remove();
        }
        
    }
    public static void main(String [] args)
    {
        System.out.println("通过insert方法建立AVLTree");
        int [] Data={ 1,2,3,4,5,6,7,8};
        AVLTree Tree=new AVLTree();
        for(int i=0;i<Data.length;i++)
        {
            Tree.Avltree=Tree.insert(Data[i],Tree.Avltree);
            
        }
        
        System.out.println("Tree.Avltree Preorder *******:");
        PreOrder(Tree.Avltree);
        System.out.println("Tree.Avltree Leveorder *******:");
        leveOrder(Tree.Avltree);
        System.out.println("Tree.Avltree remove *******:");
        Tree.remove(6, Tree.Avltree);
        leveOrder(Tree.Avltree);
        
    }
    }

结果:

通过insert方法建立AVLTree

Tree.Avltree Preorder *******:
[4][2][1][3][6][5][7][8]
Tree.Avltree Leveorder *******:
[4][2][6][1][3][5][7][8]
Tree.Avltree remove *******:
Flag: true
Flag: true
Flag: false

[4][2][7][1][3][5][8]

原文地址:https://www.cnblogs.com/woainifanfan/p/6034791.html