二叉树系列之一:二叉树
来源:互联网 发布:ubuntu ati显卡驱动 编辑:程序博客网 时间:2024/05/19 20:58
二叉树系列包括二叉树基类、二叉搜索树、红黑树以及AVL树。这里先讨论二叉树基类。
先看BTNode类的定义
template <class T>
struct BTNode
...{
BTNode(T d, COLOR c = RED, BF f = NORMAL, BTNode* l = nil_, BTNode* r = nil_, BTNode* p = nil_)
: data_(d), color_(c), factor_(f), lchild_(l), rchild_(r), parent_(p) ...{}
BTNode *lchild_, *rchild_, *parent_;
int color_, factor_;
T data_;
static BTNode* nil() ...{ return nil_; }
// use singleton pattern
static BTNode* createNil()
...{
if (nil_ == BTNode<T>::nil())
...{
nil_ = new BTNode();
nilify(nil_);
}
return nil_;
}
// nilify the node
static void nilify(BTNode* x = nil_)
...{
x->lchild_ = nil_;
x->rchild_ = nil_;
x->parent_ = nil_;
x->color_ = BLACK;
x->factor_ = NORMAL;
}
static void increment() ...{ refcnt_++; }
static void decrement() ...{ if (--refcnt_ == 0) delete nil_; }
private:
BTNode() : data_(T(0)), color_(RED), factor_(NORMAL), lchild_(0), rchild_(0), parent_(0) ...{}
static BTNode* nil_;
static int refcnt_;
};
struct BTNode
...{
BTNode(T d, COLOR c = RED, BF f = NORMAL, BTNode* l = nil_, BTNode* r = nil_, BTNode* p = nil_)
: data_(d), color_(c), factor_(f), lchild_(l), rchild_(r), parent_(p) ...{}
BTNode *lchild_, *rchild_, *parent_;
int color_, factor_;
T data_;
static BTNode* nil() ...{ return nil_; }
// use singleton pattern
static BTNode* createNil()
...{
if (nil_ == BTNode<T>::nil())
...{
nil_ = new BTNode();
nilify(nil_);
}
return nil_;
}
// nilify the node
static void nilify(BTNode* x = nil_)
...{
x->lchild_ = nil_;
x->rchild_ = nil_;
x->parent_ = nil_;
x->color_ = BLACK;
x->factor_ = NORMAL;
}
static void increment() ...{ refcnt_++; }
static void decrement() ...{ if (--refcnt_ == 0) delete nil_; }
private:
BTNode() : data_(T(0)), color_(RED), factor_(NORMAL), lchild_(0), rchild_(0), parent_(0) ...{}
static BTNode* nil_;
static int refcnt_;
};
这里增加了Nil节点的操作。Nil节点的增加是为了在派生类红黑树中的实现。这些操作包括了该节点的创建,该节点的引用访问以及该节点的删除。引用计数的增加使所有红黑树的叶子节点和根节点都指向了同一个Nil节点,便于红黑树的实现。
在BTree类中,主要包括了有关二叉树的一些基本操作,如二叉树的构造,二叉树的销毁以及二叉树的打印。这里值得一提的是二叉树的打印,它是按照二叉树的树形结构来打印的,看起来比较直观。对于红黑树和AVL树的调试,树形打印提供了很大的方便。
完整的代码为(BTree.h):
#ifndef _BINARY_TREE_H_
#define _BINARY_TREE_H_
#include <queue>
#include <iomanip>
#include <iostream>
using std::setw;
using std::cout;
using std::queue;
using std::ostream;
enum COLOR ...{ RED = 0, BLACK };
enum BF ...{ LOW = -2, LESS, NORMAL, MORE, HIGH };
template <class T>
struct BTNode
...{
BTNode(T d, COLOR c = RED, BF f = NORMAL, BTNode* l = nil_, BTNode* r = nil_, BTNode* p = nil_)
: data_(d), color_(c), factor_(f), lchild_(l), rchild_(r), parent_(p) ...{}
BTNode *lchild_, *rchild_, *parent_;
int color_, factor_;
T data_;
static BTNode* nil() ...{ return nil_; }
// use singleton pattern
static BTNode* createNil()
...{
if (nil_ == BTNode<T>::nil())
...{
nil_ = new BTNode();
nilify(nil_);
}
return nil_;
}
// nilify the node
static void nilify(BTNode* x = nil_)
...{
x->lchild_ = nil_;
x->rchild_ = nil_;
x->parent_ = nil_;
x->color_ = BLACK;
x->factor_ = NORMAL;
}
static void increment() ...{ refcnt_++; }
static void decrement() ...{ if (--refcnt_ == 0) delete nil_; }
private:
BTNode() : data_(T(0)), color_(RED), factor_(NORMAL), lchild_(0), rchild_(0), parent_(0) ...{}
static BTNode* nil_;
static int refcnt_;
};
template <class T> BTNode<T>* BTNode<T>::nil_ = BTNode<T>::nil();
template <class T> int BTNode<T>::refcnt_ = 0;
template <class T>
class BTree
...{
public:
BTree(T data = T())
...{
BTNode<T>::createNil();
BTNode<T>::increment();
root_ = new BTNode<T>(data);
BTNode<T>::nilify(root_);
}
virtual ~BTree() ...{ destroy(root_); BTNode<T>::decrement(); }
int height() const ...{ return height(root_); }
void print(ostream& out) ...{ print(out, root_); }
protected:
BTNode<T>* root_;
private:
int height(BTNode<T>* x) const
...{
if (x == BTNode<T>::nil()) return 0;
int hl = height(x->lchild_);
int hr = height(x->rchild_);
if (hl > hr) return ++hl;
else return ++hr;
}
void destroy(BTNode<T>* x)
...{
if (x != BTNode<T>::nil())
...{
destroy(x->lchild_);
destroy(x->rchild_);
delete x;
}
}
void print(ostream& out, BTNode<T>* p)
...{
queue<BTNode<T>* > node;
int level = 0, h = height(p) - 1;
for ( int i = 1; i < 2<<h; i++)
...{
// specify the print format
if (i == 1<<level) out << endl << setw(2 << (h - level++));
else out << setw(4 << (h - level + 1));
// print the data, '-' for nil node
if (p != BTNode<T>::nil()) out << p->data_;
else out << '-';
// push the left and right child
node.push(p->lchild_); node.push(p->rchild_);
// pop the node to print
p = node.front(); node.pop();
}
}
};
template <class T>
ostream& operator <<(ostream& out, BTree<T>& bt)
...{
bt.print(out);
return out;
}
#endif
#define _BINARY_TREE_H_
#include <queue>
#include <iomanip>
#include <iostream>
using std::setw;
using std::cout;
using std::queue;
using std::ostream;
enum COLOR ...{ RED = 0, BLACK };
enum BF ...{ LOW = -2, LESS, NORMAL, MORE, HIGH };
template <class T>
struct BTNode
...{
BTNode(T d, COLOR c = RED, BF f = NORMAL, BTNode* l = nil_, BTNode* r = nil_, BTNode* p = nil_)
: data_(d), color_(c), factor_(f), lchild_(l), rchild_(r), parent_(p) ...{}
BTNode *lchild_, *rchild_, *parent_;
int color_, factor_;
T data_;
static BTNode* nil() ...{ return nil_; }
// use singleton pattern
static BTNode* createNil()
...{
if (nil_ == BTNode<T>::nil())
...{
nil_ = new BTNode();
nilify(nil_);
}
return nil_;
}
// nilify the node
static void nilify(BTNode* x = nil_)
...{
x->lchild_ = nil_;
x->rchild_ = nil_;
x->parent_ = nil_;
x->color_ = BLACK;
x->factor_ = NORMAL;
}
static void increment() ...{ refcnt_++; }
static void decrement() ...{ if (--refcnt_ == 0) delete nil_; }
private:
BTNode() : data_(T(0)), color_(RED), factor_(NORMAL), lchild_(0), rchild_(0), parent_(0) ...{}
static BTNode* nil_;
static int refcnt_;
};
template <class T> BTNode<T>* BTNode<T>::nil_ = BTNode<T>::nil();
template <class T> int BTNode<T>::refcnt_ = 0;
template <class T>
class BTree
...{
public:
BTree(T data = T())
...{
BTNode<T>::createNil();
BTNode<T>::increment();
root_ = new BTNode<T>(data);
BTNode<T>::nilify(root_);
}
virtual ~BTree() ...{ destroy(root_); BTNode<T>::decrement(); }
int height() const ...{ return height(root_); }
void print(ostream& out) ...{ print(out, root_); }
protected:
BTNode<T>* root_;
private:
int height(BTNode<T>* x) const
...{
if (x == BTNode<T>::nil()) return 0;
int hl = height(x->lchild_);
int hr = height(x->rchild_);
if (hl > hr) return ++hl;
else return ++hr;
}
void destroy(BTNode<T>* x)
...{
if (x != BTNode<T>::nil())
...{
destroy(x->lchild_);
destroy(x->rchild_);
delete x;
}
}
void print(ostream& out, BTNode<T>* p)
...{
queue<BTNode<T>* > node;
int level = 0, h = height(p) - 1;
for ( int i = 1; i < 2<<h; i++)
...{
// specify the print format
if (i == 1<<level) out << endl << setw(2 << (h - level++));
else out << setw(4 << (h - level + 1));
// print the data, '-' for nil node
if (p != BTNode<T>::nil()) out << p->data_;
else out << '-';
// push the left and right child
node.push(p->lchild_); node.push(p->rchild_);
// pop the node to print
p = node.front(); node.pop();
}
}
};
template <class T>
ostream& operator <<(ostream& out, BTree<T>& bt)
...{
bt.print(out);
return out;
}
#endif
- 二叉树系列之一:二叉树
- 二叉树系列文章之一 二叉树的性质
- 树系列之一: 二叉树的性质
- 二叉树系列之一(基本概念)
- 平衡二叉树之一
- 二叉搜索树之一
- 二叉树系列---基础
- 二叉树系列---recover_binary_search_tree
- 二叉树系列---symmetric_tree
- 二叉树系列
- 二叉树相关操作之一
- 二叉树系列---构造二叉查找树
- 二叉树系列---层次遍历二叉树
- 二叉树的用途之一二叉搜索树
- 二叉树系列问题1
- leetcode 二叉树系列搞定
- 【算法系列-4】二叉树
- 二叉树系列---path-sum
- 使用映射文件定制持久化类
- 不怕两千年的孤寂
- 九二共识
- 误ghost后手工修改分区表来恢复数据
- 由邱兴华是否应做精神病司法鉴定想到的
- 二叉树系列之一:二叉树
- 跳槽者的心态
- 匈奴国王阿提拉:令整个欧洲发抖的"上帝之鞭"
- 二叉树系列之二:二叉搜索树
- 日志(2007.01)
- 二叉树系列之三:红黑树
- 二叉树系列之四:AVL树
- 这也不知道是第几次开bk了
- 读 《Windows程序设计》(4)