423 lines
6.8 KiB
C++
423 lines
6.8 KiB
C++
//-----------------------------------------------------------------------------+
|
|
// Copyright (C), 1998-2007, SH Software Co. Ltd.
|
|
// = FileName : BinTree.h
|
|
// = Version : ver2.0
|
|
// = Author : zjq
|
|
// = CreateDate : 2002-09-09
|
|
// = Description: 类的声明
|
|
// = Maintainers: nodeList没有定义,所以我认为该类没有用
|
|
//
|
|
//-----------------------------------------------------------------------------+
|
|
#ifndef _BINTREE_H_
|
|
#define _BINTREE_H_
|
|
|
|
#ifndef _TABLE_H_
|
|
#include "Table.h"
|
|
#endif
|
|
|
|
//二叉树
|
|
template<class T> class BinTree
|
|
{
|
|
public:
|
|
//contruct/distruct
|
|
BinTree(BinTree<T>*pParentTree = NULL);
|
|
BinTree(const BinTree<T>&bTree);
|
|
BinTree<T>& operator=(const BinTree<T>&bTree);
|
|
void SetLeftChild(BinTree<T>*pTree);
|
|
void SetRightChild(BinTree<T>*pTree);
|
|
BinTree<T>* FetchLeft();
|
|
BinTree<T>* FetchRight();
|
|
void ReleaseLeft();
|
|
void ReleaseRight();
|
|
void Clear();
|
|
virtual ~BinTree();
|
|
|
|
//direct access
|
|
T& NodeData();
|
|
BinTree<T>* &LeftChild();
|
|
BinTree<T>* &RightChild();
|
|
BinTree<T>* &Parent();
|
|
BinTree<T>* GetRoot() const;
|
|
|
|
//const access
|
|
const T& GetNodeData() const;
|
|
const BinTree<T>* GetRightChild() const;
|
|
const BinTree<T>* GetLeftChild() const;
|
|
const BinTree<T>* GetParent() const;
|
|
|
|
//attribute
|
|
bool IsLeftEmpty() const;
|
|
bool IsRightEmpty() const;
|
|
bool IsRoot() const;
|
|
bool IsChild() const;
|
|
bool IsLeaf() const;
|
|
bool IsParent() const;
|
|
bool IsRightChild() const;
|
|
bool IsLeftChild() const;
|
|
|
|
bool operator==(const BinTree<T>& t) const;
|
|
bool operator!=(const BinTree<T>& t) const;
|
|
bool operator >(const BinTree<T>& t) const;
|
|
bool operator <(const BinTree<T>& t) const;
|
|
|
|
//other
|
|
void SwapChild();
|
|
long Find(const T&t,Table<BinTree<T>* >&trees) const;
|
|
void GetPath(Table<short>&path) const;//0为左,1为右
|
|
long GetLeafNum() const;
|
|
void GetLeafNodes(Table<BinTree<T>*>&nodes) const;
|
|
|
|
protected:
|
|
T data;
|
|
BinTree<T> *left,*right,*pParent;
|
|
};
|
|
|
|
|
|
template<class T>
|
|
BinTree<T>::BinTree(BinTree<T>*pParentTree)
|
|
: left(NULL),right(NULL),pParent(pParentTree)
|
|
{
|
|
|
|
}
|
|
|
|
template<class T>
|
|
BinTree<T>::BinTree(const BinTree<T>&bTree)
|
|
: left(NULL),right(NULL),pParent(NULL)
|
|
{
|
|
*this = bTree;
|
|
}
|
|
|
|
template<class T>
|
|
void BinTree<T>::ReleaseLeft()
|
|
{
|
|
if (left != NULL)
|
|
{
|
|
delete left;
|
|
}
|
|
left = NULL;
|
|
}
|
|
|
|
template<class T>
|
|
void BinTree<T>::ReleaseRight()
|
|
{
|
|
if(right != NULL)
|
|
{
|
|
delete right;
|
|
}
|
|
right = NULL;
|
|
}
|
|
|
|
template<class T>
|
|
void BinTree<T>::Clear()
|
|
{
|
|
ReleaseLeft();
|
|
ReleaseRight();
|
|
}
|
|
|
|
template<class T>
|
|
BinTree<T>::~BinTree()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
template<class T>
|
|
T& BinTree<T>::NodeData()
|
|
{
|
|
return data;
|
|
}
|
|
|
|
template<class T>
|
|
BinTree<T>* & BinTree<T>::LeftChild()
|
|
{
|
|
return left;
|
|
}
|
|
|
|
template<class T>
|
|
BinTree<T>* & BinTree<T>::RightChild()
|
|
{
|
|
return right;
|
|
}
|
|
|
|
template<class T>
|
|
BinTree<T>* & BinTree<T>::Parent()
|
|
{
|
|
return pParent;
|
|
}
|
|
|
|
template<class T>
|
|
const T& BinTree<T>::GetNodeData() const
|
|
{
|
|
return data;
|
|
}
|
|
|
|
template<class T>
|
|
const BinTree<T>* BinTree<T>::GetRightChild() const
|
|
{
|
|
return right;
|
|
}
|
|
|
|
template<class T>
|
|
const BinTree<T>* BinTree<T>::GetLeftChild() const
|
|
{
|
|
return left;
|
|
}
|
|
|
|
template<class T>
|
|
const BinTree<T>* BinTree<T>::GetParent() const
|
|
{
|
|
return pParent;
|
|
}
|
|
|
|
//attribute
|
|
template<class T>
|
|
bool BinTree<T>::IsLeftEmpty() const
|
|
{
|
|
return left == NULL;
|
|
}
|
|
|
|
template<class T>
|
|
bool BinTree<T>::IsRightEmpty() const
|
|
{
|
|
return right == NULL;
|
|
}
|
|
|
|
template<class T>
|
|
bool BinTree<T>::IsRoot() const
|
|
{
|
|
return pParent == NULL;
|
|
}
|
|
|
|
template<class T>
|
|
bool BinTree<T>::IsChild() const
|
|
{
|
|
return pParent != NULL;
|
|
}
|
|
|
|
template<class T>
|
|
bool BinTree<T>::IsLeaf() const
|
|
{
|
|
return !IsParent();
|
|
}
|
|
|
|
template<class T>
|
|
bool BinTree<T>::IsParent() const
|
|
{
|
|
return !IsLeftEmpty() || !IsRightEmpty();
|
|
}
|
|
|
|
template<class T>
|
|
bool BinTree<T>::IsRightChild() const
|
|
{
|
|
return IsChild() ? pParent->GetRightChild() == this:false;
|
|
}
|
|
|
|
template<class T>
|
|
bool BinTree<T>::IsLeftChild() const
|
|
{
|
|
return IsChild() ? pParent->GetLeftChild() == this:false;
|
|
}
|
|
|
|
template<class T>
|
|
bool BinTree<T>::operator != (const BinTree<T>& t) const
|
|
{
|
|
return !(*this == t);
|
|
}
|
|
|
|
template<class T>
|
|
bool BinTree<T>::operator > (const BinTree<T>& t) const
|
|
{
|
|
return data > t.GetNodeData();
|
|
}
|
|
|
|
template<class T>
|
|
bool BinTree<T>::operator < (const BinTree<T>& t) const
|
|
{
|
|
return data < t.GetNodeData();
|
|
}
|
|
|
|
//other
|
|
template<class T>
|
|
void BinTree<T>::SwapChild()
|
|
{
|
|
Exchange(right,left);
|
|
}
|
|
|
|
template<class T>
|
|
BinTree<T>* BinTree<T>::GetRoot() const
|
|
{
|
|
BinTree<T>* pTree = (BinTree<T>*)this;
|
|
while(pTree->IsChild())
|
|
{
|
|
pTree = (BinTree<T>*)(pTree->GetParent());
|
|
}
|
|
return pTree;
|
|
}
|
|
|
|
template<class T>
|
|
void BinTree<T>::SetLeftChild(BinTree<T>*pTree)
|
|
{
|
|
if(pTree == left)
|
|
{
|
|
return;
|
|
}
|
|
if(pTree != NULL)
|
|
{
|
|
pTree->Parent() = this;
|
|
}
|
|
ReleaseLeft();
|
|
left = pTree;
|
|
}
|
|
|
|
template<class T>
|
|
void BinTree<T>::SetRightChild(BinTree<T>*pTree)
|
|
{//双向
|
|
if(pTree == right)
|
|
{
|
|
return;
|
|
}
|
|
ReleaseRight();
|
|
right = pTree;
|
|
if(pTree != NULL)
|
|
{
|
|
pTree->Parent() = this;
|
|
}
|
|
}
|
|
|
|
template<class T>
|
|
BinTree<T>* BinTree<T>::FetchLeft()
|
|
{
|
|
BinTree<T>*p = left;
|
|
left = NULL;
|
|
if(p != NULL)
|
|
{
|
|
p->Parent() = NULL;
|
|
}
|
|
return p;
|
|
}
|
|
|
|
template<class T>
|
|
BinTree<T>* BinTree<T>::FetchRight()
|
|
{
|
|
BinTree<T>*p = right;
|
|
right = NULL;
|
|
if(p != NULL)
|
|
{
|
|
p->Parent() = NULL;
|
|
}
|
|
return p;
|
|
}
|
|
|
|
template<class T>
|
|
long BinTree<T>::GetLeafNum() const
|
|
{
|
|
if(IsLeaf())
|
|
{
|
|
return 1;
|
|
}
|
|
long res = 0;
|
|
|
|
if(!IsLeftEmpty())
|
|
{
|
|
res += GetLeftChild()->GetLeafNum();
|
|
}
|
|
if(!IsRightEmpty())
|
|
{
|
|
res += GetRightChild()->GetLeafNum();
|
|
}
|
|
return res;
|
|
}
|
|
|
|
template<class T>
|
|
void BinTree<T>::GetLeafNodes(Table<BinTree<T>*>&nodes) const
|
|
{
|
|
if(IsLeaf())
|
|
{
|
|
this->nodeList.AddTail(this);
|
|
}
|
|
else
|
|
{
|
|
if(!IsLeftEmpty())
|
|
{
|
|
GetLeftChild()->GetLeafNodes(nodes);
|
|
}
|
|
if(!IsRightEmpty())
|
|
{
|
|
GetRightChild()->GetLeafNodes(nodes);
|
|
}
|
|
}
|
|
}
|
|
|
|
template<class T>
|
|
void BinTree<T>::GetPath(Table<short>&path) const
|
|
{
|
|
if(IsLeftChild())
|
|
{
|
|
GetParent()->GetPath(path);
|
|
path.AddTail(0);
|
|
}
|
|
else if(IsRightChild())
|
|
{
|
|
GetParent()->GetPath(path);
|
|
path.AddTail(1);
|
|
}
|
|
}
|
|
|
|
template<class T>
|
|
long BinTree<T>::Find(const T&t,Table<BinTree<T>* >&trees) const
|
|
{
|
|
if(data == t)
|
|
{
|
|
trees.AddTail(this);
|
|
}
|
|
if(!IsLeftEmpty())
|
|
{
|
|
left->Find(t,trees);
|
|
}
|
|
if(!IsRightEmpty())
|
|
{
|
|
right->Find(t,trees);
|
|
}
|
|
return trees.GetLength();
|
|
}
|
|
|
|
template<class T>
|
|
BinTree<T>& BinTree<T>::operator=(const BinTree<T>&t)
|
|
{
|
|
data = t.GetNodeData();
|
|
if(!t.IsLeftEmpty())
|
|
{
|
|
SetLeftChild(new BinTree<T>(*t.GetLeftChild()));
|
|
}
|
|
if(!t.IsRightEmpty())
|
|
{
|
|
SetRightChild(new BinTree<T>(*t.GetRightChild()));
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
template<class T>
|
|
bool BinTree<T>::operator==(const BinTree<T>&t) const
|
|
{
|
|
if(data != t.GetNodeData())
|
|
{
|
|
return false;
|
|
}
|
|
if((!IsLeftEmpty() && t.IsLeftEmpty()) || (IsLeftEmpty() && !t.IsLeftEmpty())
|
|
(!IsRightEmpty() && t.IsRightEmpty()) || (IsRightEmpty() && !t.IsRightEmpty()))
|
|
{
|
|
return false;
|
|
}
|
|
if((!IsLeftEmpty() && !t.IsLeftEmpty()) && *left != *(t.GetLeftChild()))
|
|
{
|
|
return false;
|
|
}
|
|
if((!IsRightEmpty() && !t.IsRightEmpty()) && *right != *(t.GetRightChild()))
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
#endif
|