数据结构与算法分析第八章.docx
《数据结构与算法分析第八章.docx》由会员分享,可在线阅读,更多相关《数据结构与算法分析第八章.docx(17页珍藏版)》请在冰豆网上搜索。
数据结构与算法分析第八章
[首页,上一页,下一页; 目录]
第八章
二叉树
8.1 基本概念
树是一种非线性的数据结构,它在客观世界中广泛存在,例如人类社会的族谱和各种社会组织机构都可以用树来表示。
我们最常用到的是树和二叉树,其中又以二叉树更为实用。
为什么这样说呢?
因为大部分的操作都可以转变为一个父亲、一个左儿子和一个右儿子来实现,而且对二叉树的操作更为简单。
8.2 代码实现
二叉树的代码实现如下:
///////////////////////////////////////////////////////////////////////////////
//
//FileName:
btree.h
//Version:
0.10
//Author:
LuoCong
//Date:
2005-1-1212:
22:
40
//Comment:
//
///////////////////////////////////////////////////////////////////////////////
#ifndef__BINARY_TREE_H__
#define__BINARY_TREE_H__
#include
#include
#ifdef_DEBUG
#defineDEBUG_NEWnew(_NORMAL_BLOCK,THIS_FILE,__LINE__)
#endif
#ifdef_DEBUG
#definenewDEBUG_NEW
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#endif
#ifdef_DEBUG
#ifndefASSERT
#defineASSERTassert
#endif
#else//not_DEBUG
#ifndefASSERT
#defineASSERT
#endif
#endif//_DEBUG
template
classCBTNode
{
public:
Tdata;
CBTNode*parent;
CBTNode*left;
CBTNode*right;
CBTNode(
Tdata=T(),
CBTNode*parent=NULL,
CBTNode*left=NULL,
CBTNode*right=NULL
):
data(data),parent(parent),left(left),right(right){}
};
template
classCBTree
{
protected:
CBTNode*m_pNodeRoot;
public:
CBTree(CBTNode*initroot=NULL);
~CBTree();
voidAssignTo(CBTNode*p);
voidCopy(CBTree&p);
private:
CBTNode*Copy(CBTNode*p);
voidDestroyNode(CBTNode*p);
voidPreOrderTraverse(
constCBTNode*p,
void(*Visit)(constT&data)
)const;
voidInOrderTraverse(
constCBTNode*p,
void(*Visit)(constT&data)
)const;
voidPostOrderTraverse(
constCBTNode*p,
void(*Visit)(constT&data)
)const;
voidGetNodesCount(constCBTNode*p,unsignedint*unCount)const;
voidGetLeafCount(constCBTNode*p,unsignedint*unCount)const;
public:
T&GetNodeData(CBTNode*p);
TGetNodeData(constCBTNode*p)const;
voidSetNodeData(CBTNode*p,constT&data);
CBTNode*&GetRoot();
CBTNode*GetRoot()const;
CBTNode*&GetParent(CBTNode*p);
CBTNode*GetParent(constCBTNode*p)const;
CBTNode*&GetLeftChild(CBTNode*p);
CBTNode*GetLeftChild(constCBTNode*p)const;
CBTNode*&GetRightChild(CBTNode*p);
CBTNode*GetRightChild(constCBTNode*p)const;
CBTNode*&GetLeftSibling(CBTNode*p);
CBTNode*GetLeftSiblig(constCBTNode*p)const;
CBTNode*&GetRightSibling(CBTNode*p);
CBTNode*GetRightSibling(constCBTNode*p)const;
public:
intIsEmpty()const;
voidDestroy();
voidPreOrderTraverse(void(*Visit)(constT&data))const;
voidInOrderTraverse(void(*Visit)(constT&data))const;
voidPostOrderTraverse(void(*Visit)(constT&data))const;
unsignedintGetNodesCount()const;//Gethowmanynodes
unsignedintGetLeafCount()const;
unsignedintGetDepth()const;
unsignedintGetDepth(constCBTNode*p)const;
};
template
inlineCBTree:
:
CBTree(CBTNode*initroot):
m_pNodeRoot(initroot)
{
}
template
inlineCBTree:
:
~CBTree()
{
Destroy();
}
template
inlinevoidCBTree:
:
AssignTo(CBTNode*p)
{
ASSERT(p);
m_pNodeRoot=p;
}
template
inlinevoidCBTree:
:
Copy(CBTree&p)
{
if(NULL!
=p.m_pNodeRoot)
m_pNodeRoot=Copy(p.m_pNodeRoot);
else
m_pNodeRoot=NULL;
}
template
inlineCBTNode*CBTree:
:
Copy(CBTNode*p)
{
if(p)
{
CBTNode*pNewNode=newCBTNode;
if(NULL==pNewNode)
returnNULL;
pNewNode->data=p->data;
pNewNode->parent=p->parent;
pNewNode->left=Copy(p->left);
pNewNode->right=Copy(p->right);
returnpNewNode;
}
else
returnNULL;
}
template
inlineCBTNode*&CBTree:
:
GetLeftChild(CBTNode*p)
{
ASSERT(p);
return*(&(p->left));
}
template
inlineCBTNode*CBTree:
:
GetLeftChild(constCBTNode*p)const
{
ASSERT(p);
returnp->left;
}
template
inlineCBTNode*&CBTree:
:
GetRightChild(CBTNode*p)
{
ASSERT(p);
return*(&(p->right));
}
template
inlineCBTNode*CBTree:
:
GetRightChild(constCBTNode*p)const
{
ASSERT(p);
returnp->right;
}
template
inlineCBTNode*&CBTree:
:
GetLeftSibling(CBTNode*p)
{
ASSERT(p);
if(p->parent)
return*(&(p->parent->left));
else
return*(&(p->parent));//returnNULL;
}
template
inlineCBTNode*CBTree:
:
GetLeftSiblig(constCBTNode*p)const
{
ASSERT(p);
if(p->parent)
returnp->parent->left;
else
returnp->parent;//returnNULL;
}
template
inlineCBTNode*&CBTree:
:
GetRightSibling(CBTNode*p)
{
ASSERT(p);
if(p->parent)
return*(&(p->parent->right));
else
return*(&(p->parent));//returnNULL;
}
template
inlineCBTNode*CBTree:
:
GetRightSibling(constCBTNode*p)const
{
ASSERT(p);
if(p->parent)
returnp->parent->right;
else
returnp->parent;//returnNULL;
}
template
inlineCBTNode*&CBTree:
:
GetParent(CBTNode*p)
{
ASSERT(p);
return*(&(p->parent));
}
template
inlineCBTNode*CBTree:
:
GetParent(constCBTNode*p)const
{
ASSERT(p);
returnp->parent;
}
template
inlineT&CBTree:
:
GetNodeData(CBTNode*p)
{
ASSERT(p);
returnp->data;
}
template
inlineTCBTree:
:
GetNodeData(constCBTNode*p)const
{
ASSERT(p);
returnp->data;
}
template
inlinevoidCBTree:
:
SetNodeData(CBTNode*p,constT&data)
{
ASSERT(p);
p->data=data;
}
template
inlineintCBTree:
:
IsEmpty()const
{
returnNULL==m_pNodeRoot;
}
template
inlineCBTNode*&CBTree:
:
GetRoot()
{
return*(&(m_pNodeRoot));
}
template
inlineCBTNode*CBTree:
:
GetRoot()const
{
returnm_pNodeRoot;
}
template
inlinevoidCBTree:
:
DestroyNode(CBTNode*p)
{
if(p)
{
DestroyNode(p->left);
DestroyNode(p->right);
deletep;
}
}
template
inlinevoidCBTree:
:
Destroy()
{
DestroyNode(m_pNodeRoot);
m_pNodeRoot=NULL;
}
template
inlinevoidCBTree:
:
PreOrderTraverse(void(*Visit)(constT&data))const
{
PreOrderTraverse(m_pNodeRoot,Visit);
}
template
inlinevoidCBTree:
:
PreOrderTraverse(
constCBTNode*p,
void(*Visit)(constT&data)
)const
{
if(p)
{
Visit(p->data);
PreOrderTraverse(p->left,Visit);
PreOrderTraverse(p->right,Visit);
}
}
template
inlinevoidCBTree:
:
InOrderTraverse(void(*Visit)(constT&data))const
{
InOrderTraverse(m_pNodeRoot,Visit);
}
template
inlinevoidCBTree:
:
InOrderTraverse(
constCBTNode*p,
void(*Visit)(constT&data)
)const
{
if(p)
{
InOrderTraverse(p->left,Visit);
Visit(p->data);
InOrderTraverse(p->right,Visit);
}
}
template
inlinevoidCBTree:
:
PostOrderTraverse(void(*Visit)(constT&data))const
{
PostOrderTraverse(m_pNodeRoot,Visit);
}
template
inlinevoidCBTree:
:
PostOrderTraverse(
constCBTNode*p,
void(*Visit)(constT&data)
)const
{
if(p)
{
PostOrderTraverse(p->left,Visit);
PostOrderTraverse(p->right,Visit);
Visit(p->data);
}
}
template
inlineunsignedintCBTree:
:
GetNodesCount()const
{
unsignedintunCount;
GetNodesCount(m_pNodeRoot,&unCount);
returnunCount;
}
template
inlinevoidCBTree:
:
GetNodesCount(
constCBTNode*p,
unsignedint*unCount
)const
{
ASSERT(unCount);
unsignedintunLeftCount;
unsignedintunRightCount;
if(NULL==p)
*unCount=0;
elseif((NULL==p->left)&&(NULL==p->right))
*unCount=1;
else
{
GetNodesCount(p->left,&unLeftCount);
GetNodesCount(p->right,&unRightCount);
*unCount=1+unLeftCount+unRightCount;
}
}
template
inlineunsignedintCBTree:
:
GetLeafCount()const
{
unsignedintunCount=0;
GetLeafCount(m_pNodeRoot,&unCount);
returnunCount;
}
template
inlinevoidCBTree:
:
GetLeafCount(
constCBTNode*p,
unsignedint*unCount
)const
{
ASSERT(unCount);
if(p)
{
//ifthenode'sleft&rightchildrenarebothNULL,itmustbealeaf
if((NULL==p->left)&&(NULL==p->right))
++(*unCount);
GetLeafCount(p->left,unCount);
GetLeafCount(p->right,unCount);
}
}
template
inlineunsignedintCBTree:
:
GetDepth()const
{
//Minus1herebecauseIthinktherootnode'sdepthshouldbe0.
//So,don'tdoitifuthinktherootnode'sdepthshouldbe1.
returnGetDepth(m_pNodeRoot)-1;
}
template
inlineunsignedintCBTree:
:
GetDepth(constCBTNode*p)const
{
unsignedintunDepthLeft;
unsignedintunDepthRight;
if(p)
{
unDepthLeft=GetDepth(p->left);
unDepthRight=GetDepth(p->right);
return1+//ifdon'tplus1here,thetree'sdepthwillbealways0
(unDepthLeft>unDepthRight?
unDepthLeft:
unDepthRight);
}
else
return0;
}
#endif//__BINARY_TREE_H__
测试代码:
///////////////////////////////////////////////////////////////////////////////
//
//FileName:
btree.cpp
//Version:
0.10
//Author:
LuoCong
//Date:
2005-1-1213:
17:
07
//Comment:
//
///////////////////////////////////////////////////////////////////////////////
#include
#include"btree.h"
usingnamespacestd;
//结点的数据类型
typedefcharElementType;
//回调函数:
Visit()=PrintElement()
staticvoidPrintElement(constElementType&data)
{
cout<}
intmain()
{
CBTNode*pRoot;
CBTNode*pLeftChild;
CBTNode*pRightChild;
CBTreebtree;
#ifdef_DEBUG
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF);
#endif
pRoo