二叉树
在计算机科学中,二叉树是每个节点最多有两个子树的有序树。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。
二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树属于有序树,所以二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有2i − 1个结点;深度为k的二叉树至多有2k − 1个结点;对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0 = n2 + 1。二叉树有多种存储形式。本文采用经常用的二叉链表形式存储。对二叉树的部分操作进行了代码实现。上代码:
typedef struct _BINARY_TREE_NODE_
{
string strElement;
struct _BINARY_TREE_NODE_ *LChild,*RChild;
}BTreeNode,*PBTree;
class BTree
{
public:
BTree():Root(NULL)
{
nDepth = CreateBTree(Root);
}
~BTree()
{
DestroyBTree();
}
int GetDepth() const {return nDepth;}
void PreOrderTraverseRecur()// previous order using recursion
{
PreOrder(Root);
}
void PreOrderTraverseNotRecur();// previous order not using recursion
void InOrderTraverseRecur()// in order using recursion
{
InOrder(Root);
}
void InOrderTraverseNotRecur();// in order not using recursion
void PostOrderTraverseRecur()//post order using recursion
{
PostOrder(Root);
}
void PostOrderTraverseNotRecur();// post order not using recursion
void LevelOrderTraverse();//traverse BTree by layer
private:
PBTree Root;
int nDepth;
private:
int CreateBTree(PBTree& pointer);//create BTree
void DestroyBTree();//delete all nodes created in heap
void PreOrder(PBTree pointer);
void InOrder(PBTree pointer);
void PostOrder(PBTree pointer);
};
/*
**************二叉树*******************
*/
int BTree::CreateBTree(PBTree& pointer)
{
pointer = new BTreeNode;
cin>>pointer->strElement;
if (pointer->strElement == "null")
{
delete pointer;
pointer = NULL;
return 0;
}
else
{
int i,j;
i = CreateBTree(pointer->LChild);
j = CreateBTree(pointer->RChild);
if(i>j)
return (i+1);
else
return (j+1);
}
}
void BTree::DestroyBTree()
{
list<PBTree> PNodeList;
if(Root)
PNodeList.push_back(Root);
while(!PNodeList.empty())
{
PBTree temp = PNodeList.front();
PNodeList.pop_front();
if(temp->LChild)
PNodeList.push_back(temp->LChild);
if(temp->RChild)
PNodeList.push_back(temp->RChild);
delete temp;
}
}
void BTree::PreOrder(PBTree pointer)
{
if (pointer)
{
cout<<pointer->strElement<<endl;
PreOrder(pointer->LChild);
PreOrder(pointer->RChild);
}
}
void BTree::InOrder(PBTree pointer)
{
if (pointer)
{
InOrder(pointer->LChild);
cout<<pointer->strElement<<endl;
InOrder(pointer->RChild);
}
}
void BTree::PostOrder(PBTree pointer)
{
if (pointer)
{
PostOrder(pointer->LChild);
PostOrder(pointer->RChild);
cout<<pointer->strElement<<endl;
}
}
/*
traverse tree by previous order
using list instead of stack because I would not like to include<stack>
and as well the last three functions
*/
void BTree::PreOrderTraverseNotRecur()
{
list<PBTree> ListNode;
if (Root)
{
ListNode.push_front(Root);
}
while(!ListNode.empty())
{
PBTree temp = ListNode.front();
ListNode.pop_front();
cout<<temp->strElement<<endl;
if(temp->RChild)
ListNode.push_front(temp->RChild);
if(temp->LChild)
ListNode.push_front(temp->LChild);
}
}
void BTree::InOrderTraverseNotRecur()
{
list<PBTree> ListNode;
PBTree temp = Root;
if(temp)
ListNode.push_back(temp);
while(temp->LChild)
{
ListNode.push_front(temp->LChild);
temp = temp->LChild;
}
while(!ListNode.empty())
{
temp = ListNode.front();
ListNode.pop_front();
cout<<temp->strElement<<endl;
if(temp->RChild)
{
ListNode.push_front(temp->RChild);
temp = ListNode.front();
while(temp->LChild)
{
ListNode.push_front(temp->LChild);
temp = temp->LChild;
}
}
}
}
void BTree::PostOrderTraverseNotRecur()
{//somebody help me or let me take a consideration. haha...
list<string> strResult;
list<PBTree> ListTree;
if(Root)
ListTree.push_front(Root);
while(! ListTree.empty())
{
PBTree pointer;
pointer = ListTree.front();
ListTree.pop_front();
while(pointer)
{
strResult.push_front(pointer->strElement);
if(pointer->LChild)
ListTree.push_front(pointer->LChild);
pointer = pointer->RChild;
}
}
while(!strResult.empty())
{
cout<<strResult.front()<<endl;
strResult.pop_front();
}
}
void BTree::LevelOrderTraverse()
{
list<PBTree> ListNode;
if(Root)
ListNode.push_front(Root);
while(!ListNode.empty())
{
PBTree temp = ListNode.back();
ListNode.pop_back();
if(temp->LChild)
ListNode.push_front(temp->LChild);
if(temp->RChild)
ListNode.push_front(temp->RChild);
cout<<temp->strElement<<endl;
}
}
根据先序和中序的序列,重建二叉树。代码如下:
typedef struct _BINARY_TREE_NODE_
{
char chValue;
struct _BINARY_TREE_NODE_ *Left,*Right;
}BTreeNode,*PBTree;
void RebuildBTree(const char* pPreOrder,const char* pInOrder,int nLen,PBTree& pRoot)
{
if (nLen==1)
{
pRoot = (BTreeNode*)malloc(sizeof(BTreeNode));
(pRoot)->chValue=pPreOrder[0];
(pRoot)->Left = NULL;
(pRoot)->Right = NULL;
return;
}
else
{
(pRoot) = (BTreeNode*)malloc(sizeof(BTreeNode));
(pRoot)->chValue=pPreOrder[0];
//search first char in InOrder
int i=0;
for (i=0;i<nLen;++i )
{
if(pInOrder[i]==pPreOrder[0])
break;
}
if(i>0)
RebuildBTree(pPreOrder+1,pInOrder,i,((pRoot)->Left));
else
pRoot->Left= NULL;
if(i<nLen-1)
RebuildBTree(&(pPreOrder[i+1]),&(pInOrder[i+1]),nLen-i-1,((pRoot)->Right));
else
pRoot->Right=NULL;
}
}
void PreOr(PBTree pRoot)
{
if (pRoot)
{
printf(" %c ",pRoot->chValue);
PreOr(pRoot->Left);
PreOr(pRoot->Right);
}
}
void InOrder1(PBTree pRoot)
{
if(pRoot->Left)
InOrder1(pRoot->Left);
if(pRoot)
printf(" %c ",pRoot->chValue);
if (pRoot->Right)
{
InOrder1(pRoot->Right);
}
}
void Last(PBTree pRoot)
{
if(pRoot->Left)
Last(pRoot->Left);
if(pRoot->Right)
Last(pRoot->Right);
if(pRoot)
printf(" %c ",pRoot->chValue);
}
int main()
{
PBTree Root;
char Pre[]={"abdcef"};
char InOrder[]={"dbaecf"};
RebuildBTree(Pre,InOrder,6,Root);
printf("Previous Order\n");
PreOr(Root);
printf("\n");
printf("In Order\n");
InOrder1(Root);
printf("\n");
printf("Last Order\n");
Last(Root);
printf("\n");
return 0;
}