(1)【实现二叉树的各种基本运算的算法】
问题描述:该算法的设计,要求运行结果如下所示:
二叉树的基本运算如下:
(1)创建二叉树
(2)输出二叉树:A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))
(3)H 结点:左孩子为 J 右孩子为 K
(4)二叉树 bt 的高度:7
(5)释放二叉树 bt
(2)【实现二叉树的 3 种遍历算法】
问题描述:该算法的设计,要求运行结果如下所示:
二叉树 bt:A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))
***层次遍历序列:A B C D E F G H I J K L M N
先序遍历序列:
递归算法:A B D E H J K L M N C F G I
非递归算法:A B D E H J K L M N C F G I
中序遍历序列:
递归算法:D B J H L K M N E A F C G
非递归算法:D B J H L K M N E A F C G I
后序遍历序列:
递归算法:D J L N M K H E B F I G C A
***非递归算法:D J L N M K H E B F I G C A
(3)【查找与定位算法】
问题描述:定位二叉树 bt 中结点值为 x 的结点及其所在的层次。
(4)【路径问题】
问题描述:采用先序遍历方法输出所有从叶子结点到根结点的逆路径。
二叉树 b:A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))
先序遍历方法:
D 到根结点逆路径: D->B->A
J 到根结点逆路径: J->H->E->B->A
L 到根结点逆路径: L->K->H->E->B->A
N 到根结点逆路径: N->M->K->H->E->B->A
F 到根结点逆路径: F->C->A
I 到根结点逆路径: I->G->C->A
第一条最长逆路径长度:7
第一条最长逆路径:N M K H E B A
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <queue>
#include <stack>
using namespace std;
//采用先序遍历方法输出所有从叶子结点到根结点的逆路径。
typedef struct BiTNode{
char data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
int depth=0;//全局变量 树深
char longestpath[50];
void CreateBiTree(BiTree &T);//按先序次序输入二叉树中结点的值,构造二叉链表表示的二叉树T。
void BiTreeLevelOrder(BiTree t);
void Print(BiTree T );//输出二叉树
void Child(BiTree T,char e);//H 结点:左孩子为J 右孩子为K
int BiTreeDepth(BiTree T);// 二叉树bt 的高度:7
void PreOrderTraverse(BiTree T);//先序遍历
void PreOrderTraverse_NonRecursion(BiTree T);//先序遍历 非递归
void InOrderTraverse(BiTree T);//中序遍历
void InOrderTraverse_NonRecursion(BiTree T);//中序遍历 非递归
void PostOrderTraverse(BiTree T);//后序遍历
void PostOrderTraverse_NonRecursion(BiTree T);//后序遍历 非递归
void Assign(BiTree T,char e) ;//定位二叉树 bt 中结点值为 x 的结点及其所在的层次。
void pathBiTree(BiTree T);//采用先序遍历方法输出所有从叶子结点到根结点的逆路径。
void BiTreeDestroy(BiTree &T);//释放二叉树
int BiTreeDepth(BiTree T);// 二叉树bt 的高度:7
int main(int argc, char** argv) {
BiTree bt;
CreateBiTree(bt);
printf("输出二叉树:\n");
Print(bt); printf("\n");
Child(bt,'H');
cout<<"depth:"<<BiTreeDepth(bt)<<endl;
printf("层次遍历:\n");
BiTreeLevelOrder(bt);
printf("\n\n先序遍历:\n");
PreOrderTraverse(bt);
printf("\n\n先序遍历非递归算法:\n");
PreOrderTraverse_NonRecursion(bt);
printf("\n\n中序遍历:\n");
InOrderTraverse(bt);
printf("\n\n中序遍历非递归算法:\n");
InOrderTraverse_NonRecursion(bt);//中序遍历 非递归
printf("\n\n后序遍历:\n");
PostOrderTraverse(bt);
printf("\n\n后序遍历非递归:\n");
PostOrderTraverse_NonRecursion(bt);
Assign(bt ,'E') ;
pathBiTree(bt);
printf("\n\n第一条最长逆路径长度为:%d ",depth);
printf("\n\n第一条最长逆路径为:");
for(int j=depth;j>=1;j--)
printf(" %c ",longestpath[j]);
BiTreeDestroy(bt);
return 0;
}
void CreateBiTree(BiTree &T)
{
// 按先序次序输入二叉树中结点的值
// 构造二叉链表表示的二叉树T。
char ch;
static int i = 0;
int j=0;
char pch[ ]="ABD$$EHJ$$KL$$M$N$$$CF$$G$I$$"; // 欲产生的 先序序列。
//printf("\n静态变量i的值分别为:%d\n", i);
//scanf("%c",&ch);
ch = pch[i++];
if(ch == '$') // 空树
T = NULL;
else {
T = (BiTree)malloc(sizeof(BiTNode));
if(!T) // 检测是否申请结点成功
exit(-1);
T->data = ch; // 生成根结点
CreateBiTree(T->lchild); // 构造左子树
CreateBiTree(T->rchild); // 构造右子树
}
}
void BiTreeLevelOrder(BiTree t)
{//用队列实现
queue<BiTNode*>tq;//创建队列tq,队列的每个元素都是结点指针
BiTNode* p=t;//p为一个指针,初始时指向根节点
if(p!=NULL)
{
tq.push(p);//根节点入队
}
while(!tq.empty())//树不为空时
{
p = tq.front();//出队
cout << p->data;
tq.pop();
cout<<" ";
if(p->lchild)
{
tq.push(p->lchild);
}
if(p->rchild)
{
tq.push(p->rchild);
}
}
}
void PreOrderTraverse(BiTree T)//先序遍历
{
if(T!=NULL)
{
printf("%c ",T->data);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
else return;
}
void PreOrderTraverse_NonRecursion(BiTree T)//先序遍历 非递归
{
BiTree stack[50];
int top=-1;
while((top!=-1)||T)
{
while(T)
{
printf("%c ",T->data);
stack[++top]=T;
T=T->lchild; //遍历左子树
}
if(top!=-1)
{
T=stack[top--];
T=T->rchild;//遍历右子树
}
}
}
void InOrderTraverse(BiTree T)//中序遍历
{
if(T!=NULL)
{
InOrderTraverse(T->lchild);
printf("%c ",T->data);
InOrderTraverse(T->rchild);
}
else return;
}
void InOrderTraverse_NonRecursion(BiTree T)//中序遍历 非递归
{
BiTree stack[50];
int top=-1;
while(top!=-1||T)
{
while(T)
{
stack[++top]=T;
T=T->lchild; //遍历左子树
}
if(top!=-1)
{
T=stack[top--];
printf("%c ",T->data);
T=T->rchild;//遍历右子树
}
}
}
void PostOrderTraverse(BiTree T)//后序遍历
{
if(T!=NULL)
{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
printf("%c ",T->data);
}
else return;
}
void PostOrderTraverse_NonRecursion(BiTree T)//后序遍历 非递归
{
stack<BiTree>S;
BiTree p=T;
BiTree last=T;
S.push(p);
while(!S.empty())
{
p=S.top();
if((p->lchild==NULL && p->rchild==NULL) ||
(p->rchild==NULL && last==p->lchild) ||
(last==p->rchild))
{
cout<<p->data<<" ";
last=p;
S.pop();
}
else
{
if(p->rchild)
S.push(p->rchild);
if(p->lchild)
S.push(p->lchild);
}
}
}
void Assign(BiTree T,char e) //定位二叉树 bt 中结点值为 x 的结点及其所在的层次
{
static int i=0;
if(T!=NULL)
{
i++;
if(T->data==e)
{
printf("\n\n结点值为 %c 处在第 %d 层 。",e,i);
return;
}
Assign(T->lchild,e);
Assign(T->rchild,e);
i--;
}
}
void pathBiTree(BiTree T)
{
static char path[50];
static int i=0;
if(T)
{
if(T->lchild==NULL&&T->rchild==NULL)
{
printf("\n\n %c的路径为: %c",T->data,T->data);
for(int j=i;j>0;j--)
printf("->%c",path[j]);
if((i+1)>depth)
{
depth=i+1;
longestpath[depth]=T->data;
for(int j=1;j<=i;j++)
longestpath[j]=path[j];
}
return;
}
else
{
i++;
path[i]=T->data;
pathBiTree(T->lchild);
pathBiTree(T->rchild);
i--;
}
}
}
void Print(BiTree T )//输出二叉树:A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I))) 中序遍历
{
if(T)
{
if(!T->lchild&&!T->rchild)
{
printf("%c",T->data);
return;
}
printf("%c",T->data);
printf("(");
Print(T->lchild);
if(T->rchild)
{
printf(",");
Print(T->rchild);
}
printf(")");
}
}
void Child(BiTree T,char e)//H 结点:左孩子为J 右孩子为K
{
if(T==NULL)
return ;
if(T->data==e)
{
if(T->lchild)
{
printf("left child :%c\n",T->lchild->data);
}
else {
printf("没有左孩子\n");
}
if(T->rchild)
{
printf("right child :%c\n",T->rchild->data);
}
else {
printf("没有右孩子\n");
}
return ;
}
else
{
Child(T->lchild,e);
Child(T->rchild,e);
}
}
int BiTreeDepth(BiTree T)// 二叉树bt 的高度:7
{
if(T==NULL)
return 0;
else if(T->lchild==NULL&&T->rchild==NULL)
return 1;
else
return 1+max(BiTreeDepth(T->lchild),BiTreeDepth(T->rchild));
}
void BiTreeDestroy(BiTree &T)//释放二叉树
{
if(T!=NULL)
{
if(T->lchild) BiTreeDestroy(T->lchild);
if(T->rchild) BiTreeDestroy(T->rchild);
free(T);
T=NULL;
}
}