Files

269 lines
6.2 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
template <class DT>
struct BTNode // 结点定义
{
DT data ; //数据域
BTNode* lchild; //指向左子树的指针
BTNode* rchild; //指向右子树的指针
};
//算法5.1 先序遍历递归算法
template <class DT>
void PreOrDerBiTree(BTNode<DT> *bt)
{
if(bt!=NULL)
{
cout<<bt->data<<' '; //输出结点上的数据
PreOrDerBiTree(bt->lchild); //递归的调用前序遍历左子树
PreOrDerBiTree(bt->rchild); //递归的调用前序遍历右子树
}
//return;
}
//算法5.2 中序遍历递归算法
template <class DT>
void InOrDerBiTree(BTNode<DT> *bt)
{
if(bt!=NULL)
{
InOrDerBiTree(bt->lchild); //递归的调用中序遍历左子树
cout<<bt->data<<' '; //输出结点上的数据
InOrDerBiTree(bt->rchild); //递归的调用中序遍历右子树
}
//return;
}
//算法5.3 后序遍历递归算法
template <class DT>
void PostOrDerBiTree(BTNode<DT> *bt)
{
if(bt!=NULL)
{
PostOrDerBiTree(bt->lchild); //递归的调用后序遍历左子树
PostOrDerBiTree(bt->rchild); //递归的调用后序遍历右子树
cout<<bt->data<<' '; //输出结点上的数据
}
//return;
}
//算法5.4 层序遍历算法
template<class DT>
void LevelBiTree(BTNode<DT> *bt)
{
SqQueue<DT> Q; // 创建一个队
int m=20;
InitQueue(Q,m);
BTNode<DT>* p;
p=bt;
if(p) EnQueue(Q,p); // 树非空,入队
while (!QueueEmpty(Q)) // 队非空
{
DeQueue(Q,p); // 出队
cout<<p->data; // 访问
if(p->lchild!=NULL) // 有左孩子
EnQueue(Q, p->lchild); // 左孩子入队
if(p->rchild!=NULL) // 有右孩子
EnQueue(Q, p->rchild); // 右孩子入队
}
DestroyQueue(Q); // 销毁队列
}
//算法5.5 先序非遍历递归算法
template <class DT>
void PreOrderBiTree_N(BTNode<DT> *bt)
{
SqStack<DT> S; // 创建栈
int m=20;
InitStack(S, m);
BTNode<DT>* p;
p=bt;
while (p!=NULL || !StackEmpty(S)) // 树非空或栈非空
{
while(p!=NULL) // 结点非空
{
cout<<p->data<<' '; // 访问结点
Push(S,p); // 入栈
p=p->lchild; // 转左子树
}
if(!StackEmpty(S)) // 栈非空
{
Pop(S,p); // 出栈
p=p->rchild; // 转出栈结点的右子树
}
}
DestroyStack(S); //销毁栈
}
//算法5.6 中序非遍历递归算法
template <class DT>
void InOrderBiTree_N(BTNode<DT> *bt)
{
SqStack<DT> S; // 创建一个栈
int m=20;
InitStack(S, m);
BTNode<DT>* p;
p=bt;
while (p!=NULL || !StackEmpty(S)) // 结点非空或栈非空
{
while(p!=NULL) // 结点非空
{
Push(S,p); // 出栈
p=p->lchild; // 转出栈结点右子树
}
if(!StackEmpty(S)) // 栈非空
{
Pop(S,p); // 出栈
cout<<p->data<<' '; // 访问出栈结点
p=p->rchild; // 转出栈结点的右子树
}
}
DestroyStack(S); // 销毁栈
}
//算法5.7 后序非遍历递归算法
template <class DT>
void PostOrderBiTree_N(BTNode<DT> *bt)
{ // 1. 初始化
SqStack<DT> S; // 创建一个栈
int m=20;
InitStack(S, m);
BTNode<DT>* p;
BTNode<DT>* r;
p=bt;
bool flag; // 顶点操作标志
do
{
while(p) // 结点非空
{
Push(S,p); // 结点入栈
p=p->lchild; // 转左子树
}
r=NULL; // 指向刚被访问点,初值为空
flag=true; // true表示处理栈顶结点
while(!StackEmpty(S) && flag) // 栈非空且当前处理的是栈顶结点
{
GetTop(S,p); // 获取栈顶元素
if(p->rchild==r) // 如果当前结点是栈元素的右孩子
{
cout<<p->data<<' '; // 访问栈顶元素
Pop(S,p); // 出栈
r=p; // r指向被访问结点
}
else // 否则
{
p=p->rchild; // 转栈顶元素右孩子
flag=false; // 当前点为非栈顶结点
}
}
}while(!StackEmpty(S)); // 栈非空,循环
cout<<endl;
DestroyStack(S); // 销毁栈
}
//算法5.8 创建二叉树
template <class DT>
void CreateBiTree(BTNode<DT> *&bt)
{
char ch;
cin>>ch; // 输入根结点的数据
if(ch=='#') // # 表示指针为空,说明树为空
bt=NULL ;
else
{
bt=new BTNode<DT>; // 申请内存
if(!bt)
{
cout<<"申请内存失败!"<<endl;
exit(-1); // 申请内存失败退出
}
bt->data=ch;
CreateBiTree(bt->lchild); // 创建根结点左子树
CreateBiTree(bt->rchild); // 创建根结点右子树
}
return;
}
//算法5.9 销毁二叉树
template <class DT>
void DestroyBiTree(BTNode<DT> *&bt)
{
if(bt) // 树非空
{
DestroyBiTree(bt->lchild); // 销毁左子树
DestroyBiTree(bt->rchild); // 销毁右子树
delete bt;
}
}
//算法5.10 结点查找
template<class DT>
BTNode<DT>* Search(BTNode<DT> * bt, DT e) // 查找值为e的元素
{
BTNode<DT> *p;
if(bt==NULL) // 结点为空,返回
return NULL;
else if(bt->data==e) // 找到,返回结点指针
return bt;
else // 结点值不为e
{
p=Search(bt->lchild,e); // 在左子树上查找
if(p!=NULL) // 找到
return p; // 返回结点指针
else // 未找到
return Search(bt->rchild,e); // 转右子树上查找
}
}
//算法5.11 求树深
template <class DT>
int Depth(BTNode<DT> *bt)
{
int hl,hr;
if(bt==NULL) // 树空
return 0; // 深度为0
else // 树非空
{
hl=Depth(bt->lchild); // 求左子树深度
hr=Depth(bt->lchild); // 求右子树深度
if(hl>hr) // 左子树高
return hl+1; // 树高为左子树高加1
else return hr+1; // 左子树高,树高为左子树高加1
}
}
//算法5.12 结点计数
template <class DT>
int NodeCount(BTNode<DT> *bt)
{
if(bt==NULL) // 空树结点数为0
return 0;
else // 非空树结点数为左、右子树结点数的和加1
return NodeCount(bt->lchild)+NodeCount(bt->rchild)+1;
}
template <class DT>
void DispBiTree(BTNode<DT> * bt,int level) // 显示树
{
if(bt) // 空二叉树不显示
{ DispBiTree(bt->rchild,level+1); // 显示右子树
cout<<endl; // 显示新行
for(int i=0;i<level-1;i++)
cout<<" "; // 确保在第level列显示节点
cout<<bt->data; // 显示节点
DispBiTree(bt->lchild,level+1); // 显示左子树
cout<<endl;
}//if
}