数据结构-AVL二叉平衡树
来源:互联网 发布:angularjs 2不用node 编辑:程序博客网 时间:2024/05/18 20:33
1.AVLTreeNode.h
#ifndef DATASTRUCTURE_AVLTREENODE_H#define DATASTRUCTURE_AVLTREENODE_Htemplate<class T>class AVLTreeNode {public: AVLTreeNode(T value, AVLTreeNode<T> *l, AVLTreeNode<T> *r) : key(value), lchild(l), rchild(r) {} T key;//节点的值 int height;//节点的高度,用于计算父节点的平衡因子 AVLTreeNode<T> *lchild; AVLTreeNode<T> *rchild;};/*在另外一些AVL实现的节点设计方案中,会把BF作为结点的一个属性存储起来,而在这里我们存储的是节点的高度,通过节点的高度我们也可以间接计算出节点的BF。例如节点A的左孩子的height = 2,右孩子 的height = 1,那么节点A的平衡因子为2 - 1 = 1.*/#endif //DATASTRUCTURE_AVLTREENODE_H
2.AVLTree.h
#ifndef DATASTRUCTURE_AVLTREE_H#define DATASTRUCTURE_AVLTREE_H#include "AVLTreeNode.h"#include <iostream>using namespace std;template<class T>class AVLTree {public: AVLTree(); //构造函数 ~AVLTree(); //析构函数 void preOrder(); //前序遍历AVL树 void inOrder(); //中序遍历AVL树 void postOrder(); //后序遍历AVL树 void print(); //打印AVL树 void destroy(); //销毁AVL树 void insert(T key); //插入指定值的节点 void remove(T key); //移除指定值的节点 AVLTreeNode<T> *search_recurse(T key); //利用递归算法进行指定值的查找 AVLTreeNode<T> *search_iterator(T key); //利用迭代算法进行指定值的查找 T minimum(); //返回AVL中的最小值 T maximum(); //返回AVL中的最大值 int height(); //返回树的高度private: AVLTreeNode<T> *root; void preOrder(AVLTreeNode<T> *pnode) const; void inOrder(AVLTreeNode<T> *pnode) const; void postOrder(AVLTreeNode<T> *pnode) const; void print(AVLTreeNode<T> *pnode, T key, int direction) const; //const为函数重载提供了一个参考 //常成员函数, 它不改变对象的成员变量. //也不能调用类中任何非const成员函数。 void destroy(AVLTreeNode<T> *&pnode); /*指针的引用*/ /* int fun(int*& p) { return *p;// 返回的是指针P指向的内容 }*/// 连起来跟没写这两个字符是一样的意思,取了地址&相当于引用,*是解引用,就是取内容,所以这两个操作符连在一起就相当于什么也没做,还是p。 int height(AVLTreeNode<T> *pnode); T max(T a, T b); AVLTreeNode<T> *insert(AVLTreeNode<T> *&pnode, T key); AVLTreeNode<T> *remove(AVLTreeNode<T> *&pnode, T key); //常成员函数, 它不改变对象的成员变量. //也不能调用类中任何非const成员函数。 AVLTreeNode<T> *minimum(AVLTreeNode<T> *pnode) const; AVLTreeNode<T> *maximum(AVLTreeNode<T> *pnode) const; AVLTreeNode<T> *search_recurse(AVLTreeNode<T> *pnode, T key) const; AVLTreeNode<T> *search_iterator(AVLTreeNode<T> *pnode, T key) const; AVLTreeNode<T> *leftRotation(AVLTreeNode<T> *pnode); //单旋:左旋操作 AVLTreeNode<T> *rightRotation(AVLTreeNode<T> *pnode); //单旋:右旋操作 AVLTreeNode<T> *leftRightRotation(AVLTreeNode<T> *pnode); //双旋:先左旋后右旋操作 AVLTreeNode<T> *rightLeftRotation(AVLTreeNode<T> *pnode); //双旋:先右旋后左旋操作};/*构造函数*/template<typename T>AVLTree<T>::AVLTree() :root(nullptr) {};/*析构函数*/template<typename T>AVLTree<T>::~AVLTree() { destroy(root);}/*返回两者中的较大者*/template<typename T>T AVLTree<T>::max(T a, T b) { return a > b ? a : b;};/*返回树中最大节点值*/template<typename T>AVLTreeNode<T> *AVLTree<T>::maximum(AVLTreeNode<T> *pnode) const { if (pnode != nullptr) { while (pnode->rchild != nullptr) pnode = pnode->rchild; return pnode; } return nullptr;};template<typename T>T AVLTree<T>::maximum() { AVLTreeNode<T> *presult = maximum(root); if (presult != nullptr) return presult->key;};/*返回树中最小节点值*/template<typename T>AVLTreeNode<T> *AVLTree<T>::minimum(AVLTreeNode<T> *pnode) const { if (pnode != nullptr) { while (pnode->lchild != nullptr) pnode = pnode->lchild; return pnode; } return nullptr;};template<typename T>T AVLTree<T>::minimum() { AVLTreeNode<T> *presult = minimum(root); if (presult != nullptr) return presult->key;};/*返回一棵树的高度*/template<typename T>int AVLTree<T>::height(AVLTreeNode<T> *pnode) { if (pnode != nullptr) { return pnode->height; } return 0; //如果是空树,高度为0};template<typename T>int AVLTree<T>::height() { return height(root);};/*左旋转操作*//*pnode为最小失衡子树的根节点*//*返回旋转后的根节点*/template<typename T>AVLTreeNode<T> *AVLTree<T>::leftRotation(AVLTreeNode<T> *proot) { AVLTreeNode<T> *prchild = proot->rchild; proot->rchild = prchild->lchild; prchild->lchild = proot; proot->height = max(height(proot->lchild), height(proot->rchild)) + 1; //更新节点的高度值 prchild->height = max(height(prchild->lchild), height(prchild->rchild)) + 1; //更新节点的高度值 return prchild;};/*右旋转操作*//*pnode为最小失衡子树的根节点*//*返回旋转后的根节点*/template<typename T>AVLTreeNode<T> *AVLTree<T>::rightRotation(AVLTreeNode<T> *proot) { AVLTreeNode<T> *plchild = proot->lchild; proot->lchild = plchild->rchild; plchild->rchild = proot; proot->height = max(height(proot->lchild), height(proot->rchild)) + 1; //更新节点的高度值 plchild->height = max(height(plchild->lchild), height(plchild->rchild)) + 1; //更新节点的高度值 return plchild;};/*先左后右做旋转*//*参数proot为最小失衡子树的根节点*//*返回旋转后的根节点*/template<typename T>AVLTreeNode<T> *AVLTree<T>::leftRightRotation(AVLTreeNode<T> *proot) { proot->lchild = leftRotation(proot->lchild); return rightRotation(proot);};/*先右旋再左旋*//*参数proot为最小失衡子树的根节点*//*返回旋转后的根节点*/template<typename T>AVLTreeNode<T> *AVLTree<T>::rightLeftRotation(AVLTreeNode<T> *proot) { proot->rchild = rightRotation(proot->rchild); return leftRotation(proot);};/*插入操作*//*递归地进行插入*//*返回插入后的根节点*/template<typename T>AVLTreeNode<T> *AVLTree<T>::insert(AVLTreeNode<T> *&pnode, T key) { if (pnode == nullptr) //寻找到插入的位置 { pnode = new AVLTreeNode<T>(key, nullptr, nullptr); } else if (key > pnode->key) //插入值比当前结点值大,插入到当前结点的右子树上 { pnode->rchild = insert(pnode->rchild, key); if (height(pnode->rchild) - height(pnode->lchild) == 2) //插入后出现失衡 { if (key > pnode->rchild->key) //情况一:插入右子树的右节点,进行左旋 pnode = leftRotation(pnode); else if (key < pnode->rchild->key) //情况三:插入右子树的左节点,进行先右再左旋转 pnode = rightLeftRotation(pnode); } } else if (key < pnode->key) //插入值比当前节点值小,插入到当前结点的左子树上 { pnode->lchild = insert(pnode->lchild, key); if (height(pnode->lchild) - height(pnode->rchild) == 2) //如果插入导致失衡 { if (key < pnode->lchild->key) //情况二:插入到左子树的左孩子节点上,进行右旋 pnode = rightRotation(pnode); else if (key > pnode->lchild->key) pnode = leftRightRotation(pnode);//情况四:插入到左子树的右孩子节点上,进行先左后右旋转 } } pnode->height = max(height(pnode->lchild), height(pnode->rchild)) + 1; return pnode;};template<typename T>void AVLTree<T>::insert(T key) { insert(root, key);};/*递归查找指定元素*/template<typename T>AVLTreeNode<T> *AVLTree<T>::search_recurse(T key) { return search_recurse(root, key);};template<typename T>AVLTreeNode<T> *AVLTree<T>::search_recurse(AVLTreeNode<T> *pnode, T key) const { if (pnode != nullptr) { if (key == pnode->key) return pnode; if (key > pnode->key) return search_recurse(pnode->rchild, key); else return search_recurse(pnode->lchild, key); } return nullptr;};/*非递归查找指定元素*/template<typename T>AVLTreeNode<T> *AVLTree<T>::search_iterator(T key) { return search_iterator(root, key);};template<typename T>AVLTreeNode<T> *AVLTree<T>::search_iterator(AVLTreeNode<T> *pnode, T key) const { while (pnode != nullptr) { if (pnode->key == key) return pnode; else if (key > pnode->key) pnode = pnode->rchild; else pnode = pnode->lchild; } return nullptr;};/*删除指定元素*/template<typename T>AVLTreeNode<T> *AVLTree<T>::remove(AVLTreeNode<T> *&pnode, T key) { if (pnode != nullptr) { if (key == pnode->key) //找到删除的节点 { //因AVL也是二叉排序树,删除节点要维护其二叉排序树的条件 if (pnode->lchild != nullptr && pnode->rchild != nullptr) //若左右都不为空 { if (height(pnode->lchild) > height(pnode->rchild)) //左子树比右子树高 { //使用左子树最大节点来代替被删节点,而删除该最大节点 AVLTreeNode<T> *ppre = maximum(pnode->lchild); //左子树最大节点 pnode->key = ppre->key; //将最大节点的值覆盖当前结点 pnode->lchild = remove(pnode->lchild, ppre->key); //递归地删除最大节点 } else { //使用最小节点来代替被删节点,而删除该最小节点 AVLTreeNode<T> *psuc = minimum(pnode->rchild); //右子树的最小节点 pnode->key = psuc->key; //将最小节点值覆盖当前结点 pnode->rchild = remove(pnode->rchild, psuc->key); //递归地删除最小节点 } } else { AVLTreeNode<T> *ptemp = pnode; if (pnode->lchild != nullptr) pnode = pnode->lchild; else if (pnode->rchild != nullptr) pnode = pnode->rchild; delete ptemp; return nullptr; } } else if (key > pnode->key) //要删除的节点比当前节点大,则在右子树进行删除 { pnode->rchild = remove(pnode->rchild, key); if (height(pnode->lchild) - height(pnode->rchild) == 2) //删除右子树节点导致不平衡:相当于情况二或情况四 { if (height(pnode->lchild->rchild) > height(pnode->lchild->lchild)) pnode = leftRightRotation(pnode); //相当于情况四 else pnode = rightRotation(pnode); //相当于情况二 } } else if (key < pnode->key) //要删除的节点比当前节点小,则在左子树进行删除 { pnode->lchild = remove(pnode->lchild, key); if (height(pnode->rchild) - height(pnode->lchild) == 2) //删除左子树节点导致不平衡:相当于情况三或情况一 { if (height(pnode->rchild->lchild) > height(pnode->rchild->rchild)) pnode = rightLeftRotation(pnode); else pnode = leftRotation(pnode); } } return pnode; } return nullptr;};template<typename T>void AVLTree<T>::remove(T key) { root = remove(root, key);};/*中序遍历*/template<typename T>void AVLTree<T>::inOrder(AVLTreeNode<T> *pnode) const { if (pnode != nullptr) { inOrder(pnode->lchild); cout << pnode->key << endl; inOrder(pnode->rchild); }};template<typename T>void AVLTree<T>::inOrder() { inOrder(root);};/*前序遍历*/template<typename T>void AVLTree<T>::preOrder(AVLTreeNode<T> *pnode) const { if (pnode != nullptr) { cout << pnode->key << endl; inOrder(pnode->lchild); inOrder(pnode->rchild); }};template<typename T>void AVLTree<T>::preOrder() { preOrder(root);};/*后列遍历*/template<typename T>void AVLTree<T>::postOrder(AVLTreeNode<T> *pnode) const { if (pnode != nullptr) { inOrder(pnode->lchild); inOrder(pnode->rchild); cout << pnode->key << endl; }}template<typename T>void AVLTree<T>::postOrder() { postOrder(root);};/*销毁AVL树*/template<typename T>void AVLTree<T>::destroy(AVLTreeNode<T> *&pnode) { if (pnode != nullptr) { destroy(pnode->lchild); destroy(pnode->rchild); delete pnode; pnode = nullptr; }};template<typename T>void AVLTree<T>::destroy() { destroy(root);}#endif //DATASTRUCTURE_AVLTREE_H
3.main.cpp 测试
#include <iostream>#include "AVLTree/AVLTreeNode.h"#include "AVLTree/AVLTree.h"using namespace std;int main(){ AVLTree<int> a; for(int i=0;i<10;i++) a.insert(i); cout<<"树高:"<<a.height()<<endl; cout<<"中序遍历:"<<endl; a.inOrder(); cout<<"删除元素10"<<endl; a.remove(10); AVLTreeNode<int> * b=a.search_iterator(10); AVLTreeNode<int> * c=a.search_iterator(6); if(b!=nullptr) cout<<b->key; else cout<<"无此元素"<<endl; if(c!=nullptr) cout<<c->key; else cout<<"无此元素"<<endl; a.remove(6); cout<<"中序遍历:"<<endl; a.inOrder(); return 0;}
输出:
树高:4
中序遍历:
0
1
2
3
4
5
6
7
8
9
删除元素10
无此元素
6中序遍历:
0
1
2
3
4
5
7
8
9
阅读全文
0 0
- 数据结构 - 平衡二叉树 AVL
- 数据结构-AVL二叉平衡树
- 数据结构:AVL树(平衡二叉树)
- 数据结构:平衡二叉树(AVL树)
- 【数据结构】平衡二叉树之AVL树
- 数据结构:平衡二叉树(AVL树)
- 数据结构 — AVL树(平衡二叉树)
- 数据结构-平衡搜索二叉树(AVL树)
- 【数据结构重温】平衡二叉树(AVL)
- 数据结构之平衡二叉树AVL
- 数据结构--树论--平衡二叉树(AVL TREE)
- 数据结构-平衡二叉树(AVL Tree)
- 【数据结构基础】平衡二叉树(AVL)
- 数据结构与算法10: 平衡二叉树AVL(AVL Tree)
- AVL 平衡二叉树
- 平衡二叉树(AVL)
- 平衡二叉树(AVL)
- AVL 平衡二叉树
- 使用myeclipse创建maven项目
- JVM性能调优
- ultraedit 使用
- Centos7 设置时区
- SQL 语句:基础
- 数据结构-AVL二叉平衡树
- C 宏的陷阱
- kettle 资源库连接中断解决办法
- NYOJ 90 整数划分(递推||dp)
- SSM+vue+jdk1.8前后端分离解决跨域请求
- java中byte与int相互转化的原理
- CUDA(一) GPU计算性能的相关计算公式
- 日志系列-常见处理方案
- 使用Collections.sort(List<T>,Comparator<T>)给List<String>排序(一)