二叉树的层序遍历算法
① 建立二叉树,层序、先序遍历
#include <iostream>
#include "sq_Queue.h"
#define M 1000
using namespace std;
template<class T>
struct Btnode
{T d;
Btnode *lchild;
Btnode *rchild;
};
template<class T>
class Binary_Tree
{private:
Btnode<T> *BT;
public:
Binary_Tree(){BT=NULL;return;}
void creat_Binary_Tree(T);
void pretrav_Binary_Tree();
void level( );
};
template<class T>
void Binary_Tree<T>::creat_Binary_Tree(T end)
{
Btnode<T> *p;
T x;
cin>>x;
if(x==end)
return; p=new Btnode<T>;
p->d=x;
p->lchild=NULL;
p->rchild=NULL;
BT=p;
creat(p,1,end);
creat(p,2,end);
return;
}
template<class T>
static creat(Btnode<T> *p,int k,T end)
{
Btnode<T> *q;
T x;
cin>>x;
if(x!=end)
{
q=new Btnode<T>; q->d=x;
q->lchild=NULL;
q->rchild=NULL;
if(k==1) p->lchild=q; if(k==2) p->rchild=q; creat(q,1,end); creat(q,2,end); }
return 0;
}
//————————————前序遍历二叉链表——————————————
template<class T>
void Binary_Tree<T>::pretrav_Binary_Tree( )
{
Btnode<T> *p;
p=BT;
pretrav(p); cout<<endl;
return;
}
template<class T>
static pretrav(Btnode<T> *p)
{
if(p!=NULL)
{
cout<<p->d<<" "; pretrav(p->lchild); pretrav(p->rchild); }
return 0;
}
//————————————按层次遍历二叉链表——————————————
template<class T>
void Binary_Tree<T>::level( )
{
Btnode<T> *k;
sq_Queue<Btnode<T>*>q(M);
if(BT!=NULL)
q.ins_sq_Queue(BT);
while(q.flag_sq_Queue( ))
{
k=q.del_sq_Queue( );
cout<<k->d<<endl;
if(k->lchild!=NULL) q.ins_sq_Queue(k->lchild);
if(k->rchild!=NULL) q.ins_sq_Queue(k->rchild);
}
return;
}
int main( )
{
Binary_Tree<int>b; cout<<"输入各结点值(-1为结束符值):"<<endl;
b.creat_Binary_Tree(-1); cout<<"前序序列:"<<endl;
b.pretrav_Binary_Tree( );
cout<<"按层次输出二叉链表中所有结点值:"<<endl;
b.level( );
再建立一个用户自定义文件sq_Queue,把下面的考进去
#include <iostream>
using namespace std;
//定义循环队列类
template<class T> //模板声明,数据元素虚拟类型为T
class sq_Queue
{private: //数据成员
int mm; //存储空间容量
int front; //排头指针
int rear; //队尾指针
int s; //标志
T *q; //循环队列存储空间首地址
public: //成员函数
sq_Queue(int); //构造函数,建立空循环队列
void prt_sq_Queue(); //输出排头与队尾指针以及队中元素
int flag_sq_Queue(); //检测循环队列的状态
void ins_sq_Queue(T); //入队
T del_sq_Queue(); //退队
};
//建立容量为mm的空循环队列
template<class T>
sq_Queue<T>::sq_Queue(int m)
{mm=m; //存储空间容量
q=new T[mm]; //动态申请存储空间
front=mm;
rear=mm;
s=0;
return;
}
//输出排头与队尾指针以及队中元素
template<class T>
void sq_Queue<T>::prt_sq_Queue()
{int i;
cout<<"front="<<front<<endl;
cout<<"rear="<<rear<<endl;
if(s==0){cout<<"队列空!"<<endl;
return;
}
i=front;
do{i=i+1;
if(i==mm+1)i=1;
cout<<q[i-1]<<endl;
}while(i!=rear);
return;
}
//检测循环队列的状态
template<class T>
int sq_Queue<T>::flag_sq_Queue()
{if((s==1)&&(rear==front))return(-1); //存储空间已满,返回-1
if(s==0)return(0); //循环队列为空,返回0
return(1); //正常返回1
}
//入队
template<class T>
void sq_Queue<T>::ins_sq_Queue(T x)
{if((s==1)&&(rear==front)) //存储空间已满,上溢错误
{cout<<"Queue_overflow!"<<endl;
return;
}
rear=rear+1; //队尾指针进一
if(rear==mm+1)rear=1;
q[rear-1]=x; //新元素入队
s=1; //入队后队列非空
return;
}
//退队
template<class T>
T sq_Queue<T>::del_sq_Queue()
{T y;
if(s==0) //队列为空,下溢错误
{cout<<"Queue_underflow!"<<endl;
return(0);
}
front=front+1; //排头指针进一
if(front==mm+1)front=1;
y=q[front-1]; //将退队元素赋值给变量
if(front==rear)s=0;
return(y); //返回退队元素
}
② 二叉树层次遍历怎么进行
设计一个算法层序遍历二叉树(同一层从左到右访问)。思想:用一个队列保存被访问的当前节点的左右孩子以实现层序遍历。
void HierarchyBiTree(BiTree Root){
LinkQueue *Q; // 保存当前节点的左右孩子的队列
InitQueue(Q); // 初始化队列
if (Root == NULL) return ; //树为空则返回
BiNode *p = Root; // 临时保存树根Root到指针p中
Visit(p->data); // 访问根节点
if (p->lchild) EnQueue(Q, p->lchild); // 若存在左孩子,左孩子进队列
if (p->rchild) EnQueue(Q, p->rchild); // 若存在右孩子,右孩子进队列
while (!QueueEmpty(Q)) // 若队列不空,则层序遍历 { DeQueue(Q, p); // 出队列
Visit(p->data);// 访问当前节点
if (p->lchild) EnQueue(Q, p->lchild); // 若存在左孩子,左孩子进队列
if (p->rchild) EnQueue(Q, p->rchild); // 若存在右孩子,右孩子进队列
}
DestroyQueue(Q); // 释放队列空间
return ;
这个已经很详细了!你一定可以看懂的!加油啊!
③ 求c#前中后序遍历二叉树的算法及思想
下面简单介绍一下几种算法和思路:
先序遍历:
1. 访问根结点
2. 按先序遍历左子树;
3. 按先序遍历右子树;
4. 例如:遍历已知二叉树结果为:A->B->D->G->H->C->E->F
中序遍历:
1. 按中序遍历左子树;
2. 访问根结点;
3. 按中序遍历右子树;
4. 例如遍历已知二叉树的结果:B->G->D->H->A->E->C->F
后序遍历:
1. 按后序遍历左子树;
2. 按后序遍历右子树;
3. 访问根结点;
4. 例如遍历已知二叉树的结果:G->H->D->B->E->F->C->A
层次遍历:
1.从上到下,从左到右遍历二叉树的各个结点(实现时需要借辅助容器);
2.例如遍历已知二叉树的结果:A->B->C->D->E->F->G->H
附加代码:
二叉遍历算法解决方案
using System;
using System.Collections.Generic;
using System.Text;
namespace structure
{
class Program
{
二叉树结点数据结构的定义#region 二叉树结点数据结构的定义
//二叉树结点数据结构包括数据域,左右结点以及父结点成员;
class nodes<T>
{
T data;
nodes<T> Lnode, Rnode, Pnode;
public T Data
{
set { data = value; }
get { return data; }
}
public nodes<T> LNode
{
set { Lnode = value; }
get { return Lnode; }
}
public nodes<T> RNode
{
set { Rnode = value; }
get { return Rnode; }
}
public nodes<T> PNode
{
set { Pnode = value; }
get { return Pnode; }
}
public nodes()
{ }
public nodes(T data)
{
this.data = data;
}
}
#endregion
#region 先序编历二叉树
static void PreOrder<T>(nodes<T> rootNode)
{
if (rootNode != null)
{
Console.WriteLine(rootNode.Data);
PreOrder<T>(rootNode.LNode);
PreOrder<T>(rootNode.RNode);
}
}
#endregion
④ 层序遍历二叉树
#include<stdio.h>
#include<stdlib.h>
#define m 100
typedef char etype;
typedef struct bitnode
{
etype data;
struct bitnode *lch,*rch;
}bitnode,*bitree;
bitree que[m];
int front=0,rear=0;
bitnode *creat_bt1();
bitnode *creat_bt2();
void preorder(bitnode *p);
void inorder(bitnode *p);
void postorder(bitnode *p);
void enqueue(bitree);
bitree delqueue();
void levorder(bitree);
int treedepth(bitree);
void prtbtree(bitree,int);
void exchange(bitree);
int leafcount(bitree);
void paintleaf(bitree);
bitnode *t;
int count=0;
void main()
{
char ch;int k;
do{
printf("\n\n\n");
printf("\n==========主菜单==============");
printf("\n 1.建立二叉树方法 1");
printf("\n 2.建立二叉树方法 2");
printf("\n 3.先序递归遍历二叉树");
printf("\n 4.中序递归遍历二叉树");
printf("\n 5.后序递归遍历二叉树");
printf("\n 6.层次遍历二叉树");
printf("\n 7.计算二叉树的高度");
printf("\n 8.计算二叉树中叶结点个数");
printf("\n 9.交换二叉树的左右子树");
printf("\n 10.打印二叉树");
printf("\n 0.结束程序运行");
printf("\n===============================");
printf("\n 请输入您的选择(0,1,2,3,4,5,6,7,8,9,10)");
scanf("%d",&k);
switch(k)
{case 1:t=creat_bt1();break;
case 2:printf("\n请输入二叉树各节点的值:");fflush(stdin);
t=creat_bt2();break;
case 3:if(t)
{printf("先序遍历二叉树:");
preorder(t);
printf("\n");
}
else printf("二叉树为空!\n");
break;
case 4:if(t)
{printf("中序遍历二叉树:");
inorder(t);
printf("\n");
}
else printf("二叉树为空!\n");
break;
case 5:if(t)
{printf("后序遍历二叉树:");
postorder(t);
printf("\n");
}
else printf("二叉树为空!\n");
break;
case 6:if(t)
{printf("层次遍历二叉树:");
levorder(t);
printf("\n");
}
else printf("二叉树为空!\n");
break;
case 7:if(t)
{printf("二叉树的高度为:%d",treedepth(t));
printf("\n");
}
else printf("二叉树为空!\n");
break;
case 8:if(t)
{printf("二叉树的叶子结点数为:%d\n",leafcount(t));
printf("二叉树的叶结点数为:");paintleaf(t);
printf("\n");
}
else printf("二叉树为空!\n");
break;
case 9:if(t)
{printf("二叉树的左右子树:\n");
exchange(t);
prtbtree(t,0);
printf("\n");
}
else printf("二叉树为空!\n");
break;
case 10:if(t)
{printf("逆时针旋转90度输出的二叉树:\n");
prtbtree(t,0);
printf("\n");
}
else printf("二叉树为空!\n");
break;
case 0:exit(0);
}
}while(k>=1&&k<=10);
printf("\n再见! 按回车键,返回…\n");
ch=getchar();
}
bitnode *creat_bt1()
{
bitnode *t,*p,*v[20];int i,j;etype e;
printf("\n请输入二叉树各结点的编号和对应的值(如:1,a):");
scanf("%d,%c",&i,&e);
while(i!=0&&e!='#')
{
p=(bitnode *)malloc(sizeof(bitnode));
p->data=e;p->lch=NULL;p->rch=NULL;
v[i]=p;
if(i==1)t=p;
else
{j=i/2;
if(i%2==0) v[j]->lch=p;
else
v[j]->rch=p;
}
printf("\n 请继续输入二叉树各结点的编号和对应的值:");
scanf("%d,%c",&i,&e);
}
return(t);
}
bitnode *creat_bt2()
{
bitnode *t;etype e;
scanf("%c",&e);
if(e=='#')
t=NULL;
else
{
t=(bitnode *)malloc(sizeof(bitnode));
t->data=e;
t->lch=creat_bt2();
t->rch=creat_bt2();
}
return(t);
}
void preorder(bitnode *p){
if(p)
{
printf("%3c",p->data);
preorder(p->lch);
preorder(p->rch);
}
}
void inorder(bitnode *p)
{
if(p){
inorder(p->lch);
printf("%3c",p->data);
inorder(p->rch);
}
}
void postorder(bitnode *p)
{
if(p)
{
postorder(p->lch);
postorder(p->rch);
printf("%3c",p->data);
}
}
void enqueue(bitree T)
{
if(front!=(rear+1)%m)
{rear=(rear+1)%m;
que[rear]=T;}
}
bitree delqueue()
{
if(front==rear)return NULL;
front=(front+1)%m;
return(que[front]);
}
void levorder(bitree T)
{
bitree p;
if(T)
{
enqueue(T);
while(front!=rear)
{
p=delqueue();
printf("%3c",p->data);
if(p->lch!=NULL)enqueue(p->lch);
if(p->rch!=NULL)enqueue(p->rch);
}
}
}
int treedepth(bitree bt)
{
int hl,hr,max;
if(bt!=NULL)
{
hl=treedepth(bt->lch);
hr=treedepth(bt->rch);
max=(hl>hr)? hl:hr;
return(max+1);
}
else
return(0);
}
void prtbtree(bitree bt,int level)
{
int j;
if(bt){
prtbtree(bt->rch,level+1);
for(j=0;j<=6*level+1;j++)printf(" ");
printf("%c\n",bt->data);
prtbtree(bt->lch,level+1);
}
}
void exchange(bitree bt)
{
bitree p;
if(bt)
{p=bt->lch;bt->lch=bt->rch;bt->rch=p;
exchange(bt->lch);exchange(bt->rch);
}
}
int leafcount(bitree bt)
{
if(bt!=NULL)
{
leafcount(bt->lch);
leafcount(bt->rch);
if((bt->lch==NULL)&&(bt->rch==NULL))
count++;
}
return(count);
}
void paintleaf(bitree bt)
{
if(bt!=NULL)
{
if(bt->lch==NULL&&bt->rch==NULL)
printf("%3c",bt->data);
paintleaf(bt->lch);
paintleaf(bt->rch);
}
}
⑤ 试完成二叉树按层次(同一层自左至右)遍历的算法。
#include "iostream.h"
#include "stdlib.h"
#include "stdio.h"
typedef char ElemType;//定义二叉树结点值的类型为字符型
const int MaxLength=10;//结点个数不超过10个
typedef struct BTNode{
ElemType data;
struct BTNode *lchild,*rchild;
}BTNode,* BiTree;
void CreateBiTree(BiTree &T){//按先序次序输入,构造二叉链表表示的二叉树T,空格表示空树
// if(T) return;
char ch;
ch=getchar(); //不能用cin来输入,在cin中不能识别空格。
if(ch==' ') T=NULL;
else{
if(!(T=(BTNode *)malloc(sizeof(BTNode)))) cout<<"malloc fail!";
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
void PreOrderTraverse(BiTree T){//先序遍历
if(T){
cout<<T->data<<' ';
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
void InOrderTraverse(BiTree T){//中序遍历
if(T){
InOrderTraverse(T->lchild);
cout<<T->data<<' ';
InOrderTraverse(T->rchild);
}
}
void PostOrderTraverse(BiTree T){//后序遍历
if(T){
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout<<T->data<<' ';
}
}
void LevelOrderTraverse(BiTree T){//层序遍历
BiTree Q[MaxLength];
int front=0,rear=0;
BiTree p;
if(T){ //根结点入队
Q[rear]=T;
rear=(rear+1)%MaxLength;
}
while(front!=rear){
p=Q[front]; //队头元素出队
front=(front+1)%MaxLength;
cout<<p->data<<' ';
if(p->lchild){ //左孩子不为空,入队
Q[rear]=p->lchild;
rear=(rear+1)%MaxLength;
}
if(p->rchild){ //右孩子不为空,入队
Q[rear]=p->rchild;
rear=(rear+1)%MaxLength;
}
}
}
//非递归的先序遍历算法
void NRPreOrder(BiTree bt)
{ BiTree stack[MaxLength],p;
int top;
if (bt!=NULL){
top=0;p=bt;
while(p!=NULL||top>0)
{ while(p!=NULL)
{
cout<<p->data;
stack[top]=p;
top++;
p=p->lchild;
}
if (top>0)
{ top--; p=stack[top]; p=p->rchild; }
}
}
}
//非递归的中序遍历算法
void NRInOrder(BiTree bt)
{ BiTree stack[MaxLength],p;
int top;
if (bt!=NULL){
top=0;p=bt;
while(p!=NULL||top>0)
{ while(p!=NULL)
{
stack[top]=p;
top++;
p=p->lchild;
}
if (top>0)
{ top--; p=stack[top];cout<<p->data; p=p->rchild; }
}
}
}
//非递归的后序遍历算法
/*bt是要遍历树的根指针,后序遍历要求在遍历完左右子树后,再访问根。
需要判断根结点的左右子树是否均遍历过。
可采用标记法,结点入栈时,配一个标志tag一同入栈
(1:遍历左子树前的现场保护,2:遍历右子树前的现场保护)。
首先将bt和tag(为1)入栈,遍历左子树;
返回后,修改栈顶tag为2,遍历右子树;最后访问根结点。*/
typedef struct
{
BiTree ptr;
int tag;
}stacknode;
void NRPostOrder(BiTree bt)
{
stacknode s[MaxLength],x;
BiTree p=bt;
int top;
if(bt!=NULL){
top=0;p=bt;
do
{
while (p!=NULL) //遍历左子树
{
s[top].ptr = p;
s[top].tag = 1; //标记为左子树
top++;
p=p->lchild;
}
while (top>0 && s[top-1].tag==2)
{
x = s[--top];
p = x.ptr;
cout<<p->data; //tag为R,表示右子树访问完毕,故访问根结点
}
if (top>0)
{
s[top-1].tag =2; //遍历右子树
p=s[top-1].ptr->rchild;
}
}while (top>0);}
}//PostOrderUnrec
int BTDepth(BiTree T){//求二叉树的深度
if(!T) return 0;
else{
int h1=BTDepth(T->lchild);
int h2=BTDepth(T->rchild);
if(h1>h2) return h1+1;
else return h2+1;
}
}
int Leaf(BiTree T){//求二叉树的叶子数
if(!T) return 0;
else if(!T->lchild&&!T->rchild) return 1;
else return(Leaf(T->lchild)+Leaf(T->rchild));
}
int NodeCount(BiTree T){//求二叉树的结点总数
if(!T) return 0;
else return NodeCount(T->lchild)+NodeCount(T->rchild)+1;
}
void main(){
BiTree T;
T=NULL;
int select;
//cout<<"请按先序次序输入各结点的值,以空格表示空树(输入时可连续输入):"<<endl;
// CreateBiTree(T);
while(1){
cout<<"\n\n请选择要执行的操作:\n";
cout<<"1.创建二叉树\n";
cout<<"2.二叉树的递归遍历算法(前、中、后)\n";
cout<<"3.二叉树的层次遍历算法\n";
cout<<"4.求二叉树的深度\n";
cout<<"5.求二叉树的叶子结点\n";
cout<<"6.求二叉树的结点总数\n";
cout<<"7.二叉树的非递归遍历算法(前、中、后)\n"; //此项可选做
cout<<"0.退出\n";
cin>>select;
switch(select){
case 0:return;
case 1:
cout<<"请按先序次序输入各结点的值,以空格表示空树(输入时可连续输入):"<<endl;
CreateBiTree(T);
break;
case 2:
if(!T) cout<<"未建立树,请先建树!";
else{
cout<<"\n先序遍历:\n";
PreOrderTraverse(T);
cout<<"\n中序遍历:\n";
InOrderTraverse(T);
cout<<"\n后序遍历:\n";
PostOrderTraverse(T);
}
break;
case 3:
cout<<"\n层序遍历:\n";
LevelOrderTraverse(T);
break;
case 4:
cout<<"二叉树的深度为:\n";
cout<<BTDepth(T);
break;
case 5:
cout<<"\n叶子节点数:\n";
cout<<Leaf(T);
break;
case 6:
cout<<"总节点数:\n";
cout<<NodeCount(T);
break;
case 7:
if(!T) cout<<"未建立树,请先建树!";
else{
cout<<"\n先序遍历:\n";
NRPreOrder(T);
cout<<"\n中序遍历:\n";
NRInOrder(T);
cout<<"\n后序遍历:\n";
NRPostOrder(T);
}
break;
default:
cout<<"请确认选择项:\n";
}//end switch
}//end while
}
参考资料:找来的,你看看吧!
⑥ 二叉树中的层序遍历
层次遍历就是按二叉树的每一层的顺序来遍历,也就是先访问根结果,然后访问第一层,接着访问第二层...
38题应选:B。大致是先从层次上看出二叉树的根结点为然后从中序中可以看出DBA为左边的结点,CE为右边的结点。然后结合两个可以发现D、E分别是第二层的左右子结点。而B,A则分别为第三层第四层的右结点,C是第三层上的左结点。
⑦ 以二叉连表做存储结构,试编写按层次顺序遍历二叉树的算法
//二叉树,按层次访问
//引用如下地址的思想,设计一个算法层序遍历二叉树(同一层从左到右访问)。思想:用一个队列保存被访问的当前节点的左右孩子以实现层序遍历。
//http://..com/link?url=a9ltidaf-SQzCIsa
typedef struct tagMyBTree
{
int data;
struct tagMyBTree *left,*right;
}MyBTree;
void visitNode(MyBTree *node)
{
if (node)
{
printf("%d ", node->data);
}
}
void visitBTree(queue<MyBTree*> q);
void createBTree(MyBTree **tree)
{
int data = 0;
static int initdata[15] = {1,2,4,0,0,5,0,0,3,6,0,0,7,0,0};//构造成满二叉树,利于查看结果
static int i = 0;
//scanf("%d", &data);
data = initdata[i++];
if (data == 0)
{
*tree = NULL;
}
else
{
*tree = (MyBTree*)malloc(sizeof(MyBTree));
if (*tree == NULL)
{
return;
}
(*tree)->data = data;
createBTree(&(*tree)->left);
createBTree(&(*tree)->right);
}
}
void visitBTreeTest()
{
queue<MyBTree*> q;
MyBTree *tree;
createBTree(&tree);
q.push(tree);
visitBTree(q);
}
void visitBTree(queue<MyBTree*> q)
{
if (!q.empty())
{
MyBTree *t = q.front();
q.pop();
visitNode(t);
if (t->left)
{
q.push(t->left);
}
if (t->right)
{
q.push(t->right);
}
visitBTree(q);
}
}
⑧ 设完成二叉树按层次(同一层自左至右)遍历的算法。
#include "iostream.h"
#include "stdlib.h"
#include "stdio.h"
typedef char ElemType;//定义二叉树结点值的类型为字符型
const int MaxLength=10;//结点个数不超过10个
typedef struct BTNode{
ElemType data;
struct BTNode *lchild,*rchild;
}BTNode,* BiTree;
void CreateBiTree(BiTree &T){//按先序次序输入,构造二叉链表表示的二叉树T,空格表示空树
// if(T) return;
char ch;
ch=getchar(); //不能用cin来输入,在cin中不能识别空格。
if(ch==' ') T=NULL;
else{
if(!(T=(BTNode *)malloc(sizeof(BTNode)))) cout<<"malloc fail!";
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
void PreOrderTraverse(BiTree T){//先序遍历
if(T){
cout<<T->data<<' ';
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
void InOrderTraverse(BiTree T){//中序遍历
if(T){
InOrderTraverse(T->lchild);
cout<<T->data<<' ';
InOrderTraverse(T->rchild);
}
}
void PostOrderTraverse(BiTree T){//后序遍历
if(T){
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout<<T->data<<' ';
}
}
void LevelOrderTraverse(BiTree T){//层序遍历
BiTree Q[MaxLength];
int front=0,rear=0;
BiTree p;
if(T){ //根结点入队
Q[rear]=T;
rear=(rear+1)%MaxLength;
}
while(front!=rear){
p=Q[front]; //队头元素出队
front=(front+1)%MaxLength;
cout<<p->data<<' ';
if(p->lchild){ //左孩子不为空,入队
Q[rear]=p->lchild;
rear=(rear+1)%MaxLength;
}
if(p->rchild){ //右孩子不为空,入队
Q[rear]=p->rchild;
rear=(rear+1)%MaxLength;
}
}
}
//非递归的先序遍历算法
void NRPreOrder(BiTree bt)
{ BiTree stack[MaxLength],p;
int top;
if (bt!=NULL){
top=0;p=bt;
while(p!=NULL||top>0)
{ while(p!=NULL)
{
cout<<p->data;
stack[top]=p;
top++;
p=p->lchild;
}
if (top>0)
{ top--; p=stack[top]; p=p->rchild; }
}
}
}
//非递归的中序遍历算法
void NRInOrder(BiTree bt)
{ BiTree stack[MaxLength],p;
int top;
if (bt!=NULL){
top=0;p=bt;
while(p!=NULL||top>0)
{ while(p!=NULL)
{
stack[top]=p;
top++;
p=p->lchild;
}
if (top>0)
{ top--; p=stack[top];cout<<p->data; p=p->rchild; }
}
}
}
//非递归的后序遍历算法
/*bt是要遍历树的根指针,后序遍历要求在遍历完左右子树后,再访问根。
需要判断根结点的左右子树是否均遍历过。
可采用标记法,结点入栈时,配一个标志tag一同入栈
(1:遍历左子树前的现场保护,2:遍历右子树前的现场保护)。
首先将bt和tag(为1)入栈,遍历左子树;
返回后,修改栈顶tag为2,遍历右子树;最后访问根结点。*/
typedef struct
{
BiTree ptr;
int tag;
}stacknode;
void NRPostOrder(BiTree bt)
{
stacknode s[MaxLength],x;
BiTree p=bt;
int top;
if(bt!=NULL){
top=0;p=bt;
do
{
while (p!=NULL) //遍历左子树
{
s[top].ptr = p;
s[top].tag = 1; //标记为左子树
top++;
p=p->lchild;
}
while (top>0 && s[top-1].tag==2)
{
x = s[--top];
p = x.ptr;
cout<<p->data; //tag为R,表示右子树访问完毕,故访问根结点
}
if (top>0)
{
s[top-1].tag =2; //遍历右子树
p=s[top-1].ptr->rchild;
}
}while (top>0);}
}//PostOrderUnrec
int BTDepth(BiTree T){//求二叉树的深度
if(!T) return 0;
else{
int h1=BTDepth(T->lchild);
int h2=BTDepth(T->rchild);
if(h1>h2) return h1+1;
else return h2+1;
}
}
int Leaf(BiTree T){//求二叉树的叶子数
if(!T) return 0;
else if(!T->lchild&&!T->rchild) return 1;
else return(Leaf(T->lchild)+Leaf(T->rchild));
}
int NodeCount(BiTree T){//求二叉树的结点总数
if(!T) return 0;
else return NodeCount(T->lchild)+NodeCount(T->rchild)+1;
}
void main(){
BiTree T;
T=NULL;
int select;
//cout<<"请按先序次序输入各结点的值,以空格表示空树(输入时可连续输入):"<<endl;
// CreateBiTree(T);
while(1){
cout<<"\n\n请选择要执行的操作:\n";
cout<<"1.创建二叉树\n";
cout<<"2.二叉树的递归遍历算法(前、中、后)\n";
cout<<"3.二叉树的层次遍历算法\n";
cout<<"4.求二叉树的深度\n";
cout<<"5.求二叉树的叶子结点\n";
cout<<"6.求二叉树的结点总数\n";
cout<<"7.二叉树的非递归遍历算法(前、中、后)\n"; //此项可选做
cout<<"0.退出\n";
cin>>select;
switch(select){
case 0:return;
case 1:
cout<<"请按先序次序输入各结点的值,以空格表示空树(输入时可连续输入):"<<endl;
CreateBiTree(T);
break;
case 2:
if(!T) cout<<"未建立树,请先建树!";
else{
cout<<"\n先序遍历:\n";
PreOrderTraverse(T);
cout<<"\n中序遍历:\n";
InOrderTraverse(T);
cout<<"\n后序遍历:\n";
PostOrderTraverse(T);
}
break;
case 3:
cout<<"\n层序遍历:\n";
LevelOrderTraverse(T);
break;
case 4:
cout<<"二叉树的深度为:\n";
cout<<BTDepth(T);
break;
case 5:
cout<<"\n叶子节点数:\n";
cout<<Leaf(T);
break;
case 6:
cout<<"总节点数:\n";
cout<<NodeCount(T);
break;
case 7:
if(!T) cout<<"未建立树,请先建树!";
else{
cout<<"\n先序遍历:\n";
NRPreOrder(T);
cout<<"\n中序遍历:\n";
NRInOrder(T);
cout<<"\n后序遍历:\n";
NRPostOrder(T);
}
break;
default:
cout<<"请确认选择项:\n";
}//end switch
}//end while
}
参考资料:找来的,你看看吧!
⑨ 已知二叉树采用二叉链表存储,编写算法实现层次遍历二叉树
这是我以前写的程序,包含了前序中序后序 层次便利:若只需层序便利 只要把其余的删掉就行!
#include"stdafx.h"
#include<stdlib.h>
#include<math.h>
typedef structbitnode{
char data;
struct bitnode *lchild,*rchild;
}bitnode,*bitree;
typedef structqnode{
bitree data;
struct qnode *next;
}qnode;
typedef struct{
qnode * front;
qnode * rear;
}linkqueue;
intinitqueue(linkqueue &q)
{
q.front=q.rear=(qnode*)malloc(sizeof(qnode));
if(!q.front) exit(OVERFLOW);
q.front->next=NULL;
return 1;
}
intenqueue(linkqueue &q,bitree e)
{
qnode *p;
p=(qnode*)malloc(sizeof(qnode));
if(!p) exit(OVERFLOW);
p->data=e;p->next=NULL;
q.rear->next=p;
q.rear=p;
return 1;
}
intoutqueue(linkqueue & q,bitree &e)
{ qnode *p;
if(q.front==q.rear) return 0;
p=q.front->next;
e=p->data;
q.front->next=p->next;
if(q.rear==p)
q.rear=q.front;
return 1;
}
intcreatebitree(bitree &t)
{
char ch;
scanf("%c",&ch);
if(ch=='.')
t=NULL;
else{
if(!(t=(bitnode*)malloc(sizeof(bitnode))))
exit(OVERFLOW);
t->data=ch;
createbitree(t->lchild);
createbitree(t->rchild);
}
return 1;
}
int visit(char e)
{
printf("%c",e);
return 1;
}
intpreordertraverse(bitree t,int (*visit)(char e))
{
if(t){
if(visit(t->data))
if(preordertraverse(t->lchild,visit))
if(preordertraverse(t->rchild,visit))return 1;
return 0;
}else return 1;
}
intinordertraverse(bitree t,int (*visit)(char e))
{
if(t){
if(inordertraverse(t->lchild,visit))
if(visit(t->data))
if(inordertraverse(t->rchild,visit))return 1;
return 0;
}else return 1;
}
intpostordertraverse(bitree t,int (*visit)(char e))
{
if(t){
if(postordertraverse(t->lchild,visit))
if(postordertraverse(t->rchild,visit))
if(visit(t->data))
return 1;
return 0;
}else return 1;
}
voidlevelordertraverse(bitree t)
{
linkqueue q;
bitree e;
initqueue(q);
enqueue(q,t);
while(outqueue(q,e)){
if(e)
{
visit(e->data);
enqueue(q,e->lchild);
enqueue(q,e->rchild);
}
}
}
int main(int argc,char* argv[])
{
bitree t;
printf("输入字符:");
createbitree(t);
printf("输出先序遍历:");
preordertraverse(t, visit);
printf("\n");
printf("输出中序遍历:");
inordertraverse(t,visit);
printf("\n");
printf("输出后序遍历:");
postordertraverse(t,visit);
printf("\n");
printf("输出层序遍历:");
levelordertraverse(t);
printf("\n");
return 0;
}
⑩ 设二叉树以二叉链表存储,试设计算法,实现二叉树的层序遍历。
按层次遍历算法如下:
#include <iostream>
using namespace std;
typedef struct treenode { //树结点结构
int data;
struct treenode *left;
struct treenode *right;
}TreeNode;
typedef struct stack{ //栈结点结构
TreeNode *node;
struct stack *next;
}STACK;
void Traversal(TreeNode *root)
{
STACK *head = NULL;
STACK *tail = NULL;
if (root != NULL) //根结点入栈
{
head = new STACK();
head->next = NULL;
head->node = root;
tail = head;
}
while(head != NULL)
{
STACK *temp;
if (head->node->left != NULL) //栈顶结点的左结点入栈
{
temp = new STACK();
temp->next = NULL;
temp->node = head->node->left;
tail->next = temp;
tail = temp;
}
if (head->node->right != NULL) //栈顶结点的右结点入栈
{
temp = new STACK();
temp->next = NULL;
temp->node = head->node->right;
tail->next = temp;
tail = temp;
}
cout<<head->node->data<<endl; //结点出栈
temp = head;
head = head->next;
delete(head);
}
}