二叉树之三

#include<iostream>            
#include
<stack>
#include
<queue>
using namespace std;

struct BiNode
{
char data;
BiNode
*LChild;
BiNode
*RChild;
int ltag;int rtag;
};
void Creat(BiNode *root) //先序建立
{
char ch;
cin
>>ch;
if(ch=='#'){root->data=ch;root->ltag=root->rtag=0;} //#代表NULL
else
{
root
->data=ch;root->ltag=root->rtag=0;
root
->LChild=new BiNode;
Creat(root
->LChild); //LChild为指针类型,所以需要用*
root->RChild=new BiNode;
Creat(root
->RChild);
}
}
void Destroy(BiNode& root)
{
if(root.data!='#')
{Destroy(
*root.LChild);
Destroy(
*root.RChild);
delete
&root;}

}
bool Empty(BiNode& root)
{
if(&root==NULL)
return true;
else return false;
}



void PreOrder(BiNode& root) //先根遍历
{
if (root.data!='#')
{
cout
<<root.data;
PreOrder(
*root.LChild);
PreOrder(
*root.RChild);
}
}
void NorecPreOrder(BiNode& root) //非递归先根遍历
{
if(root.data!='#')
{
stack
<BiNode*> s;
s.push(
&root);
while(!s.empty())
{
BiNode
*q=s.top();s.pop();
cout
<<q->data<<' ';
if(q->RChild->data!='#')
s.push(q
->RChild);
if(q->LChild->data!='#')
s.push(q
->LChild);
}
}
}

void InOrder(BiNode& root) //中根遍历
{
if(root.data!='#')
{ InOrder(
*root.LChild);
cout
<<root.data;
InOrder(
*root.RChild);
}
}

void NorecInOrder(BiNode& root) //非递归中根遍历
{
if(root.data!='#')
{
stack
<BiNode*> s;
BiNode
*q=&root;int em=1;
do{
while(q->data!='#')
{s.push(q);q
=q->LChild;}
if(s.empty())em=0;
else {
q
=s.top();s.pop();
cout
<<q->data<<' ';
q
=q->RChild;
}
}
while(em);

}

}

void PostOrder(BiNode& root) //后根遍历
{
if(root.data!='#')
{
PostOrder(
*root.LChild);
PostOrder(
*root.RChild);
cout
<<root.data;
}
}

void NorecPostOrder(BiNode& root) //非递归后根遍历
{

if(root.data!='#')
{
stack
<BiNode*>s;stack<int>s2;
int em=1;
BiNode temp
=root; BiNode *p=&temp;
//为什么要声明另一个BiNode temp呢,目的是使得p所指向的地址跟root的地址不同,最终使得root的属性不改变
//temp跟root的地址不同
do
{
while(p->data!='#'){s.push(p);s2.push(1);p=p->LChild;}
//??????????????root.LChild居然改变了
//cout<<"root.LChild->data"<<root.LChild->data<<endl;
if(s.empty())em=0;
else
{
if(s2.top()==1)
{p
=s.top();s2.pop();s2.push(2);p=p->RChild;}

else //==2的情况
{p=s.top();s.pop();s2.pop();cout<<p->data<<' ';p->data='#';}

}
}
while (em);
}


}
//后根遍历,最后一次p=s.top();
//结果是p=root;
//如果不另外开个空间,找个变量来储存root
//则这二者指向相同的空间。p->data='#'即相当于root->data='#'
//可以测试:添加语句 if(root.data=='#'&&p==&root)cout<<"NorecPostOrder :"<<"my god,root.data=='#'&&p==&root"<<endl;
//为什么NorecInOrder(BiNode& root)函数不会发生这样的问题呢,代码如下:
/*
void NorecInOrder(BiNode& root) //非递归中根遍历
{
if(root.data!='#')
{
stack<BiNode*> s;
BiNode *q=&root;int em=1;
do{
while(q->data!='#')
{s.push(q);q=q->LChild;}
if(s.empty())em=0;
else {
q=s.top();s.pop();
cout<<q->data<<' ';
q=q->RChild;
}
}while(em);
if(q==&root)cout<<"NoreInOrder: q==&root"<<root.data<<endl;
}

}

*/
//虽然也有声明BiNode *q=&root;但随后q=q->LChild;。。。q的地址已经改变了,和root已经没关系,
//关键是最终并不像非递归后根遍历那样,要再次使得p=root;所以p的改变不会影响到root

void WidthFirst(BiNode& root) //宽度优先,按层遍历
{
if(root.data!='#')
{
BiNode
*p=&root;
queue
<BiNode*> q;
q.push(p);
while(!q.empty())
{
p
=q.front();q.pop();
cout
<<p->data<<' ';
if(p->LChild->data!='#')q.push(p->LChild);
if(p->RChild->data!='#')q.push(p->RChild);
}

}
}

void CountNode(BiNode& root,int& num) //num要用引用类型
{

if(root.data!='#')
{
CountNode(
*root.LChild,num);
num
++;
CountNode(
*root.RChild,num);
}
}

void CountLeaf(BiNode& root,int& num2)
{
if(root.data!='#')
{
if(root.LChild->data=='#'&&root.RChild->data=='#')
num2
++;
if(root.LChild->data!='#')
CountLeaf(
*root.LChild,num2);
if(root.RChild->data!='#')
CountLeaf(
*root.RChild,num2);
}
}

int CountDepth(BiNode& root)
{
if(root.data!='#')
{
if(root.LChild->data=='#'&&root.RChild->data=='#')return 1;
return CountDepth(*root.LChild)>CountDepth(*root.RChild)?
CountDepth(
*root.LChild)+1:CountDepth(*root.RChild)+1;

}
else return 0;
}

BiNode
* CopyTree(BiNode& root)
{


if(root.data=='#'){return &root;}
else
{
BiNode
*q;
q
=new BiNode;
q
->data=root.data;
q
->LChild=CopyTree(*root.LChild);
q
->RChild=CopyTree(*root.RChild);
return q;
}
}



void ThreadPreOrder(BiNode *root ,BiNode* &pre) //先根线索化二叉树
{
if(root->data!='#')
{

//cout<<"root.data "<<root->data<<endl;
//cout<<"pre.data "<<pre->data<<endl;
if(root->LChild->data=='#')
{
root
->LChild=pre;/*cout<<"root.LChild=&pre; root.LChild->data: "<<root->LChild->data<<endl;*/
root
->ltag=1;
}
if(pre->data!='#'&&pre->RChild->data=='#')
{
pre
->RChild=root;/*cout<<"pre.RChild=&proot; pre.RChild->data: "<<pre->RChild->data<<endl;*/
pre
->rtag=1;
}
pre
=root;
if(root->ltag==0)ThreadPreOrder(root->LChild,pre);
ThreadPreOrder(root
->RChild,pre);
}
}

void ThreadInOrder(BiNode &root,BiNode* &pre) //中根线索化二叉树
{
if(root.data!='#')
{
ThreadPreOrder(
*root.LChild,pre);
cout
<<root.data<<' ';
if(root.LChild->data=='#')
{
root.LChild
=pre;cout<<"void ThreadInOrder(BiNode& root,BiNode& pre) "<<root.LChild->data<<endl;
root.ltag
=1;
}
if(pre->data!='#'&&pre->RChild->data=='#')
{
pre
->RChild=&root;
pre
->rtag=1;cout<<"void ThreadInOrder(BiNode& root,BiNode& pre) "<<root.RChild->data<<endl;
}
pre
=&root;

ThreadPreOrder(
*root.RChild,pre);
}
}

BiNode
* inpre(BiNode *q)
{
BiNode
*p, *r;
if(q->ltag==1) p=q->LChild;
else {
r
=q->LChild;
while(r->rtag!=1)r=r->RChild;
p
=r;
}
return p;
}

void main()
{

BiNode
*rt;rt=new BiNode;
Creat(rt);
WidthFirst(
*rt);cout<<endl;

int n=0;CountNode(*rt,n);cout<<n<<endl; //统计结点,叶子,和深度
n=0;CountLeaf(*rt,n);cout<<n<<endl;
cout
<<CountDepth(*rt)<<endl;

PreOrder(
*rt);cout<<endl;
NorecPreOrder(
*rt);cout<<endl;

InOrder(
*rt);cout<<endl;
NorecInOrder(
*rt);cout<<endl;

PostOrder(
*rt);cout<<endl;
NorecPostOrder(
*rt);cout<<endl;


//BiNode *cpy;cpy=new BiNode;
//cpy=CopyTree(*rt); //之后cpy相当于rt

BiNode
*pre;pre=new BiNode;
pre
->data='#';
//ThreadPreOrder(rt,pre);
//cout<<rt->LChild->data<<endl;
cout<<rt->LChild->LChild->data<<endl;

ThreadInOrder(
*rt,pre);cout<<endl;
cout
<<rt->RChild->ltag<<endl;
cout
<<rt->RChild->LChild->data<<endl;


}


//sample input: ab#d##c## 先序建立二叉树

  

posted on 2011-08-24 16:27  sysu_mjc  阅读(174)  评论(0编辑  收藏  举报

导航