对平衡二叉搜索树Balance Binary Search Tree所有功能的实现的头文件

最近在学计算几何,经常要用到BBST去储存一些数据,正是因为BBST查找效率极高O(logn)并且占用的空间仍是线性的,而其构造的时间需要O(nlogn),是可以接受的。所以在这里总结了BBST插入、删除、查找的功能到一个头文件中:

具体实现的原理可见https://blog.csdn.net/derbi123123/article/details/104204220

头文件:

#include 
#include 
using namespace std;
#define ElementType int//这里只需要改变ElementType的类型,下面的数据类型都是ElementType

typedef struct node *AVL;
struct node{
	ElementType data;
	int height;//节点高度(根节点最高,叶子结点最低)
	AVL left;
	AVL right;
};
//创建平衡二叉树:
AVL BuildBBST(ElementType data)
{
	AVL Root=new node;
	Root->data=data;
	Root->height=1;
	Root->left=NULL;
	Root->right=NULL;
	return Root;
}
//获得节点的高度:
int GetHeight(AVL tree)
{
	if(!tree) return 0;
	return tree->height;
}
//得到节点的平衡因子:
int GetBT(AVL tree)
{
	int BT=GetHeight(tree->left)-GetHeight(tree->right);//不用绝对值是因为方便判断用哪种方式调整
	return BT;
}
//右单旋:
AVL RR(AVL A)
{
	AVL B=A->right;
	A->right=B->left;
	B->left=A;
	//更新节点高度:
	A->height=max(GetHeight(A->left),GetHeight(A->right))+1;
	B->height=max(GetHeight(B->right),A->height)+1;
	return B;
}
//左单旋:
AVL LL(AVL A)
{
	AVL B=A->left;
	A->left=B->right;
	B->right=A;
	//更新节点高度:
	A->height=max(GetHeight(A->left),GetHeight(A->right))+1;
	B->height=max(GetHeight(B->left),A->height)+1;
	return B;
}
//左—右双旋:
AVL LR(AVL A)
{
	A->left=RR(A->left);//旋转B、C、CR/CL
	return LL(A);//旋转A、C、CR/CL
}
//右—左单旋:
AVL RL(AVL A)
{
	A->right=LL(A->right);//旋转B、C、CR/CL
	return RR(A);//旋转A、C、CR/CL
}
//插入新节点
AVL Insert(AVL tree,ElementType X)
{
	if(!tree){
		tree=new node;
		tree->data=X;
		tree->left=tree->right=NULL;
	}else if(X<tree->data){
		tree->left=Insert(tree->left,X);
		if(GetBT(tree)==2){//平衡因子超过1,自己想为什么是==2而不是>=2
			if(tree->left->data>X){//左单旋
				tree=LL(tree);
			}else{//左右单旋
				tree=LR(tree);
			}
		}
	}else{
		tree->right=Insert(tree->right,X);
		if(GetBT(tree)==-2){//平衡因子超过1,自己想为什么是==-2而不是<=-2
			if(tree->right->data<X){//右单旋
				tree=RR(tree);
			}else{//右左单旋
				tree=RL(tree);
			}
		}
	}
	tree->height=max(GetHeight(tree->left),GetHeight(tree->right))+1;
	return tree;
}
//删除节点
AVL Delete(ElementType X, AVL T) { //递归删除,返回根结点
    if(T == NULL) {
        printf("find null\n");
    } else if (X < T->data) {
        T->left = Delete(X, T->left); //递归删除左子树,返回根结点(当前结点的右子树结点高度比较大)
        if(GetBT(T)== 2) {
            AVL p = T->right;
            if(GetHeight(p->left) > GetHeight(p->right)) { //当前结点的右子树结点的左子树结点高度比较大,对右边的结点双旋
                T = RR(T);
            } else { //当前结点的右子树结点的右子树结点高度比较大,对右边的结点单旋
                T = RR(T);
            }
        }
    } else if (X > T->data) { //递归删除右子树,返回根结点(当前结点的左子树结点高度比较大)
        T->right = Delete(X, T->right);
        if(GetBT(T)== -2) {
            AVL p = T->left;
            if(GetHeight(p->left) < GetHeight(p->right)) { //当前结点的左子树结点的右子树结点高度比较大,对左边的结点双旋
                T = LR(T);
            } else { //当前结点的左子树结点的左子树结点高度比较大,对左边的结点单旋
                T = LL(T);
            }
        }
    } else {
        if(T->left != NULL && T->right != NULL) { //待删除的结点有两个孩子结点
            if(GetHeight(T->left) > GetHeight(T->right)) { //当前结点的左子树结点高度比较大
                AVL p = T->left;
                while(p->right != NULL) { //寻找当前结点的前驱结点,用于删除
                    p = p->right;
                }
                T->data = p->data;
                T->left = Delete(p->data, T->left);
            } else { //当前结点的右子树结点高度比较大
                AVL p = T->right;
                while(p->left != NULL) { //寻找当前结点的后继结点,用于删除
                    p = p->left;
                }
                T->data = p->data;
                T->right = Delete(p->data, T->right);
            }
        } else if(T->left == NULL && T->right == NULL){ //待删除的结点无孩子结点
            T = NULL;
        } else if(T->right == NULL) { //待删除的结点只有左孩子结点
            AVL p = T;
            T = T->left;
            free(p);
        } else { //待删除的结点只有右孩子结点
            AVL p = T;
            T = T->right;
            free(p);            
        }
    }

    if(T != NULL) {
        T->height = max(GetHeight(T->left), GetHeight(T->right)) + 1; //更新根结点高度,左右子节点高度的最大值加1
    }
    return T;
}

//遍历BBST(其实也只能前中后序遍历选一种,我看前序遍历还比较正常一些)
void TaveralBBST(AVL tree)
{
	if(tree){
		cout<<tree->data<<" ";
		TaveralBBST(tree->left);
		TaveralBBST(tree->right);
	}
}

//查找元素:如果存在那就返回对应节点,不存在返回小于查找元素的最大值
AVL Find(ElementType X,AVL T)
{
	if(T->data==X){
		return T;
	}else if(T->data<X){
		Find(X,T->right);
	}else if(T->data>X){
		Find(X,T->left);
	}else{
		return NULL;
	}
}

测试用的程序:

#include 
#include "BBST.h"
#include 
#define NUM 10
using namespace std;

int main()
{
	//先创建只有根节点的BBST
	AVL root;
	ElementType data;
	cin>>data;
	root=BuildBBST(data);
	//向BBST中加入元素
	node bbst[NUM];
	for(int i=0;i<NUM;i++){
		cin>>bbst[i].data;
		root=Insert(root,bbst[i].data);
	}
	//输出BBST的高度
	cout<<root->height<<endl;
	//前序遍历输出所有节点
	TaveralBBST(root);
	cout<<"\n";
	//删除根节点
	root=Delete(root->data,root);
	//输出新的根节点,前序遍历输出所有节点
	cout<<root->data<<endl;
	TaveralBBST(root);
	//查找节点
	ElementType searchData;
	cin>>searchData;
	AVL child=Find(searchData,root);
	if(!child)
		cout<<"找不到您要找的节点"<<endl;
	else
		cout<<child->data;
	getch();
	return 0;
}

实例:
对平衡二叉搜索树Balance Binary Search Tree所有功能的实现的头文件_第1张图片

你可能感兴趣的:(数据结构与算法,计算几何)