博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Size Balanced Tree(SBT) 类模板C++实现(持续更新)
阅读量:2443 次
发布时间:2019-05-10

本文共 11508 字,大约阅读时间需要 38 分钟。

       Size Balanced Tree是OI神犇陈启峰发明的,据说是目前最高效的二叉查找树,搞了好长时间终于弄出来了~这个版本的SBT本来是打算用来实现STL的set的,所以树中不存在两个键值一样的元素,当然改成multiset那样的也不是很麻烦~原本按自己的理解想设计自底向上调整的SBT,结果最后发现这样的SBT有很大的问题最简单的例子就是如果插入的数据是单调有序的,那么显然这棵SBT就会严重倾向一侧,所以必须是自顶向下调整~这次写SBT模板收获很大^_^~大家要是发现bug请留言哈~

被虐。。。重写+debug。。。

// =============================================================================// //       Filename:  size_balanced_tree.h// //    Description:  Size Balanced Tree// //        Version:  1.1//        Created:  03/29/2012 01:00:29 PM//       Revision:  none//       Compiler:  g++// //         Author:  SphinX (Whisper), topcodersphinx@gmail.com//        Company:  HFUT// // =============================================================================#ifndef SIZE_BALANCED_TREE#define SIZE_BALANCED_TREE#include 
#include
#include "dsexceptions.h"using std::cout;using std::endl;template
class SizeBalancedTree{ private: struct SizeBalancedNode { T element; SizeBalancedNode * left; SizeBalancedNode * right; int node_size; SizeBalancedNode(const T & _element, SizeBalancedNode * lt, SizeBalancedNode * rt, int sz = 1) : element(_element), left(lt), right(rt), node_size(sz) {} }; public: SizeBalancedTree() { root = NULL; tree_size = 0; } SizeBalancedTree(SizeBalancedTree & rhs) { this->root = clone(rhs.root); this->tree_size = rhs.size(); } ~SizeBalancedTree() { clear(); } const SizeBalancedTree & operator = (const SizeBalancedTree & rhs) { if (this != &rhs) { this->clear(); this->root = clone(rhs.root); this->tree_size = rhs.tree_size; } return (*this); } int size() const { return tree_size; } bool empty() const { return size() == 0; } bool contains(const T & x) const { return contains(x, root); } const T & findMin() const { if (empty()) { throw UnderflowException(); } return findMin(root)->element; } const T & findMax() const { if (empty()) { throw UnderflowException(); } return findMax(root)->element; } int rank(const T & x) const { if (!contains(x)) { return -1; } return rank(x, root); } const T & select(int _rank) const { if (_rank < 0) { throw UnderflowException(); } if (_rank >= size()) { throw OverflowException(); } return select(_rank, root)->element; } void showTree() const { showTree(root); return ; } void clear() { clear(root); tree_size = 0; return ; } void insert(const T & x) { if (contains(x)) { return ; } ++tree_size; insert(x, root); return ; } void remove(const T & x) { if (!contains(x)) { return ; } --tree_size; remove(x, root); return ; } private: SizeBalancedNode * root; int tree_size; int getNodeSize(SizeBalancedNode * t) const { if (NULL == t) { return 0; } return t->node_size; } bool contains(const T & x, SizeBalancedNode * t) const { while (t != NULL) { if (x < t->element) { t = t->left; } else if (t->element < x) { t = t->right; } else { return true; } } return false; } SizeBalancedNode * clone(SizeBalancedNode * t) const { if (NULL == t) { return NULL; } return new SizeBalancedNode(t->element, clone(t->left), clone(t->right)); } SizeBalancedNode * findMin(SizeBalancedNode * t) const { if (t != NULL) { while (t->left != NULL) { t = t->left; } } return t; } SizeBalancedNode * findMax(SizeBalancedNode * t) const { if (t != NULL) { while (t->right != NULL) { t = t->right; } } return t; } int rank(const T & x, SizeBalancedNode * t) const { int _rank = 0; while (t != NULL) { if (x < t->element) { t = t->left; } else if (t->element < x) { _rank += getNodeSize(t->left) + 1; t = t->right; } else { _rank += getNodeSize(t->left); break ; } } return _rank; } SizeBalancedNode * select(int _rank, SizeBalancedNode * t) const { while (t != NULL) { if (_rank < getNodeSize(t->left)) { t = t->left; } else if (getNodeSize(t->left) < _rank) { _rank -= getNodeSize(t->left) + 1; t = t->right; } else { break ; } } return t; } void showTree(SizeBalancedNode * t) const { if (t != NULL) { cout << "The element of this Node is " << t->element << endl; if (t->left != NULL) { cout << "Walk into left child!" << endl; showTree(t->left); cout << "Walk back!" << endl; } cout << "The element of this Node is " << t->element << endl; if (t->right != NULL) { cout << "Walk into right child!" << endl; showTree(t->right); cout << "Walk back!" << endl; } } return ; } void clear(SizeBalancedNode * & t) { if (t != NULL) { clear(t->left); clear(t->right); delete t; t = NULL; } return ; } void rotateWithLeft(SizeBalancedNode * & k2) { SizeBalancedNode * k1 = k2->left; k2->left = k1->right; k1->right = k2; k1->node_size = getNodeSize(k2); k2->node_size = getNodeSize(k2->left) + getNodeSize(k2->right) + 1; k2 = k1; return ; } void rotateWithRight(SizeBalancedNode * & k2) { SizeBalancedNode * k1 = k2->right; k2->right = k1->left; k1->left = k2; k1->node_size = getNodeSize(k2); k2->node_size = getNodeSize(k2->left) + getNodeSize(k2->right) + 1; k2 = k1; return ; } void doubleWithLeft(SizeBalancedNode * & t) { rotateWithRight(t->left); rotateWithLeft(t); return ; } void doubleWithRight(SizeBalancedNode * & t) { rotateWithLeft(t->right); rotateWithRight(t); return ; } void maintain(SizeBalancedNode * & t) //Need to optimize... { if (t->left != NULL) { if (getNodeSize(t->right) < getNodeSize(t->left->left)) { rotateWithLeft(t); } else if (getNodeSize(t->right) < getNodeSize(t->left->right)) { doubleWithLeft(t); } } if (t->right != NULL) { if (getNodeSize(t->left) < getNodeSize(t->right->right)) { rotateWithRight(t); } else if (getNodeSize(t->left) < getNodeSize(t->right->left)) { doubleWithRight(t); } } if (t->left != NULL) { maintain(t->left); } if (t->right != NULL) { maintain(t->right); } return ; } void simpleInsert(const T & x, SizeBalancedNode * & t) { if (NULL == t) { t = new SizeBalancedNode(x, NULL, NULL); return ; } ++t->node_size; if (x < t->element) { simpleInsert(x, t->left); } else if (t->element < x) { simpleInsert(x, t->right); } return ; } void insert(const T & x, SizeBalancedNode * & t) { if (NULL == t) { t = new SizeBalancedNode(x, NULL, NULL); return ; } ++t->node_size; if (x < t->element) { simpleInsert(x, t->left); } else if (t->element < x) { simpleInsert(x, t->right); } else { return ; } maintain(t); return ; } void remove(const T & x, SizeBalancedNode * & t) { if (NULL == t) { return ; } --t->node_size; if (x < t->element) { remove(x, t->left); } else if (t->element < x) { remove(x, t->right); } else { if (t->left != NULL && t->right != NULL) { if (getNodeSize(t->left) < getNodeSize(t->right)) { t->element = findMin(t->right)->element; remove(t->element, t->right); } else { t->element = findMax(t->left)->element; remove(t->element, t->left); } } else { SizeBalancedNode * oldNode = t; t = ((t->left != NULL) ? t->left : t->right); delete oldNode; oldNode = NULL; } } return ; }};/* *template
*const typename SizeBalancedTree
::SizeBalancedNode * SizeBalancedTree
::nil * = new SizeBalancedTree
::SizeBalancedNode(T(), NULL, NULL, 0); */#endif

转载地址:http://gibqb.baihongyu.com/

你可能感兴趣的文章
Oracle与SQL Server在企业应用中的比较(转)
查看>>
Unix类操作系统入门(转)
查看>>
让FreeBSD使用ntpd同步时间(转)
查看>>
用cat命令查看文件内的特殊字符(转)
查看>>
debian sid下vmware不能运行一则(转)
查看>>
Linux操作系统套接字编程的5个隐患(转)
查看>>
Ubuntu Linux:定制Ubuntu安装CD(转)
查看>>
调查显示:企业级Linux用户不断攀升(转)
查看>>
Ubuntu/Linux入门介绍-dpkg(转)
查看>>
SCO UNIX学习宝典 高级进阶(转)
查看>>
Oracle9i RAC for RedFlag Linux DC4.1 32bit 安装流程(转)
查看>>
Sybase和Oracle安装过程中常遇到的问题(转)
查看>>
红帽Linux新系统整合虚拟技术 实现简易操作(转)
查看>>
Linux下/etc/default/boot文件字段说明(转)
查看>>
Linux壁纸系列三十四(转)
查看>>
使用带有Dtrace的FreeBSD(转)
查看>>
Fedora Core 4硬盘安装方法(转)
查看>>
常用的系统状态查询命令(转)
查看>>
『推荐』上G的linux视频教程和电子书FTP下载,速度快内容实用!(转)
查看>>
AIX系统日常管理(转)
查看>>