为二叉树实现一个完整的C++模板类。要求:包含构造函数、复制构造函数和析构函数,实现四个遍历及前向迭代
http://blog.csdn.net/apaolove/article/details/1866204
#include<iostream>
#include<deque>
using namespace std;
//binary node with parent node
template<typename T>
class node
{
public:
node(const T &v, node<T> *L=NULL, node<T> *R=NULL, node<T> *P=NULL):left(L),right(R),par(P)
{
value = v;
}
public:
T value;
node<T> *left, *right, *par;
};
// binary tree
template<typename T>
class BTree
{
public:
BTree(node<T> *R=NULL):root(R)
{ }
~BTree()
{
if(root)
delall();
}
node<T> *findby(const T &v); // 层次遍历,返回找到第一个结点值为v的结点指针
void Insert(const T &v); // 层次遍历二叉树,将值插在遇到的第一个叶子或者子树不全的结点上
bool delby(const T &v); // 层次遍历二叉树,删除遇到的第一个结点值为v的结点
node<T> *findleave(node<T> *cur); // 层次遍历二叉树,返回cur下遇到的第一个叶子结点
void delall();
void display(node<T> *r); // 先序遍历,打印二叉树各结点的值
public:
node<T> *root;
};
template<typename T>
node<T> *BTree<T>::findby(const T &v)
{
deque< node<T>* > Q;
bool isfind; // find v ==> isfind = true; not find ==> isfind = false
node<T> *tmp;
if(root)
Q.push_back(root);
else
{
return NULL;
}
isfind = false;
tmp = NULL;
while(!Q.empty() && !isfind)
{
tmp = Q.front();
Q.pop_front();
if(tmp->value == v)
isfind = true;
else
{
if(tmp->left)
Q.push_back(tmp->left);
if(tmp->right)
Q.push_back(tmp->right);
}
}
if(!isfind)
tmp = NULL;
return tmp;
}
template<typename T>
void BTree<T>::Insert(const T &v)
{
deque< node<T>* > Q;
node<T> *cur;
if(root)
Q.push_back(root);
else
{
root = new node<T>(v, NULL, NULL, NULL);
return;
}
while(!Q.empty()) // 原来是这里出错了.第一次是写了Q.empty(),应该是!Q.empty()
{
cur = Q.front();
Q.pop_front();
if(cur->left)
Q.push_back(cur->left);
else
{
cur->left = new node<T>(v, NULL, NULL, cur);
return;
}
if(cur->right)
Q.push_back(cur->right);
else
{
cur->right = new node<T>(v, NULL, NULL, cur);
return;
}
}
}
template<typename T>
bool BTree<T>::delby(const T &v)
{
node<T> *cur, *tmp;
bool isleave; // 判断是不是叶子结点
isleave = false;
cur = NULL;
cur = findby(v);
if(!cur) // 说明不存在结点值为v的结点
return false;
else
{
if(cur->left && cur->right) // 左右子树不为空
{
tmp = findleave(cur); // 通过层次遍历,找出cur下第一个叶子结点
tmp->left = cur->left;
tmp->right = cur->right;
// 改变左右子树的父结点,不过要判断cur是否为根结点
if(cur->left)
cur->left->par = tmp;
if(cur->right)
cur->right->par = tmp;
}
else if(cur->left) // 右子树为空
tmp = cur->left;
else if(cur->right) // 左子树为空
tmp = cur->right;
else // 左右子树皆为空,说明要删除的是叶子结点
{
(cur == cur->par->left) ? (cur->par->left = NULL) :(cur->par->right = NULL);
isleave = true;
}
if(!isleave)
{
tmp->par = cur->par;
if(cur->par)
(cur == cur->par->left) ? (cur->par->left = tmp) :(cur->par->right = tmp);
if(root == cur)
{
root = tmp;
root->par = NULL;
}
}
}
delete cur;
return true;
}
// 层次遍历二叉树,返回遇到的第一个叶子.二叉树的叶子特征:左右子树为NULL
template<typename T>
node<T> *BTree<T>::findleave(node<T> *cur)
{
deque< node<T>* > Q; // 用于层次遍历的双端队列
node<T> *tmp; // 返回的叶子指针
bool isfind; // 用来跳出while循环的flag
if(!cur) // 假如cur为空,则返回NULL
return NULL;
else
Q.push_back(cur); // 推进Q中
isfind = false;
while(!Q.empty() && !isfind) // 当队列为空或者找到叶子时终止循环
{
tmp = Q.front();
Q.pop_front();
if(!tmp->left && !tmp->right)
isfind = true;
else if(tmp->left)
Q.push_back(tmp->left);
else
Q.push_back(tmp->right);
}
// 处理该叶子的父结点
if(tmp->par)
(tmp == tmp->par->left) ? (tmp->par->left = NULL) : (tmp->par->right = NULL);
return tmp;
}
// 通过层次遍历删除二叉树所有结点
template<typename T>
void BTree<T>::delall()
{
deque< node<T>* > Q;
// 假如root为空,则直接返回,不为空,则推进Q中
if(root)
Q.push_back(root);
else
return ;
while(!Q.empty())
{
root = Q.front();
Q.pop_front();
if(root->left)
Q.push_back(root->left);
if(root->right)
Q.push_back(root->right);
delete root;
root = NULL;
}
}
// 通过前序遍历打印二叉树各结点的值
template<typename T>
void BTree<T>::display(node<T> *r)
{
if(r)
{
cout << r->value << ' ';
display(r->left);
display(r->right);
}
}
int main(void)
{
BTree<int> BT;
int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for(int it = 0; it < sizeof(a) / sizeof(a[0]); it++)
BT.Insert(a[it]); // 第一次测试,Insert不成功,Insert 已修正
BT.display(BT.root);
cout << endl;
BT.delby(1);
BT.delby(3);
BT.delby(6);
BT.delby(2);
BT.delby(8);
BT.display(BT.root);
cout << endl;
BT.delall();
BT.display(BT.root);
return 0;
}
http://www.oschina.net/code/snippet_230828_10246
C++二叉树模板类
#ifndef __BINARY_TREE_H__
#define __BINARY_TREE_H__
#include<string>
#include<vector>
#include<set>
#include<map>
#include<algorithm>
#include<cmath>
using namespace std;
template<class Elem>
class BinaryTree
{
protected:
typedef struct Node
{
public:
Node(){ left = right = parent =-1;}
Elem element;
unsigned int left;
unsigned int right;
unsigned int parent;
}Node;
std::vector<Node> data;
virtual unsigned int Depth(unsigned int index)const
{
if(index < data.size()){
unsigned int l,r,ld = 0,rd = 0;
l = data[index].left;
r = data[index].right;
if(l < data.size()){
ld = Depth(l);
}
if(r < data.size()){
rd = Depth(r);
}
return ld > rd ? (ld+1) : (rd+1);
}
return 0;
}
public:
typedef enum ChildEnum
{
Left=0,Right=1,None=-1,
}ChildEnum;
protected:
virtual void MarkChildren(unsigned int index,vector<unsigned int>& marks)
{
if(index < data.size()){
marks.push_back(index);
if(data[index].left < data.size()){
MarkChildren(data[index].left,marks);
}
if(data[index].right < data.size()){
MarkChildren(data[index].right,marks);
}
}
}
public :
//typedef typename Elem Elem;
BinaryTree<Elem>(){}
BinaryTree<Elem>(const BinaryTree<Elem>& T)
{
data.insert(T.data.begin(),T.data.end());
}
BinaryTree<Elem>(const Elem& value,unsigned int totalNo)
{
if(totalNo >0 ){
unsigned int depth = (unsigned int)(log((double)(totalNo+1))/log(2.0));
Root(value);
if(depth > 1){
vector<unsigned int> leafs;
unsigned int u= depth,i;
while(u > 0){
if(data.size() == totalNo){
break;
}
leafs.clear();
MarkLeaf(leafs);
for(i = 0; i < leafs.size(); ++i){
if(data.size() < totalNo){
InsertChild(leafs[i],Left,value);
}else{
break;
}
if(data.size() < totalNo){
InsertChild(leafs[i],Right,value);
}else{
break;
}
}
u--;
}
}
}
//(totalNo+1)
}
BinaryTree<Elem>(const Elem& value,unsigned int depth,unsigned int leafNo)
{
vector<unsigned int> leafs;
unsigned int i,j,other;
Root(value);
for(i = 1 ; i < depth-1; i++){
MarkLeaf(leafs);
for(j = 0; j < leafs.size(); ++j){
InsertChild(leafs[j],Left,value);
InsertChild(leafs[j],Right,value);
}
leafs.clear();
}
MarkLeaf(leafs);
other = leafNo - leafs.size();
for(j = 0 ; j < other; j++ ){
InsertChild(leafs[j],Left,value);
InsertChild(leafs[j],Right,value);
}
for(j = other ; j < leafs.size(); j++ ){
InsertChild(leafs[j],Left,value);
}
}
virtual bool IsEmpty(void)const{return data.empty();}
virtual unsigned int Depth(void) const
{
if(data.size()>0){
unsigned int l,r,ld = 0,rd = 0;
l = data[0].left;
r = data[0].right;
if(l < data.size()){
ld = Depth(l);
}
if(r < data.size()){
rd = Depth(r);
}
return ld > rd ? (ld+1) : (rd+1);
}else{
return 0;
}
}
virtual void Assign(unsigned int index,const Elem& value)
{
if(index < data.size()){
data[index].element = value;
}else if(index == data.size()){
Node node = Node();
node.element = value;
data.push_back(node);
}
}
virtual void Root(const Elem& value)
{
Clear();
Node node = Node();
node.element = value;
data.push_back(node);
}
virtual Elem* Root(void)
{
if(data.size() >0)
return &(data[0].element);
return NULL;
}
virtual Elem* Value(unsigned int index)
{
if(index < data.size())
return &(data[index].element);
return NULL;
}
virtual Elem* Parent(unsigned int index)
{
if(index >= data.size())
return NULL;
unsigned int p = data[index].parent;
if(p < data.size())
return &(data[p].element);
return NULL;
}
virtual Elem* LeftChild(unsigned int index)
{
if(index >= data.size())
return NULL;
unsigned int l = data[index].left;
if(l < data.size())
return &(data[l].element);
return NULL;
}
virtual Elem* RightChild(unsigned int index)
{
if(index >= data.size())
return NULL;
unsigned int r = data[index].right;
if(r < data.size())
return &(data[r].element);
return NULL;
}
virtual Elem* LeftSibling(unsigned int index)
{
if(index >= data.size())
return NULL;
unsigned int p = data[index].parent;
if(p >= data.size())
return NULL;
unsigned int l = data[p].left;
if(l < data.size())
return &(data[l].element);
return NULL;
}
virtual Elem* RightSibling(unsigned int index)
{
if(index >= data.size())
return NULL;
unsigned int p = data[index].parent;
if(p >= data.size())
return NULL;
unsigned int r = data[p].right;
if(r < data.size())
return &(data[r].element);
return NULL;
}
virtual void Clear(void)
{
data.clear();
}
virtual bool InsertChild(unsigned int index,int flag,const BinaryTree<Elem>& t)
{
unsigned int offset = data.size();
unsigned int append = t.data.size();
unsigned int i;
if(index < data.size()){
if(t.data.size() >0){
if(flag == Left){
if(data[index].left >= data.size()){
for(i=0; i < append; i++){
data.push_back(t.data[i]);
data[offset+i].parent = index;
if(t.data[i].left < append){
data[offset+i].left += offset;
}
if(t.data[i].right < append){
data[offset+i].right += offset;
}
}
}
}else if(flag == Right){
if(data[index].right >= data.size()){
for(i=0; i < append; i++){
data.push_back(t.data[i]);
data[offset+i].parent = index;
if(t.data[i].left < append){
data[offset+i].left += offset;
}
if(t.data[i].right < append){
data[offset+i].right += offset;
}
}
}
}
}
}
return false;
}
virtual unsigned int InsertChild(unsigned int index,int flag,const Elem& value)
{
if(index < data.size()){
if(flag == Left && data[index].left >= data.size() ){
Node node;
node.element = value;
node.left = -1;
node.right = -1;
node.parent = index;
data[index].left = data.size();
data.push_back(node);
return data.size()-1;
}else if(flag == Right && data[index].right >= data.size()){
Node node;
node.element = value;
node.left = -1;
node.right = -1;
node.parent = index;
data[index].right = data.size();
data.push_back(node);
return data.size()-1;
}
}
return -1;
}
virtual bool DeleteChild(unsigned int index,int flag)
{
unsigned int i,j,k;
if(index < data.size()){
vector<unsigned int> marks;
if(flag == Left && data[index].left < data.size()){
MarkChildren(data[index].left,marks);
data[index].left = -1;
}else if(flag == Right && data[index].right < data.size()){
MarkChildren(data[index].right,marks);
data[index].right = -1;
}
if(marks.size()>0){//have elem to delete;
unsigned int newSize = data.size() - marks.size();
std::sort(marks.begin(),marks.end());//排序,从小到大
set<unsigned int> dels;
vector<unsigned int> swaps;
for(i = 0 ;i < marks.size(); ++i){
if(marks[i] >= newSize ){
dels.insert(marks[i]);
}
}
for(j = newSize; j < data.size(); ++j){
if(dels.find(j) == dels.end()){
swaps.push_back(j);
}
}
//最关键的,交换开始
map<unsigned int,unsigned int> swapMap;
for(k = 0; k < swaps.size(); ++k){
swapMap[swaps[k]] = marks[k];
}
for(k = 0; k < swaps.size(); ++k){
data[marks[k]] = data[swaps[k]];
}
for(i = 0; i < newSize; ++i){
unsigned int l = data[i].left,r =data[i].right;
if(l < data.size() && swapMap.find(l) != swapMap.end()){
data[i].left = swapMap[l];
}
if(r < data.size() && swapMap.find(r) != swapMap.end()){
data[i].right = swapMap[r];
}
}
for(i = 0 ; i < marks.size(); ++i){
data.pop_back();
}
return true;
}
}
return false;
}
virtual void MarkLeaf(vector<unsigned int>& marks)
{
for(unsigned int i=0; i < data.size();i++){
if(data[i].left > data.size() && data[i].right > data.size() ){
marks.push_back(i);
}
}
}
};
#endif