本文中给出了二叉树相关的算法及操作,主要包括以下内容:
1,创建二叉树
2,先序遍历(递归)
3,中序遍历(递归)
4,后序遍历(递归)
5,先序遍历(非递归)
6,中序遍历(非递归)
7,后序遍历(非递归)
8,层序遍历
9,叶子个数
10,二叉树深度
11,二叉树宽度
12,结点交换
下面的代码经过了实例测试,是可以运行的代码,供大家参考:
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <iostream>
#include <queue>
#include <stack>
using namespace std;
typedef struct TNode{
char data;
struct TNode*lchild,*rchild;
}TNode,*Tree;
Tree Creat( )//按先序序列建立二叉树
{
//example:124##5##36##7##
Tree T;
char ch;
printf("input the node:");
scanf("%c",&ch);
fflush(stdin);
if(ch=='#')
T=NULL;
else
{
T=(TNode*)malloc(sizeof(TNode));
T->data=ch;
T->lchild=Creat();
T->rchild=Creat();
}
return T;
}
void PreOrder(Tree T)//先序遍历————递归
{
TNode *p=T;
if (p != NULL)
{
printf(" %c",p->data);
PreOrder(p->lchild ) ;
PreOrder(p->rchild ) ;
}
}
void InOrder(Tree T)//中序遍历——递归
{
TNode *p=T;
if (p != NULL)
{
InOrder( p-> lchild ) ;
printf(" %c", p ->data);
InOrder(p-> rchild ) ;
}
}
void PostOrder(Tree T)//后序遍历——递归
{
TNode *p=T;
if (p != NULL){
PostOrder( p-> lchild ) ;
PostOrder( p-> rchild ) ;
printf(" %c", p ->data);
}
}
void LayerOrder(Tree T)//层序遍历
{
TNode *p=T;
if(T==NULL)return;
queue<Tree>Q;
Q.push(T);
int Qsize=Q.size();
while(!Q.empty())
{
p=Q.front();
Qsize=Q.size();
Q.pop();
Qsize=Q.size();
cout<<p->data;
if(p->lchild!=NULL)Q.push(p->lchild);
if(p->rchild!=NULL)Q.push(p->rchild);
Qsize=Q.size();
}
}
Tree findNode(Tree t,char x)//查找数据
{
Tree p;
if(!t) return(NULL);
else if(t->data==x)return t;
else
{
p=findNode(t->lchild,x);
if(!p)p=findNode(t->rchild,x);
return(p);
}
}
int Leaf(Tree T)//叶子结点个数
{
TNode *p=T;
if(p != NULL)
{
if((p->lchild==NULL)&&(p->rchild==NULL))
return 1;
else
return(Leaf(p->lchild)+Leaf(p->rchild));
}
else
return 0;
}
int Depth(Tree T)//树的深度
{
TNode *p=T;
int l,r;
if(!p)
return 0;
else
{
l=Depth(p->lchild);
r=Depth(p->rchild);
if(l>r)
return l+1;
else
return r+1;
}
}
//求二叉树的宽度
int Width(Tree pRoot)
{
if (pRoot == NULL)
{
return 0;
}
int nLastLevelWidth = 0;//记录上一层的宽度
int nTempLastLevelWidth = 0;
int nCurLevelWidth = 0;//记录当前层的宽度
int nWidth = 1;//二叉树的宽度
queue<Tree> myQueue;
myQueue.push(pRoot);//将根节点入队列
nLastLevelWidth = 1;
Tree pCur = NULL;
while (!myQueue.empty())//队列不空
{
nTempLastLevelWidth = nLastLevelWidth;
while (nTempLastLevelWidth != 0)
{
pCur = myQueue.front();//取出队列头元素
myQueue.pop();//将队列头元素出对
if (pCur->lchild != NULL)
{
myQueue.push(pCur->lchild);
}
if (pCur->rchild != NULL)
{
myQueue.push(pCur->rchild);
}
nTempLastLevelWidth--;
}
nCurLevelWidth = myQueue.size();
nWidth = nCurLevelWidth > nWidth ? nCurLevelWidth : nWidth;
nLastLevelWidth = nCurLevelWidth;
}
return nWidth;
}
void Change(Tree T)//结点交换
{
TNode *p=T;
if(p!=NULL)
{
p=T->lchild;
T->lchild=T->rchild;
T->rchild=p;
Change(T->lchild);
Change(T->rchild);
}
}
void InOrderTraverse(Tree T)//非递归中序遍历
{
stack<Tree> Stack;
if(!T)
{
printf("空树!\n");
return;
}
while(T || !Stack.empty())
{
while(T)
{
Stack.push(T);
T=T->lchild;
}
T=Stack.top();
Stack.pop();
printf("%c",T->data);
T=T->rchild;
}
}
void PreOrderTraverse(Tree T)//非递归先序遍历
{
stack<Tree> Stack;
if(!T)
{
printf("空树!\n");
return;
}
while(T || !Stack.empty())
{
while(T)
{
Stack.push(T);
printf("%c",T->data);
T=T->lchild;
}
T=Stack.top();
Stack.pop();
T=T->rchild;
}
}
void PostOrderTraverse(Tree T)//非递归后续遍历
{
stack<Tree> s;
Tree cur; //当前结点
Tree pre=NULL; //前一次访问的结点
s.push(T);
while(!s.empty())
{
cur=s.top();
if((cur->lchild==NULL&&cur->rchild==NULL)||
(pre!=NULL&&(pre==cur->lchild||pre==cur->rchild)))
{
cout<<cur->data<<" "; //如果当前结点没有孩子结点或者孩子节点都已被访问过
s.pop();//访问完结点后才出栈
pre=cur;
}
else
{
if(cur->rchild!=NULL)//先将右孩子入栈,先进后出
s.push(cur->rchild);
if(cur->lchild!=NULL)//后进先出
s.push(cur->lchild);
}
}
}
void ShowMenu()
{
printf("\t\t\t****二叉树算法**** \n");
printf("\t\t\t~~~~~~~~~~~~~~~~ \n");
printf("\t\t\t#1. 先序遍历(递归) #\n");
printf("\t\t\t#2. 中序遍历(递归) #\n");
printf("\t\t\t#3. 后序遍历(递归) #\n");
printf("\t\t\t#4. 先序遍历(非递归) #\n");
printf("\t\t\t#5. 中序遍历(非递归) #\n");
printf("\t\t\t#6. 后序遍历(非递归) #\n");
printf("\t\t\t#7. 层序遍历 #\n");
printf("\t\t\t#8. 叶子个数 #\n");
printf("\t\t\t#9. 二叉树深度 #\n");
printf("\t\t\t#10. 二叉树宽度\n");
printf("\t\t\t#11. 结点交换 #\n");
printf("\t\t\t#0. 退出程序 #\n");
printf("\t\t\t~~~~~~~~~~~~~~~~\n");
}
int main()
{
Tree T;
int t, l, d , w;
printf("\t\t\t****创建二叉树****\n");
printf("◤请先序输入树的各元素,用#表示空结点:\n");
T=Creat();
while(1)
{
ShowMenu();
printf("◤请您选择(0-11):");
scanf("%d",&t);
switch(t)
{
case 1: printf(" ◎先序遍历(递归):");
PreOrder(T);printf("\n");
break;
case 2: printf(" ◎中序遍历(递归):");
InOrder(T);printf("\n"); break;
case 3: printf(" ◎后序遍历(递归):");PostOrder(T);
printf("\n"); break;
case 4: printf(" ◎先序遍历(非递归):");
PreOrderTraverse(T);printf("\n"); break;
case 5: printf(" ◎中序遍历(非递归):");
InOrderTraverse(T);printf("\n"); break;
case 6: printf(" ◎后序遍历(非递归):");
PostOrderTraverse(T); printf("\n"); break;
case 7:printf(" ◎层序遍历:");
LayerOrder(T); printf("\n"); break;
case 8: printf(" ◎叶子结点个数:");
l=Leaf(T);printf(" %d 个\n",l); break;
case 9: printf(" ◎二叉树深度:");
d=Depth(T);printf(" %d\n",d); break;
case 10: printf(" ◎二叉树宽度:");
w=Width(T);printf("%d\n",w);break;
case 11: printf(" █各结点已交换█");
Change(T);printf("\n",d); break;
case 0: printf("\t\t******谢谢使用,再见!******\n");
return 0;break;
default: printf("※输入出错!!!请重输:\n");
}
}
}