自建二叉树,及收获的经验
来源:互联网 发布:合并pdf软件 编辑:程序博客网 时间:2024/06/04 18:38
二叉树常用来表示:表达式、文件系统、URL、域名、学院组织、族谱
他们的共同点就是有层次结构
实现:
包含的方法:
插入/删除结点
获取树的基本信息
前序/中序/后序/层次遍历
template<typename value_type>class BinTree {using size_type = unsigned;using calcu_type = int;#ifndef _STACK_#include<stack>#endif // !_STACK_#ifndef _QUEUE_#include<queue>#endif // !_QUEUE_private:class BinNode {public:const bool _voidNode = true;size_type _depth = 0;size_type _size = 1;size_type _height = 0;BinNode* _father = nullptr;BinNode* _leftChild = nullptr;BinNode* _rightChild = nullptr;value_type _value;void _update_size(calcu_type num) {BinNode* now = this->_father;while (now->_father != nullptr) {//非root时now->_size += num;now = now->_father;}now->_size += num;}void _update_height(calcu_type num) {//更新祖先高度BinNode* now = this;BinNode* sib;while (now->_father != nullptr) {//now非rootif (now->_father->_leftChild == now)sib = now->_father->_rightChild;else sib = now->_father->_leftChild;if (now->_height > sib->_height || sib->_voidNode)now->_father->_height += num;now = now->_father;}}void _update_size_and_height(calcu_type num) {_update_size(num);_update_height(num);}public:BinNode(const value_type&val):_value(val), _father(nullptr), _voidNode(false), _size(1){_rightChild = new BinNode();_leftChild = new BinNode();}//rootBinNode(const value_type& val, BinNode* father):_value(val), _father(father), _voidNode(false){_depth = father->_depth + 1;//left voidNode is provided by father_rightChild = new BinNode();}//new childBinNode() {}//voidNode~BinNode() {delete _rightChild;delete _leftChild;}size_type get_height() { return this->_height; }BinNode* insert_left_child(const value_type& val) {BinNode* tmp = new BinNode(val, this);tmp->_leftChild = this->_leftChild;// 传递被替换的空结点this->_leftChild = tmp;this->_leftChild->_update_size_and_height(1);return this->_leftChild;}BinNode* insert_right_child(const value_type& val) {BinNode* tmp = new BinNode(val, this);tmp->_leftChild = this->_rightChild;// 传递被替换的空结点this->_rightChild = tmp;this->_rightChild->_update_size_and_height(1);return this->_rightChild;}};BinNode* root = nullptr;BinNode* _curNode = root;public:BinTree() {}BinTree(const value_type& val) {root = new BinNode(val);_curNode = root;}~BinTree() { delete root; }bool empty() { return root == nullptr; }size_type get_height() { return root->_height; }size_type get_cur_depth() { return _curNode->_depth; }bool is_void_node() { return _curNode->_voidNode; }const value_type& get_cur_value() { return _curNode->_value; }const value_type& insert_as_right_child(const value_type& val) {if (this->empty()) {root = _curNode = new BinNode(val);return val;}else {_curNode = _curNode->insert_right_child(val);return _curNode->_value;}}const value_type& insert_as_left_child(const value_type& val) {if (this->empty()) {root = _curNode = new BinNode(val);return val;}else {_curNode = _curNode->insert_left_child(val);return _curNode->_value;}}template<typename method>void trav_level(method& visit) {if (this->empty())return;BinNode* front = root;std::stack<BinNode*>pointerQueue;pointerQueue.push(front);while (!pointerStack.empty()){front = pointerQueue.pop();visit(front->_value);if (front->_leftChild->_voidNode == false)pointerQueue.push(front->_leftChild);if (front->_rightChild->_voidNode == false)pointerQueue.push(front->_rightChild);}}//层次遍历template<typename method>void trav_pre(method& visit) {if (this->empty())return;BinNode* front = root;std::stack<BinNode*>pointerStack;pointerStack.push(front);while (!pointerStack.empty()){front = pointerStack.pop();visit(front->_value);if (front->_leftChild->_voidNode == false)pointerStack.push(front->_leftChild);if (front->_rightChild->_voidNode == false)pointerStack.push(front->_rightChild);}}//preorder先序遍历template<typename method>void trav_in(method& visit) {if (this->empty())return;BinNode* front = root;std::stack<BinNode*>pointerStack;pointerStack.push(front);while (!pointerStack.empty()){if (front->_leftChild->_voidNode == false)pointerStack.push(front->_leftChild);front = pointerStack.pop();visit(front->_value);if (front->_rightChild->_voidNode == false)pointerStack.push(front->_rightChild);}}//inorder中序遍历template<typename method>void trav_post(method& visit) {if (this->empty())return;BinNode* front = root;std::stack<BinNode*>pointerStack;pointerStack.push(front);while (!pointerStack.empty()){front = pointerStack.pop();visit(front->_value);if (front->_rightChild->_voidNode == false)pointerStack.push(front->_rightChild);if (front->_leftChild->_voidNode == false)pointerStack.push(front->_leftChild);}}//postorder后序遍历value_type& roll_back(size_type times){if (times > _curNode->_depth)return this->back_to_root();else {for (size_type i = 1; i <= times; ++i)_curNode = _curNode->_father;return _curNode->_value;}} //roll back max to root, no excptionvalue_type& back_to_root() {_curNode = root;return _curNode->_value;}value_type& go_to_left_child() {_curNode = _curNode->_leftChild;return _curNode->_value;}value_type& go_to_right_child() {_curNode = _curNode->_rightChild;return _curNode->_value;}void delete_left_tree() {delete _curNode->_leftChild;_cureNode->_leftChild = new BinNode();}void delete_right_tree() {delete _curNode->_leftChild;_cureNode->_rightChild = new BinNode();}};
加入以下代码可用于测试:
class add_note {public:void operator()(std::string& val) {val += " visited!";}}add;int main() {BinTree<std::string>* p;{BinTree<std::string>aTree;p = &aTree;aTree.insert_as_left_child("root");aTree.insert_as_left_child("root's left");aTree.roll_back(1);aTree.insert_as_right_child("root's right");aTree.insert_as_left_child("root's left's left");aTree.trav_level(add);}int a = 0;}
总结:
1.关于 delete
delete 实际是调用对象的析构函数,析构函数结束的瞬间,相当于此对象(this)的堆空间被回收,但析构函数期间可以做其他复杂的操作
2.关于 指针容器
C++容器模板类中保存的是 原对象的复制品(调用拷贝构造函数或移动构造函数)。保存对象指针而不是对象本身,可以节省拷贝构造函数调用次数,建立“管理资源”的容器
3.现版本缺点:
1.不可多线程
2.未处理异常
3.未考虑继承问题
4.未知的栈类坑
阅读全文
0 0
- 自建二叉树,及收获的经验
- 数据结构之自建算法库——二叉树的链式存储及基本运算
- 第十周-自建算法库--二叉树的链式存储及基本运算
- 数据结构之自建算法库——二叉树的链式存储及基本运算
- 完成基于哈夫曼树(最优二叉树)的压缩及解压小程序的收获
- 第九周项目1之自建算法库——二叉树的链式存储及基本运算
- 第九周项目一C/C++数据结构自建算法库—二叉树的链式存储及基本运算
- 今天的问题及收获
- 缺陷经验收获
- 二叉树及特殊的二叉树
- 二叉树及二叉树的应用
- python使用PIL处理图片的一些收获和经验
- 项目:××CEO峰会邮件邀请函页面的经验和收获
- 二叉树的建立及遍历(二叉树)
- 纯C创建二叉树及二叉树的遍历
- 二叉树的遍历及线索二叉树
- 二叉树学习之二叉树的构建及操作
- 二叉树的深度及平衡二叉树40
- python爬取数据
- u-boot回顾(二)
- 回归分析
- Ubuntu下设置静态IP
- H5+CSS3设计动态的首页背景
- 自建二叉树,及收获的经验
- text文本框, textarea文本域 框内提示文字
- 特殊密码锁
- Java HashSet
- 项目导入idea后 项目启动正常 但浏览器404
- hdu 2098
- Java TreeSet
- 虚拟币开发专题(怎样找回因转账0确认而卡住的山寨币)
- 怎样使用CSS设置文字之间的距离?