二叉树习题 3.5
- 设一棵二叉树以二叉链表表示,试编写有关二叉树的递归算法:
1) 统计二叉树中度为1的结点个数;
2) 统计二叉树中度为2的结点个数;
3) 统计二叉树中度为0(叶节点)的结点个数;
4) 统计二叉树的高度;
5) 统计二叉树的宽度,即在二叉树的各层上具有结点数最多的那一层上结点总数;
6) 计算二叉树中各结点中最大元素的值;
7) 交换每个结点的左孩子结点和右孩子结点;
8) 从二叉树中删去所有叶节点; - 编写算法判别给定二叉树是否为完全二叉树。
#include <iostream>
#include <queue>
#define MIN -100000000
using namespace std;
template <class T>
class BT;
template <class T>
class BTNode
{
friend class BT<T>;
private:
T data;
BTNode *lChild;
BTNode *rChild;
public:
BTNode();
BTNode(T& d);
BTNode(T& d, BTNode *l, BTNode *r);
BTNode<T> *GetLChild();
BTNode<T> *GetRChild();
void SetLChild(BTNode<T> *l);
void SetRChild(BTNode<T> *r);
~BTNode(){}
T GetValue();
bool SetValue(T& val);
bool IsLeaf();
void DisplayNode();
};
template <class T>
BTNode<T>::BTNode()
{
lChild=rChild=NULL;
}
template <class T>
BTNode<T>::BTNode(T& d)
{
lChild=rChild=NULL;
data=d;
}
template <class T>
BTNode<T>::BTNode(T& d, BTNode *l, BTNode *r)
{
lChild=l;
rChild=r;
data=d;
}
template <class T>
BTNode<T>* BTNode<T>:: GetLChild()
{
return lChild;
}
template <class T>
BTNode<T>* BTNode<T>:: GetRChild()
{
return rChild;
}
template <class T>
void BTNode<T>:: SetLChild(BTNode<T> *l)
{
lChild=l;
}
template <class T>
void BTNode<T>:: SetRChild(BTNode<T> *r)
{
rChild=r;
}
template <class T>
T BTNode<T>:: GetValue()
{
return data;
}
template <class T>
bool BTNode<T>:: SetValue(T& val)
{
this->data=val;
return true;
}
template <class T>
bool BTNode<T>:: IsLeaf()
{
if(lChild==NULL&&rChild==NULL)
return true;
else
return false;
}
template <class T>
void BTNode<T>:: DisplayNode()
{
cout<<"该结点的数据为: "<<data<<endl;
}
template <class T>
class BT
{
private:
BTNode<T> *root;
int s;
public:
BT(){root=NULL;}
~BT(){}
void NewTree();
BTNode<T>* SetSubTree();
bool IsEmpty();
BTNode<T>* GetRoot();
bool GetParent(BTNode<T> *cur);
bool GetLSibling(BTNode<T> *cur);
bool GetRSibling(BTNode<T> *cur);
bool LevelOrder(BTNode<T> *r);
bool PreOrder(BTNode<T> *r);
bool DeleteNode(BTNode<T> *r);
void Display();
void RecDisplay(BTNode<T> *t);
int GetDegree(int num);
int CalDegree2(BTNode<T> *r);
int CalDegree1(BTNode<T> *r);
int CalDegree0(BTNode<T> *r);
int GetHeight(BTNode<T> *r);
void CalWidth(BTNode<T> *r,int *count,int depth);
int GetWidth();
T GetMax(BTNode<T> *r);
void SwapChildren(BTNode<T> *r);
void DeleteLeaf(BTNode<T> *r);
bool IsCompleteBT();
};
template <class T>
void BT<T>::NewTree()
{
cout<<"请输入根结点的数据:"<<endl;
root=SetSubTree();
}
template <class T>
BTNode<T>* BT<T>::GetRoot()
{
return root;
}
template <class T>
BTNode<T>* BT<T>:: SetSubTree()
{
T t;
cin>>t;
BTNode<T> *p;
if(t=='#')
return NULL;
else
{
p=new BTNode<T>;
p->SetValue(t);
cout<<"请输入左孩子结点的数据:(输入‘#’则表示不存在左孩子结点)"<<endl;
p->SetLChild(SetSubTree());
cout<<"请输入右孩子结点的数据:(输入‘#’则表示不存在右孩子结点)"<<endl;
p->SetRChild(SetSubTree());
return p;
}
}
template <class T>
bool BT<T>:: IsEmpty()
{
return !root;
}
template <class T>
bool BT<T>:: LevelOrder(BTNode<T> *r)
{
queue<BTNode<T>*> NodeQueue;
BTNode<T> *p=root;
if(p)
NodeQueue.push(p);
while (!NodeQueue.empty())
{
p=NodeQueue.front();
NodeQueue.pop();
if(p->lChild)
NodeQueue.push(p->lChild);
if(p->rChild)
NodeQueue.push(p->rChild);
}
return true;
}
template <class T>
bool BT<T>:: PreOrder(BTNode<T> *r)
{
if(r)
{
PreOrder(r->lChild);
PreOrder(r->rChild);
return true;
}
return false;
}
template <class T>
void BT<T>:: Display()
{
RecDisplay(root);
cout<<endl;
}
template <class T>
void BT<T>:: RecDisplay(BTNode<T> *t)
{
if(t!=NULL)
{
cout<<t->data;
if(t->lChild||t->rChild)
{
cout<<'(';
RecDisplay(t->lChild);
cout<<',';
if(t->rChild)
RecDisplay(t->rChild);
else
cout<<'#';
cout<<')';
}
}
else
{
cout<<'#';
}
}
template <class T>
int BT<T>:: GetDegree(int num)
{
s=0;
if(num==2)
return CalDegree2(root);
else if(num==1)
return CalDegree1(root);
else if(num==0)
return CalDegree0(root);
else
return -1;
}
template <class T>
int BT<T>:: CalDegree2(BTNode<T> *r)
{
if(!r)
return 0;
s=(r->lChild!=NULL)&&(r->rChild!=NULL);
return s+CalDegree2(r->lChild)+CalDegree2(r->rChild);
}
template <class T>
int BT<T>:: CalDegree1(BTNode<T> *r)
{
if(!r)
return 0;
s=(r->lChild!=NULL&&r->rChild==NULL)||(r->lChild==NULL&&r->rChild!=NULL);
return s+CalDegree1(r->lChild)+CalDegree1(r->rChild);
}
template <class T>
int BT<T>:: CalDegree0(BTNode<T> *r)
{
if(r==NULL)
return 0;
s=(r->lChild==NULL)&&(r->rChild==NULL);
return s+CalDegree0(r->lChild)+CalDegree0(r->rChild);
}
template <class T>
int BT<T>:: GetHeight(BTNode<T> *r)
{
if(!r)
return 0;
int left=GetHeight(r->lChild)+1;
int right=GetHeight(r->rChild)+1;
return (left>right)?left:right;
}
template <class T>
void BT<T>:: CalWidth(BTNode<T> *r,int *count,int depth)
{
if(!r)
return ;
count[depth]++;
CalWidth(r->lChild,count,depth+1);
CalWidth(r->rChild,count,depth+1);
}
template <class T>
int BT<T>:: GetWidth()
{
int de=GetHeight(root);
int *count=new int [de];
for(int i=0;i<de;i++)
count[i]=0;
CalWidth(root,count,0);
int max=0;
for(int i=0;i<de;i++)
max=((count[i]>max)?count[i]:max);
return max;
}
template <class T>
T BT<T>:: GetMax(BTNode<T> *r)
{
if(r)
{
T left=GetMax(r->lChild);
T current=r->data;
T right=GetMax(r->rChild);
T max=((left>right)?left:right);
return ((current>max)?current:max);
}
else
return MIN;
}
template <class T>
void BT<T>::SwapChildren(BTNode<T> *r)
{
if(!r)
return;
BTNode<T> *temp;
temp=r->lChild;
r->lChild=r->rChild;
r->rChild=temp;
SwapChildren(r->lChild);
SwapChildren(r->rChild);
}
template <class T>
void BT<T>:: DeleteLeaf(BTNode<T> *r)
{
if(!r)
return;
if(!root->lChild&&!root->rChild)
{
delete root;
root=NULL;
}
if(r->lChild)
{
if(!r->lChild->lChild&&!r->lChild->rChild)
{
delete r->lChild;
r->lChild=NULL;
}
else
DeleteLeaf(r->lChild);
}
if(r->rChild)
{
if(!r->rChild->lChild&&!r->rChild->rChild)
{
delete r->rChild;
r->rChild=NULL;
}
else
DeleteLeaf(r->rChild);
}
}
template <class T>
bool BT<T>:: IsCompleteBT()
{
queue<BTNode<T>*> NodeQueue;
int flag=1;
NodeQueue.push(root);
while(!NodeQueue.empty())
{
BTNode<T> *p=NodeQueue.front();
NodeQueue.pop();
if(p)
{
if(!flag) return false;
NodeQueue.push(p->lChild);
NodeQueue.push(p->rChild);
}
else
{
flag=0;
}
}
return true;
}
int main()
{
BT<char> Tree;
Tree.NewTree();
cout<<"该二叉树为"<<endl;
Tree.Display();
if(Tree.IsCompleteBT())
cout<<"该二叉树为完全二叉树"<<endl;
else
cout<<"该二叉树不是完全二叉树"<<endl;
for(int i=0;i<3;i++)
{
cout<<"二叉树中度为"<<i<<"的结点个数为:"<<Tree.GetDegree(i)<<endl;
}
cout<<"二叉树的高度为:"<<Tree.GetHeight(Tree.GetRoot())<<endl;
cout<<"二叉树的宽度为:"<<Tree.GetWidth()<<endl;
cout<<"二叉树的最大元素为:"<<Tree.GetMax(Tree.GetRoot())<<endl;
cout<<"交换每一个左右孩子后的二叉树为:"<<endl;
Tree.SwapChildren(Tree.GetRoot());
Tree.Display();
cout<<"删除叶节点后的二叉树为:"<<endl;
Tree.DeleteLeaf(Tree.GetRoot());
Tree.Display();
return 0;
}