Essential C++ chapter06 binary tree 的学习笔记记录及问题

  • Author:Dargon
  • Note date:2021/02/28
  • Source: 《Essential C++》 and 《C ++ primer plus》
  • Note: 关于二叉树的构建 插入 移除 和打印 利用C++ template
  • Version: 更改错误 关于输出 << 运算符的问题 2021/03/03

文章目录

  • Essential C++ chapter06 binary tree 的学习笔记记录及问题
    • 1 BTnode class template 的构建
    • 2 Binary Tree Class template 的构造
    • 3 关于class template 的测试
    • 4 记录

1 BTnode class template 的构建

  • 主要是对于tree 的节点信息的存储 包括value值 、左右子节点的指针 在将此 Class 进行初始化,其余的就是数据结构里正常的 树节点的insert remove and clear 等操作。
/************************************************************ @name    Essential C++ 6th chapter* @brief   BTnode class 的声明区域* @date    2021/02/26
*********************************************************/
template<typename elemType>
class BinaryTree; /* forward declaration */template < typename valType >
class BTnode {friend class BinaryTree<valType>; /* 声明友元函数 需要在前面进行声明 */public:BTnode() {}BTnode( const valType &val );void insert_value( const valType& val );void remove_value( const valType &val, BTnode *& prev );static void lchild_leaf( BTnode *leaf, BTnode *subtree );private:valType _val; /* node 所存储的具体信息 值 */int _cnt; /* 记录重复次数 */BTnode *_lchild; /* 左右子节点 */BTnode *_rchild;};template<typename valType>
inline BTnode<valType>::
BTnode( const valType &val ) : _val(val) {_cnt =1;_lchild =_rchild =0;
}template<typename valType>
void BTnode<valType>::
insert_value( const valType& val ) {if( val ==_val ) {_cnt++;return;}if( val <_val ) {if( ! _lchild ) {_lchild =new BTnode( val );}else {_lchild->insert_value( val );}}else {if( ! _rchild ) {_rchild =new BTnode( val );}else {_rchild->insert_value( val );}}
}template<typename valType>
void BTnode<valType>::
remove_value( const valType &val, BTnode * & prev ) { /* 这个 “* & ” 是有点东西的 */if( val <_val ) {if( ! _lchild ) {return; /* 不在此 binary tree 中 */}else {_lchild->remove_value( val, _lchild ); /* 进行递归的 remove */}}else if( val >_val ) {if( ! _rchild ) {return;}else {_rchild->remove_value( val, _rchild );}}else {/* 找到需要删除的value */if( _rchild ) { /* 利用 右子树 进行 取代移除点的位置 */prev =_rchild;if( _lchild ) { /* 原来节点的左子树 */if( ! prev->_lchild ) {prev->_lchild =_lchild;}else {BTnode<valType>::lchild_leaf( _lchild, prev->_lchild );}}}else { /* remove节点 没有右子树 直接上左子树 */prev =_lchild; }delete this; }}template<typename valType>
inline void BTnode<valType>::
lchild_leaf( BTnode *leaf, BTnode *subtree ) {while( subtree->_lchild ) {/* 找左子树的 叶节点(最小值) */subtree =subtree->_lchild;}/* 将此 leaf 接在 左边最后面 */subtree->_lchild =leaf;
}

2 Binary Tree Class template 的构造

  • 对于整体树 的一个class template的构造 其中遇到的一个问题 在进行operator << 的重构时,出现不明问题 待解决 代码部分已进行注释 其余的操作见代码。
/************************************************************ @name    Essential C++ 6th chapter* @brief   BinaryTree class 的声明区域* @date    2021/02/26
*********************************************************/template < typename elemType >
class BinaryTree {public:/*  这句没有按照书上的写友元函数  *///friend ostream& operator<<( ostream &, const BinaryTree<elemType>& );/* constructor */BinaryTree();BinaryTree( const BinaryTree& );/* destructor */~BinaryTree();/* operator = */BinaryTree& operator=( const BinaryTree& );void insert( const elemType& );void remove( const elemType& elem );void remove_root();bool empty() { return _root ==0; }void clear() { if( _root ) { clear( _root ); _root =0;} } /* 对应下面自己家的clear */void preorder(); void pre_recursion( BTnode<elemType> *node ); /* 所使用的输出 */void inorder();void in_recursion( BTnode<elemType> *node );void postorder();void post_recursion( BTnode<elemType> *node );void preorder( BTnode<elemType> *node, ostream &os =cout );        static ostream & display_val( elemType &nodevalue, ostream &os =cout );        BTnode<elemType> * get_root() { return _root; }ostream& print( ostream &os =cout );private:BTnode<elemType> *_root; /* 只声明一个 指向BTnode 型的指针 */void clear( BTnode<elemType> *node );/* copy operator */void copy( BTnode<elemType> *tar, BTnode<elemType> *src );};/* default constructor */
template<typename elemType>
inline BinaryTree<elemType>::BinaryTree() : _root(0) {}/* copy constructor */
template<typename elemType>
inline BinaryTree<elemType>::BinaryTree( const BinaryTree &rhs ) {copy( _root, rhs._root );
}template<typename elemType>
inline BinaryTree<elemType>::~BinaryTree() {clear();
}template<typename elemType>
inline BinaryTree<elemType> &BinaryTree<elemType>:: /* 相当于 返回类型 */
operator=( const BinaryTree &rhs ) {if( this != &rhs ) {clear();copy( _root, rhs._root );}return *this;
}/* insert */
template<typename elemType>
inline void BinaryTree<elemType>::
insert( const elemType &elem ) {if( ! _root ) {_root =new BTnode<elemType> (elem);}else {_root->insert_value( elem ); /* 还未初始化 */}
}/* remove */
template<typename elemType>
inline void BinaryTree<elemType>::
remove( const elemType &elem ) {if( _root ) {if( _root->_val ==elem ) {remove_root(); /* 对于根节点的操作 特殊处理 */}else {_root->remove_value( elem, _root ); /* 正常情况的处理 */}}
}template<typename elemType>
inline void BinaryTree<elemType>::
remove_root() {if( ! _root ) return;BTnode<elemType> *tmp =_root;/* 从右子树 下手 */if( _root->_rchild ) {_root =_root->_rchild; /* 右子树 取代根 的位置 *//* 下面只需要将根 的 左子树部分 搬移到 右子节点 左子树的底部 即可 */if( tmp->_lchild ) {BTnode<elemType> *lc =tmp->_lchild;     /* 原来根的 左子树 */BTnode<elemType> *newlc =_root->_lchild;/* 现在根的 左子树 */if( ! newlc ) { /* 没有 直接接上 */_root->_lchild =lc; }else {/* 有的话 找到左子树的 底部 接到下面就可以 */BTnode<elemType>::lchild_leaf( lc, newlc );}}}/* 直接 左子树 接上 */else {_root =_root->_lchild;}delete tmp; /* delete root node */
}/* clear */
template<typename elemType>
inline void BinaryTree<elemType>::
clear( BTnode<elemType> *pt ) {if( pt ) {clear( pt->_lchild );clear( pt->_rchild );delete pt;}
}/* preorder */
template<typename elemType>
inline void BinaryTree<elemType>::
preorder() {pre_recursion( _root );
}template<typename elemType>
inline void BinaryTree<elemType>::
pre_recursion( BTnode<elemType> *node ) {if( node ) {std::cout << node->_val << " ";if( node->_lchild ) {pre_recursion( node->_lchild );}if( node->_rchild ) {pre_recursion( node->_rchild );}}
}/* inorder */
template<typename elemType>
inline void BinaryTree<elemType>::
inorder() {in_recursion( _root );
}template<typename elemType>
inline void BinaryTree<elemType>::
in_recursion( BTnode<elemType> *node ) {if( node ) {std::cout << node->_val << " ";if( node->_lchild ) {in_recursion( node->_lchild );}if( node->_rchild ) {in_recursion( node->_rchild );}}
}/* postorder */
template<typename elemType>
inline void BinaryTree<elemType>::
postorder() {post_recursion( _root );
}template<typename elemType>
inline void BinaryTree<elemType>::
post_recursion( BTnode<elemType> *node ) {if( node ) {std::cout << node->_val << " ";if( node->_lchild ) {post_recursion( node->_lchild );}if( node->_rchild ) {post_recursion( node->_rchild );}}
}/* 未使用的遍历方法 */
template<typename elemType>
inline void BinaryTree<elemType>::
preorder( BTnode<elemType> *node, ostream &os ) {if( node ) {display_val( node->_val, os );preorder( node->_lchild, os );preorder( node->_rchild, os );}
}template<typename elemType>
ostream & BinaryTree<elemType>::
display_val( elemType &nodevalue, ostream &os ) {os << nodevalue << ' ';return os;
}template<typename elemType>
ostream & BinaryTree<elemType>::
print( ostream &os ) {preorder( _root, os );return os;
}/* 关乎 输出运算符问题 此处更改错误 */
/* 把参数的 const 类型声明去掉 原因 是在调用时候 你所定义的函数就是 non-const类型 所以输出也要一样 */
template<typename elemType>
inline ostream&
operator<<( ostream &os, BinaryTree<elemType> &bt ) {os << "\nTree: " << endl;//return bt.print(os);return os;
}

3 关于class template 的测试

  • 此处打印 树 使用 前序遍历preorder 进行显示 “<<" 操作符未使用
int exercise_06_01() {BinaryTree<string> bt;bt.insert( "Piglet" );bt.insert( "Eeyore" );bt.insert( "Roo" );bt.insert( "Tigger" );bt.insert( "Chris" );bt.insert( "Pooh" );bt.insert( "Kanga" );cout << "Preorder tracersal: \n";bt.preorder();bt.remove( "Piglet" );cout << "\n\nPreorder traversal after Piglet remove: \n";bt.preorder();bt.remove( "Eeyore" );bt.insert( "Piglet" );cout << "\n\nPreorder traversal after Eeyore remove: \n";bt.preorder();BinaryTree<string> bt;cout << bt << endl;return RUN_TEST_OK;
}程序的输出测试:
Preorder tracersal:
Piglet Eeyore Chris Kanga Roo Pooh Tigger Preorder traversal after Piglet remove:
Roo Pooh Eeyore Chris Kanga Tigger        Preorder traversal after Eeyore remove:
Roo Pooh Kanga Chris Piglet Tigger
Tree:
Roo Pooh Kanga Chris Piglet Tigger"I'm fine, Dargon !"按任意键关闭终端。

4 记录

  • 初学习 C++ ,把Essential C++ 学习结束,应该不太适合没有任何语言接触的同学学习,之前有C的基础 但是对于作者 想在漫不经意中所传达的知识,自己肯定有很多没有get 到的。其实 对于语言这种东西 还得老老实实的学习 不要相信多少多少天完成 都是扯淡 。学习嘛! 沉甸甸的 踏实 好些。 对于新接触的一门语言来说 重要的是你要按照它的语法来描述同一样的东西 这点是很重要的,其实远远没有到使用逻辑技巧去解决一些实用性的问题 暂且 把这称作基础吧!
  • 隔几天 突然找到问题所在 特此回来更改 一天天的 净写BUG了

EssentialC++_chapter06 binary tree 的学习笔记记录及问题相关推荐

  1. Activiti 学习笔记记录(2016-8-31)

    上一篇:Activiti 学习笔记记录(二) 导读:上一篇学习了bpmn 画图的常用图形标记.那如何用它们组成一个可用文件呢? 我们知道 bpmn 其实是一个xml 文件 转载于:https://ww ...

  2. 关于NB-IOT模块链接阿里物联网平台的学习笔记-记录

    关于NB-IOT模块链接阿里物联网平台思路的学习笔记-记录 叙述 调试思路总结 调试过程 AT命令-方式一 AT命令-方式二 AT命令-方式三 软件 关于遇到问题 总结 叙述 前一段是写了一篇&quo ...

  3. sql个人学习笔记记录

    sql个人学习笔记记录 一: MySQL命令和语句挺多,全部记忆下来不现实,况且有不常用的指令.下面把大部分的指令做了记录和详细的注释. -- 启动MySQLnet start mysql -- 创建 ...

  4. 005-PS基础学习笔记记录-持续更新

    admin@admindembp 001-基础学习笔记 % tree -N -L 1 . ├── 000-Adobe全套系列-破解软件下载.md ├── 001-平面设计接单地址.md ├── 002 ...

  5. OSPF学习笔记记录

    前言: 本次笔记我们主要通过俩条线来贯穿OSPF协议,第一条为工作过程:第二条为LSA. 基本概念: IETF提出了基于SPF算法的链路状态路由协议OSPF ( Open Shortest Path ...

  6. 设备树(device tree)学习笔记

    1.反编译设备树 在设备树学习的时候,如果可以看到最终生成的设备树的内容,对于我们学习设备树以及分析问题有很大帮助.这里我们需要使用设备树生成工具dtc的反编译功能 root@pengdl-Virtu ...

  7. 01postman学习笔记记录

    系列文章目录 文章目录 系列文章目录 前言 一.postman是什么? 二. 接口是什么? 三. 接口测试和接口测试的目的 1.什么是接口测试 2.为什么要进行接口测试 3.接口测试重点 4.接口测试 ...

  8. 嵌入式学习笔记-记录系统启动次数

    在实际应用的过程中,我偶尔会用到计算开发板的启动次数,最笨的方法将所有log保存,最后就是查看log,数一下启动次数,可以通过查找关键字的方式(当然,我不会笨到启动一次记录一次的,嘿嘿).感觉这样太麻 ...

  9. 进程通信学习笔记(记录上锁)

    Posix fcntl记录上锁 记录上锁的Posix接口是fcntl函数 #include <fcntl.h> int fcntl(int fd, int cmd, .../* struc ...

最新文章

  1. 第十五届全国大学生智能汽车竞赛 人工智能创意组总决赛
  2. Chrome 开发工具之Network
  3. JAVA多线程中wait()方法的详细分析
  4. 近似装箱问题(两种脱机算法实现)
  5. java单例模式的实现方法_JAVA单例模式的几种实现方法
  6. VS编译时自动引用Debug|Release版本的dll
  7. Python爬虫的学习入门
  8. workbench字符匹配错误_猪憨憨刷题笔记-LeetCode-10 正则表达式匹配
  9. Kelihos荣升恶意软件之王
  10. IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。
  11. 语音识别平台_语音识别 平台_微信语音识别开放平台 - 云+社区 - 腾讯云
  12. win10系统怎么恢复出厂设置,电脑重置win10系统
  13. 唯品会web前端实习生一面二面经
  14. 简述基于JavaEE企业级开发技术(Spring)(1)
  15. A Weakly Supervised Convolutional Network for Change Segmentation and Classification
  16. Win10 64位 hosts文件的默认内容
  17. java 微信转账 ca_error_对接微信红包时:CA证书出错,请登录微信支付商户平台下载证书...
  18. 数据库系统概念原书第六版黑皮书第一章课后习题作业答案
  19. bugly怎么读_使用指南
  20. Java8集合过滤操作

热门文章

  1. 星舆科技高精度“定位+地图”,赋能智能网联汽车发展
  2. Android开发之WIFI与网络连接处理
  3. Qt example 之 简易字典
  4. Upgrading to MySQL 5.7---focusing on temporal types
  5. 华纳云:PaaS、IaaS、SaaS、Bass、Fass、无服务的理解与区别
  6. etcher恢复正常_我们不会恢复正常; 我们会发现正常
  7. 19种常见的二极管应用电路
  8. 5G工业互联网应用(1)——闭环控制
  9. 新手运营适合哪个跨境电商平台
  10. 用计算机制作汽车碰撞,国内外汽车碰撞计算机模拟研究的现状和趋势.pdf