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了