平衡二叉树

来源:互联网 发布:ubuntu 16.04 pyqt5 编辑:程序博客网 时间:2024/05/16 03:23
#pragma once
#define VOID template<class T>\void AVItree<T>::#define NODE template<class T>\typename AVItree<T>::node* AVItree<T>::#define max(a,b) (a)>(b)?(a):(b)#define tempRoot (*t)//平衡二叉树template <class T>class AVItree{struct node{T data;node *left, *right;int height;//树的高度、平衡因子node(const T data) :data(data) { left = right = NULL; height = 0; }}*root;public:AVItree() { root = NULL; }~AVItree() { _clear(&root); }//插入数据void insert(T data) { _ins(&root, data); }//中序遍历输出void midOut() { _midP(&root); }//获取树的高度int getHG() { return getHeight(&root); }//删除节点void del(T data) { _del(data, &root); }private:node* findMax(node**);//得到数据最大的结点node* findMin(node**); node* Lrotate(node**);//旋转node* Rrotate(node**);node* LRrotate(node**);node* RLrotate(node**);int getHeight(node**);//得到树的高度void _ins(node**, T);//插入void _midP(node**);//中序输出void _clear(node**);//清空void _del(T const, node**);//删除节点};//删除指定节点VOID _del(T const data, node*tempRoot){if (!tempRoot)return;//我都不是树,你删除个屁呀else if (data == tempRoot->data){//找到了,该死的数藏在这里了if (tempRoot->left && tempRoot->right){//他娘的左右子树都不是空树,让老子心烦if (getHeight(&tempRoot->left) > getHeight(&tempRoot->right)){//左树看上去比较高大,砍他tempRoot->data = findMax(&tempRoot->left)->data;//把左树上那个最大叶子给我拿意大利炮轰了_del(tempRoot->data, &tempRoot->left);}else{//NO NO NO 右子树看着更让人生气tempRoot->data = findMin(&tempRoot->right)->data;//那就让右树上最小的叶子切腹自尽_del(tempRoot->data,&tempRoot->right);}}else  {//左右子树有至少一个是空的node *old = tempRoot;if (tempRoot->left || tempRoot->right){tempRoot = tempRoot->left ? tempRoot->left : tempRoot->right;delete old;}else{delete tempRoot;tempRoot = NULL;}}//因为是平衡树,且只有一个节点,那就肯定已经是末端了,不要多想了}else if (data < tempRoot->data){//没找到,但是比我小,给我去左边搜_del(data, &tempRoot->left);if (getHeight(&tempRoot->right)- getHeight(&tempRoot->left) > 1){//还能平衡吗?因为是删的左边,//左边已经不可能会比右边还粗大了,好汉不提当年勇,快平衡一下吧if (getHeight(&tempRoot->right->left) >getHeight(&tempRoot->right->right))//左边不能比右边大,看我乾坤大挪移tempRoot = LRrotate(&tempRoot);else//不平衡,总要移动一下嘛tempRoot = Rrotate(&tempRoot);}else//心理上还能承受这次打击,只调整下高度就好了tempRoot->height = max(getHeight(&tempRoot->left),getHeight(&tempRoot->right)) + 1;//注意这里不是-1哦,毕竟,爸爸总要比孩子高一辈嘛}else//没找到,再去右边找找{_del(data, &tempRoot->right);if (getHeight(&tempRoot->left) - getHeight(&tempRoot->right) > 1){if (getHeight(&tempRoot->left->right) >getHeight(&tempRoot->left->left))tempRoot = RLrotate(&tempRoot);elsetempRoot = Rrotate(&tempRoot);}elsetempRoot->height = max(getHeight(&tempRoot->left),getHeight(&tempRoot->right)) + 1;}//在找不到就说明这个傻逼用户想要删一个不存在的数,不管他了}//求树的高度template<class T>int AVItree<T>::getHeight(node*tempRoot){if (!tempRoot)return -1;else return tempRoot->height;}//右旋转NODE Rrotate(node *tempRoot){node *q = tempRoot->left;tempRoot->left = q->right;q->right = tempRoot;tempRoot = q;//旋转完毕,下面是高度的重新调整    tempRoot->height = max(getHeight(&tempRoot->left),getHeight(&tempRoot->right)) + 1;    q->height = max(getHeight(&q->left),getHeight(&q->right)) + 1;return q;}//左旋转NODE Lrotate(node*tempRoot){node *q = tempRoot->right;tempRoot->right = q->left;q->left = tempRoot;tempRoot = q;tempRoot->height = max(getHeight(&tempRoot->left),getHeight(&tempRoot->right)) + 1;q->height = max(getHeight(&q->left),getHeight(&q->right)) + 1;return q;}//右左旋转NODE RLrotate(node*tempRoot){Lrotate(&tempRoot->left);return Rrotate(&tempRoot);}//左右旋转NODE LRrotate(node*tempRoot){Rrotate(&tempRoot->right);return Lrotate(&tempRoot);}//插入数据VOID _ins(node*tempRoot, T data){if (!tempRoot)tempRoot = new node(data);else if (data < tempRoot->data){//因为数据要比根数据小,所以要插入在左边_ins(&tempRoot->left, data);//插入后判断平衡情况if (getHeight(&tempRoot->left) - getHeight(&tempRoot->right) > 1){//如果不平衡(高度差为2),就旋转if (data < tempRoot->left->data)//4->3->2这种情况tempRoot = Rrotate(&tempRoot);//只进行右旋转else//4->2->3这种情况,如果只右旋,2为开头,显然是不对的tempRoot = RLrotate(&tempRoot);//需要右左旋转}//这里有另一种写法,判断符号的写法,不过太JB难,} //或者说我找到的那种教程与我平常的代码风格相差太大,我看不懂else if (data > tempRoot->data){_ins(&tempRoot->right, data);if (getHeight(&tempRoot->right) - getHeight(&tempRoot->left) > 1){if (data > tempRoot->right->data)tempRoot = Lrotate(&tempRoot);elsetempRoot = LRrotate(&tempRoot);}}//插入了数据就要重新调整一次树的高度tempRoot->height = max(getHeight(&tempRoot->left), getHeight(&tempRoot->right)) + 1;}//输出VOID _midP(node*tempRoot){if (tempRoot){_midP(&tempRoot->left);cout << tempRoot->data << ends;_midP(&tempRoot->right);}}//清空数据VOID _clear(node*tempRoot){if (!tempRoot)return;_clear(&tempRoot->left);_clear(&tempRoot->right);delete tempRoot;tempRoot = NULL;}//找最大结点NODE findMax(node*tempRoot){if (!tempRoot)return NULL;if (!tempRoot->right)return tempRoot;return findMax(&tempRoot->right);}//找最小结点NODE findMin(node*tempRoot){if (!tempRoot)return NULL;if (!tempRoot->left)return tempRoot;return findMin(&tempRoot->left);}


原创粉丝点击