平衡二叉树
来源:互联网 发布:nagle算法 编辑:程序博客网 时间:2024/05/21 17:54
- #include "iostream"
- #include "cmath"
- using namespace std;
- //首先分析了这几种旋转,发现都和平衡因子有关系,当一个结点平衡因子为2的时候,就该旋转了。
- /*左旋之后,K1子节点的右枝上如果有结点给予K2,左枝上的结点保持不变;
- 右旋之后,K1子节点的左枝上如果有结点给予K2,右枝上的结点保持不变。*/
- template<class T>
- class avlTree
- {
- public:
- avlTree();
- avlTree(const avlTree &rhs);
- ~avlTree();
- const avlTree<T> &operator=(const avlTree &rhs);
- //int Balance(avlNode *t); //隐含了一个类嵌套的问题,就是私有类的位置问题。BAB OR ABA
- void insert(const T &x);
- void remove(const T &x);
- void inOrderPrint();
- private:
- struct avlNode
- {
- T element;
- avlNode *left;
- avlNode *right;
- int height;
- avlNode(const T &theElement, avlNode *lt, avlNode *rt, int h = 0)
- :element(theElement), left(lt), right(rt), height(h){}
- };
- avlNode *root;
- void RR(avlNode *k2);
- void LL(avlNode *k2);
- void LR(avlNode *k2);
- void RL(avlNode *k2);
- void insert(const T &x, avlNode * &root); //结点比较的插入
- void remove(const T &x, avlNode * &root);
- void inOrderPrint(avlNode * root);
- public:
- int height(avlNode *t);
- };
- template<class T>
- avlTree<T>::avlTree()
- {
- root = NULL;
- }
- template<class T>
- avlTree<T>::~avlTree()
- {
- }
- template<class T>
- avlTree<T>::avlTree(const avlTree &rhs)
- {
- root = rhs;
- }
- template<class T>
- const avlTree<T> &avlTree<T>::operator=(const avlTree &rhs)
- {
- if(this = &rhs)
- return *this;
- delete root;
- root = new avlNode;
- root = rhs.root;
- return *this;
- }
- /*if the tree is unbalance ,adjust the smallest unbalance tree to get the balance tree */
- /* the smallest unbalance root node is the nearest to the branches nodes*/
- template<class T>
- int avlTree<T>::height(avlNode *t)
- {
- return root == NULL ? -1 : root->height;
- }
- /* case one RR //定义右旋,右旋时K2的左孩子一定不为空。 //外侧插入
- * 80 ← k2 60
- * /\ /\
- * k1→ 60 90 → 20 80
- * / \ / /\
- * 20 75 ? 75 90
- * /
- * ?
- */
- template<class T>
- void avlTree<T>::RR(avlNode *k2) //the t node is unbalance node
- {
- avlNode *k1 = k2->left;
- k2->left = k1->right;
- k1->right = k2;
- k2->height = max(height(k2->right), height(k2->left)) + 1;
- k1->height = max(height(k1->left), k2->height) + 1;
- k2 = k1;
- }
- /* case two LL //定义左旋,左旋时,k2的右孩子一定不为空 //外侧插入
- * k2→ 100 120
- * /\ /\
- * 85 120 ←k1 → 100 130
- * / \ / \ \
- * 110 130 85 110 ?
- * \
- * ?
- */
- template<class T>
- void avlTree<T>::LL(avlNode *k2)
- {
- avlNode *k1; //enter the tree
- k1 = k2->right;
- k2->right = k1->left;
- k1->left = k2;
- k2->height = max(height(k2->right), height(k2->left)) + 1;
- k1->height = max(height(k2->right), k2->height) + 1;
- k2 = k1;
- }
- /* case three RL //内测插入 //r有个孩子不为空
- * the detal can contain two cases
- * first
- *
- * LL RR
- * 100 → p → 100 → 90
- * /\ /\ /\
- * p → 80 120 l → 90 120 80 100
- * /\ / /\ \
- * 60 90 ← r 80 60 85 120
- * / /\ /
- * 85 60 85 ?
- * / /
- * ? ?
- */
- template<class T>
- void avlTree<T>::RL(avlNode *k2)
- {
- LL(k2->left);
- RR(k2);
- }
- /* case four LR //内测插入 //r有个孩子不为空
- * the detal can contain two cases
- * 右旋 左旋
- * 80 → 80 ← p → 85
- * /\ /\ /\
- * 60 100 ← p 60 85 ← r 80 100
- * /\ \ / /\
- * l →85 120 100 60 90 120
- * \ /\ /
- * 90 90 120 ?
- * / /
- * ? ?
- */
- template<class T>
- void avlTree<T>::LR(avlNode *k2)
- {
- RR(k2->right);
- LL(k2);
- }
- //插入策略,插完调整
- /* 在特殊情况时 //特殊情况先左旋为正常情况在进行右旋。
- * 39 <-k2 LL 39 <-k2 RR 30 <-r
- * / / /\
- * k1-> 20 ---> r-> 30 ---> k1-> 20 39 <-k2
- * \ /
- * r-> 30 k1-> 20
- */
- template<class T>
- void avlTree<T>::insert(const T &x)
- {
- insert(x, root);
- }
- template<class T>
- void avlTree<T>::insert(const T &x, avlNode * &root)
- {
- if(root == NULL) //如果根树为block,and then insert at there
- root = new avlNode(x, NULL, NULL);
- else if(x < root->element) //左子树上插入
- {
- insert(x, root->left);
- if(height(root->left) - height(root->right) == 2)
- if(x < root->left->element)
- RR(root);
- else //上述特殊情况下的插入
- LR(root);
- }
- else if(x > root->element)
- {
- insert(x, root->right);
- if((height(root->right) - height(root->left)) == 2)
- if(x > root->right->element)
- LL(root);
- else
- RL(root);
- }
- else
- ;
- root->height = max(height(root->left), height(root->right)) + 1; //旋转之后,现在找到左孩子和右孩子的高度,然后定义自己的高度
- }
- //删除策略,将要删的右子结点的最小节点值给了删的那个root->element
- /* 在特殊情况时
- * 39 <-root 30
- * / \ / \
- * 20 49 ---> 20 49
- * /
- * 30 delete:30
- */
- template<class T>
- void avlTree<T>::remove(const T &data) //删除结点
- {
- remove(data, root);
- }
- template<class T>
- void avlTree<T>::remove(const T &data, avlNode * &root)
- {
- if(root == NULL) //此节点不存在,
- return;
- if(data < root->element) //左子树上进行删除
- {
- remove(data, root->left); //循环找到那个结点
- if(height(root->right) - height(root->left) == 2)
- {
- if(root->right->left != NULL && (height(root->right->left) > height(root->right->right)))
- RL(root);
- else
- RR(root);
- }
- }
- else if(data > root->element) //右子树上进行删除
- {
- remove(data, root->right);
- if(height(root->left) - height(root->right) == 2)
- {
- if((root->left->right) != NULL && (height(root->left->right) > height(root->left->left)))
- LR(root);
- else
- LL(root);
- }
- }
- else if(data == root->element) //这个结点上的删除
- {
- if(root->right != NULL && root->left != NULL) //两个子节点都存在
- {
- avlNode *temp = root->right;
- while(temp != NULL) temp = temp->left; //将右子结点的最小值替换root
- root->element = temp->element;
- remove(root->element, root->right); //再将那个最小的值清除
- if(height(root->left) - height(root->right) == 2)
- {
- if(root->left->right != NULL && height(root->left->right) > height(root->left->left))
- RL(root);
- else
- LL(root);
- }
- }
- else //只存在一个子节点或不存在子节点
- {
- avlNode *temp = root;
- if(root->left == NULL) //只有右结点,将其作为根结点
- root = root->right;
- else if(root->right == NULL)
- root = root->left;
- delete temp;
- temp = NULL;
- }
- }
- if(root == NULL) return;
- root->height = max(height(root->left), height(root->right)) + 1; //重设高度
- return;
- }
- template<class T>
- void avlTree<T>::inOrderPrint() //中序遍历输出
- {
- inOrderPrint(root);
- }
- template<class T>
- void avlTree<T>::inOrderPrint(avlNode * root)
- {
- if(root == NULL)
- return;
- if(root->left)
- inOrderPrint(root->left);
- cout << root->element << " ";
- if(root->right)
- inOrderPrint(root->right);
- return;
- }
- int main()
- {
- avlTree<int> tree;
- tree.insert(20);
- tree.insert(30);
- tree.insert(25);
- tree.remove(25);
- tree.inOrderPrint();
- return 0;
- }
0 0
- 平衡二叉树平衡法则
- 二叉树--二叉平衡树
- 平衡二叉树的
- 平衡二叉树
- 平衡二叉树
- 平衡二叉树
- 平衡二叉树
- 平衡二叉查找树
- 平衡二叉树 详解
- 平衡二叉树
- 平衡二叉树
- AVL 平衡二叉树
- 平衡二叉树
- 平衡二叉树-红黑树
- 平衡二叉树
- 平衡二叉树
- 平衡二叉树
- 平衡二叉树
- 位、字节、字、地址的联系
- n-queens
- 二叉树的查找
- 搭建一个免费的,无限流量的Blog----github Pages和Jekyll入门
- CentOS 6.5系统服务详解
- 平衡二叉树
- 隐马尔可夫模型(HMM)学习
- jquery源码分析三 96-283行源码解析
- intellij idea13.1.4b配置go开发环境
- 并查集
- java学习第1天——java中的classpath与path的执行顺序
- 在CentOS 6.5上安装软件
- [Leetcode]Plus One
- CentOS 6.5 安装无线网卡驱动实现无线上网