平衡二叉查找(AVL)树(C++模板实现)
来源:互联网 发布:删除表 sql drop 编辑:程序博客网 时间:2024/06/08 21:55
最近在学习《数据结构与算法分析(C语言描述)》,上面讲到一个带平衡条件的二叉查找树,之前在一家公司笔试也遇到了类似的题,于是决定自己用C++模板实现一遍。
(声明文件)AVL.h :
#ifndef AVL_DEC_H#define AVL_DEC_Htemplate <typename T>class AvlTree;int Max(int a1, int a2){ return a1 > a2 ? a1 : a2;}//节点类模板template<typename T>class Node{public: friend class AvlTree<T>; Node(T x);private: T element; Node<T> *left; Node<T> *right; int height;};//AVL树template <typename T>class AvlTree{public: AvlTree(); ~AvlTree(); void append(T x); static int Height(Node<T>* tree); void print(); void clear();private: void FreeTree(Node<T>* r); Node<T>* append(T x, Node<T>* r); void Add2Array(Node<T>* r, T** a, int* b, int n); Node<T>* SingleRotationWithLeft(Node<T>*); Node<T>* SingleRotationWithRight(Node<T>*); Node<T>* DoubleRotationWithLeft(Node<T>*); Node<T>* DoubleRotationWithRight(Node<T>*);private: Node<T>* root;};#include "AVL_def.h"#endif // !AVL_DEC_H
(实现文件)AVL_def.h :
#ifndef AVL_DEF_H#define AVL_DEF_Htemplate<typename T>Node<T>::Node(T x){ element = x; left = nullptr; right = nullptr; height = 0;}template<typename T>AvlTree<T>::AvlTree(){ root = nullptr;}template<typename T>inline AvlTree<T>::~AvlTree(){ clear();}template<typename T>void AvlTree<T>::append(T x){ //调用另一个重载函数 root = append(x, root);}template <typename T>Node<T>* AvlTree<T>::append(T x, Node<T>* r){ if (r == nullptr) { r = new Node<T>(x); } else if (x < r->element) { //要插入的数比当前节点数小,向左递归 r->left = append(x, r->left); //如果插入操作导致当前节点不平衡 if (Height(r->left) - Height(r->right) == 2) { //在左儿子的左子树插入 if (x < r->left->element) r = SingleRotationWithLeft(r);//进行一次从左向右的单旋转 //在左儿子的右子树插入 else r = DoubleRotationWithLeft(r);//进行一次从左向右的双旋转 } } else if (x > r->element) { //要插入的数比当前节点数大,向右递归 r->right = append(x, r->right); //如果插入操作导致当前节点不平衡 if (Height(r->right) - Height(r->left) == 2) { //在右儿子的右子树插入 if (x > r->right->element) r = SingleRotationWithRight(r);//进行一次从左向右的单旋转 //在右儿子的左子树插入 else r = DoubleRotationWithRight(r);//进行一次从左向右的双旋转 } } r->height = Max(Height(r->left), Height(r->right)) + 1; return r;}//计算树的深度template<typename T>int AvlTree<T>::Height(Node<T> * r){ if (r == nullptr) return -1; else return r->height;}//清除元素template<typename T>void AvlTree<T>::clear(){ FreeTree(root); root = nullptr;}template<typename T>void AvlTree<T>::FreeTree(Node<T>* r){ if (r == nullptr) return; if (r->left == nullptr && r->right == nullptr) delete r; else { FreeTree(r->left); FreeTree(r->right); delete r; }}template<typename T>Node<T>* AvlTree<T>::SingleRotationWithLeft(Node<T>* r){ Node<T>* k1; k1 = r->left; r->left = k1->right; k1->right = r; r->height = Max(Height(r->left), Height(r->right)) + 1; k1->height = Max(Height(k1->left), r->height) + 1; return k1;}template<typename T>Node<T>* AvlTree<T>::SingleRotationWithRight(Node<T>* r){ Node<T>* k1; k1 = r->right; r->right = k1->left; k1->left = r; r->height = Max(Height(r->left), Height(r->right)) + 1; k1->height = Max(Height(k1->right), r->height) + 1; return k1;}template<typename T>Node<T>* AvlTree<T>::DoubleRotationWithLeft(Node<T>* r){ r->left = SingleRotationWithRight(r->left); return SingleRotationWithLeft(r);}template<typename T>Node<T>* AvlTree<T>::DoubleRotationWithRight(Node<T>* r){ r->right = SingleRotationWithLeft(r->right); return SingleRotationWithRight(r);}//将树的所有元素输出到一个二维数组,安全性由调用例程负责template<typename T>void AvlTree<T>::Add2Array(Node<T>* r, T** a, int* b, int n){ if (r == nullptr) return; a[n][b[n]++] = r->element; Add2Array(r->left, a, b, n + 1); Add2Array(r->right, a, b, n + 1);}#endif // !AVL_DEF_H
(测试)main.cpp :
#include <iostream>#include "AVL.h"using namespace std;//打印元素template<typename T>inline void AvlTree<T>::print(){ int n = Height(root) + 1; T** a = new T*[n]; int *b = new int[n]; for (int i = 0; i < n; ++i) { a[i] = new T[pow(2, i)]; b[i] = 0; } Add2Array(root, a, b, 0); for (int i = 0; i < n; ++i) { for (int j = 0; j < n - i - 1; ++j) cout << " "; for (int j = 0; j < b[i]; ++j) { cout << a[i][j] << " "; } cout << endl; } for (int i = 0; i < n; ++i) delete[] a[i]; delete[] a; delete[] b;}int main(){ int a[] = { 1,2,3,4,8,7,12,9,32,45,13,24,17 }; AvlTree<int> avl; for (int i = 0; i < sizeof(a) / sizeof(a[0]); ++i) avl.append(a[i]); avl.print(); system("pause"); return 0;}
阅读全文
0 0
- 平衡二叉查找(AVL)树(C++模板实现)
- AVL平衡二叉查找树实现(C语言版本)
- AVL树(平衡二叉查找树)
- AVL树(平衡二叉查找树)
- AVL树(平衡二叉查找树)
- 平衡二叉查找树(AVL)
- 平衡二叉树(AVL)模板
- 标准C实现的平衡二叉树(AVL)
- 二叉平衡树(绝对平衡)AVL 操作模板
- 平衡二叉查找树 AVL 的实现
- 二叉平衡树(AVL)-C语言
- 平衡二叉树 AVL实现(2)
- 平衡二叉树 AVL 实现(3)
- 平衡二叉树(AVL)的实现
- 平衡二叉查找树(AVL)的查找、插入、删除
- 平衡二叉查找树(AVL)的查找,插入,删除
- 【修改】C实现平衡二叉树---AVL
- C语言实现AVL-平衡二叉树
- opencv学习系列:实例练习,含多个工程实例
- VB6 WinSock控件及WinSockAPI
- 278. First Bad Version
- .Net Core使用Redis的一个入门简单Demo
- Python_正则表达式
- 平衡二叉查找(AVL)树(C++模板实现)
- 雅思作文_教育类(一)
- leetcode 673. Number of Longest Increasing Subsequence 动态规划DP
- JDK1.8发现无法引入javax.servlet包
- Kotlin之接口
- java8特性介绍之-接口函数
- 刚学完java,储存了大量的学习资料,免费分享给大家
- vs 导入命名空间问题
- Redis持久化