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
1 BTnode class template 的构建
主要是对于tree 的节点信息的存储 包括value值 、左右子节点的指针 在将此 Class 进行初始化,其余的就是数据结构里正常的 树节点的insert remove and clear 等操作。
template< typename elemType>
class BinaryTree;
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;
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 ;
}
else {
_lchild-> remove_value ( val, _lchild ) ;
}
}
else if ( val > _val ) {
if ( ! _rchild ) {
return ;
}
else {
_rchild-> remove_value ( val, _rchild ) ;
}
}
else {
if ( _rchild ) {
prev = _rchild;
if ( _lchild ) {
if ( ! prev-> _lchild ) {
prev-> _lchild = _lchild;
}
else {
BTnode< valType> :: lchild_leaf ( _lchild, prev-> _lchild ) ;
}
}
}
else {
prev = _lchild;
}
delete this;
}
}
template< typename valType>
inline void BTnode< valType> ::
lchild_leaf ( BTnode * leaf, BTnode * subtree ) {
while ( subtree-> _lchild ) {
subtree = subtree-> _lchild;
}
subtree-> _lchild = leaf;
}
2 Binary Tree Class template 的构造
对于整体树 的一个class template的构造 其中遇到的一个问题 在进行operator << 的重构时,出现不明问题 待解决 代码部分已进行注释
其余的操作见代码。
template < typename elemType >
class BinaryTree {
public:
BinaryTree ( ) ;
BinaryTree ( const BinaryTree& ) ;
~ BinaryTree ( ) ;
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 ; } }
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;
void clear ( BTnode< elemType> * node ) ;
void copy ( BTnode< elemType> * tar, BTnode< elemType> * src ) ;
} ;
template< typename elemType>
inline BinaryTree< elemType> :: BinaryTree ( ) : _root ( 0 ) { }
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;
}
template< typename elemType>
inline void BinaryTree< elemType> ::
insert ( const elemType & elem ) {
if ( ! _root ) {
_root = new BTnode< elemType> ( elem) ;
}
else {
_root-> insert_value ( elem ) ;
}
}
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;
}
template< typename elemType>
inline void BinaryTree< elemType> ::
clear ( BTnode< elemType> * pt ) {
if ( pt ) {
clear ( pt-> _lchild ) ;
clear ( pt-> _rchild ) ;
delete pt;
}
}
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 ) ;
}
}
}
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 ) ;
}
}
}
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;
}
template< typename elemType>
inline ostream&
operator<< ( ostream & os, BinaryTree< elemType> & bt ) {
os << "\nTree: " << endl;
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了