用c++实现二叉树的层次遍历

liang_8918 2009-06-23 09:11:42
写了一个二叉树的程序,只是层次遍历不会写,请大家帮帮忙~~~
ps:想用队列来做的



#include<iostream.h>
template<class T>
class BTNode 结点类
{
public:
BTNode(){lChild = rChild = NULL;}
BTNode(T x)
{
element = x; lChild = rChild = NULL;
}
BTNode(T x,BTNode<T>* l,BTNode<T>* r)
{
element = x; lChild = l; rChild = r;
}
T element;
BTNode<T>* lChild, *rChild;
};

/*template<class T>
class Queue
{
public:
bool EnQueue(T x)
{
q[(rear=(rear+1)%26)]=x;
return true;
}
bool DeQueue()
{
front = (front+1)%26;
return true;
}
int front,rear;
T *q;
};*/

template<class T>
class BinaryTree
{
public:
// friend class Queue;
BinaryTree(){root = NULL;}
// ~BinaryTree();
// bool ISEmpty();
// void Clear();
// bool Root(T x);
int Size()
{
return Size(root);
}
int Size(BTNode<T>* t)
{
if(!t) return 0;
else return Size(t -> lChild) + Size(t -> rChild) + 1;
}



void MakeTree(T x,BinaryTree<T>& left, BinaryTree<T>& right)
{
if(root || &left == &right) return;
root = new BTNode<T>(x,left.root,right.root);
left.root = right.root = NULL;
}

void BreakTree(T x , BinaryTree<T>& left, BinaryTree<T>& right)
{
if(!root || &left == &right || left.root || right.root) return;
x = root -> element;
left.root = root -> lChild;right.root = root -> rChild;
delete root; root = NULL;
}


void PreOrder() //先序
{
}
void PreOrder(void (*Visit)(T x))
{
PreOrder(Visit,root);
}
void PreOrder(void (*Visit)(T x),BTNode<T>* t)
{
if(t)
{
Visit(t -> element);
PreOrder(Visit,t -> lChild);
PreOrder(Visit,t -> rChild);
}
}

void InOrder() //中序
{
}
void InOrder(void (*Visit)(T x))
{
InOrder(Visit,root);
}
void InOrder(void (*Visit)(T x),BTNode<T>* t)
{
if(t)
{
InOrder(Visit,t -> lChild);
Visit(t -> element);
InOrder(Visit,t -> rChild);
}
}


void PostOrder() //后序
{
}
void PostOrder(void (*Visit)(T x))
{
PostOrder(Visit,root);
}
void PostOrder(void (*Visit)(T x),BTNode<T>* t)
{
if(t)
{
PostOrder(Visit,t -> lChild);
PostOrder(Visit,t -> rChild);
Visit(t -> element);
}
}

void LevelOrder() //层次(需要改动的地方)
{
}
void LevelOrder(void (*Visit)(T x))
{
LevelOrder(Visit,root);
}
void LevelOrder(void (*Visit)(T x),BTNode<T>* t)
{
if(t)
{ Visit(t -> element);

LevelOrder(Visit,t -> lChild);

LevelOrder(Visit,t -> rChild);
// else if(t->rChild != NULL)

}
}

protected:
BTNode<T>* root;

};

template<class T>
void Visit(T x)
{
cout<<x<<" ";
}

/*template<class T>
void BinaryTree<T>::MakeTree(T x,BinaryTree<T>& left, BinaryTree<T>& right)
{
if(root || &left == &right) return;
root = new BTNode<T>(x,left.root,right.root);
left.root = right.root = NULL;
}

template<class T>
void BinaryTree<T>::BreakTree(T x , BinaryTree<T>& left, BinaryTree<T>& right)
{
if(!root || &left == &right || left.root || right.root) return;
x = root -> element;
left.root = root -> lChild;right.root = root -> rChild;
delete root; root = NULL;
}

template<class T>
void BinaryTree<T>::PreOrder(void (*Visit)(T x))
{
PreOrder(VIsit,root);
}
template<class T>
void BinaryTree<T>::PreOrder(void (*VIsit)(T x),BTNode<T>* t)
{
if(t)
{
Visit(t -> element);
PreOrder(VIsit,t -> lChild);
PreOrder(Visit,t -> rChild);
}
}*/

void main()
{
BinaryTree<char> a,b,w,x,y,z;
// char e;
int f;
y.MakeTree('E',a,b);
z.MakeTree('F',a,b);
x.MakeTree('C',y,z);
y.MakeTree('A',a,b);
z.MakeTree('G',a,b);
w.MakeTree('D',y,z);
z.MakeTree('B',w,x);
cout<<"先序遍历的结果为:";
z.PreOrder(Visit);
cout<<endl;
cout<<"中序遍历的结果为:";
z.InOrder(Visit);
cout<<endl;
cout<<"后序遍历的结果为:";
z.PostOrder(Visit);
cout<<endl;
f = z.Size();
cout<<"二叉树元素的个数为:"<<f<<endl;
z.LevelOrder(Visit);

// z.BreakTree(e,y,x);
// z.PreOrder(Visit);
}



拜托拜托,很急~~~
...全文
615 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
这个就是层次遍历,怕你看不明白,上面就贴了上下文。

基本上就是按照左,右,入队,出队打印,(同时把打印对象的左,右子树入队就可以了)

void level_travel(LinkTree *s) //层次遍历一棵头节点为s的树
{
int sta,top,sin[100],cen; //标记树的层次
sta=0;
top=0;
cen=1;
ListQueue *q;
LinkTree *p;
DataQueue *test;
q=InitQueue();
p=s;
InQueue(q,p);
sin[top++]=cen;
while(q->front!=q->rear)
{
p=DeQueue(q);
if(sin[sta]>sin[sta-1]||sta==0)
{
printf("\n第%d层节点:",sin[sta]);
}
printf(" %d ",p->data);
sta++;
if(p->lchild)
{
InQueue(q,p->lchild);
sin[top++]=sin[sta-1]+1;
}
if(p->rchild)
{
InQueue(q,p->rchild);
sin[top++]=sin[sta-1]+1;
}
test=q->front->next;
}
printf("\n");
}

  • 打赏
  • 举报
回复
层次遍历不会??

给你一段二叉树的


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>

typedef struct Lnode
{
int data;
struct Lnode *lchild;
struct Lnode *rchild;
}LinkTree; //树的节点

typedef struct Dnode
{
LinkTree *data;
struct Dnode *next;
}DataQueue; //队列的节点

typedef struct LQ
{
DataQueue *front, *rear;
}ListQueue; //链式队列


void insert_tree(LinkTree *s,int data) //在s为头节点的二叉树上按lchild<parent<rchild原则添加节点,节点数据为data
{
LinkTree *temp,*b;
while(s!=NULL)
{
b=s;
if(data<s->data)
s=s->lchild;
else if(data>s->data)
s=s->rchild;
}
temp=(LinkTree *)malloc(sizeof(LinkTree));
temp->data=data;
temp->lchild=temp->rchild=NULL;
if(data<b->data)
b->lchild=temp;
else if(data>b->data)
b->rchild=temp;
}

LinkTree * Create_tree(int n,int *pdata) //创建一棵树,pdata为连续存储的将要写入树中的data的地址,n为节点个数
{
int i;
LinkTree *temp,*s;
i=1;
s=(LinkTree *)malloc(sizeof(LinkTree));
s->data=pdata[0];
s->lchild=s->rchild=NULL;
// printf("%d.\n",pdata[0]);
temp=s;
printf("OK,create C.\n");
while(i<n)
{
insert_tree(temp,pdata[i]);
i++;
}
printf("OK,create Tree.\n");
return s;
}


void dis_pre_tree(LinkTree *s) //先序遍历头节点为s的树
{
if(s==NULL)
return;
printf("%d ",s->data);
if(s->lchild!=NULL)
dis_pre_tree(s->lchild);
if(s->rchild!=NULL)
dis_pre_tree(s->rchild);
}

void dis_post_tree(LinkTree *s) //后序遍历头节点为s的树
{
if(s==NULL)
return;
if(s->lchild!=NULL)
dis_post_tree(s->lchild);
if(s->rchild!=NULL)
dis_post_tree(s->rchild);
printf("%d ",s->data);
}

ListQueue *InitQueue() //初始化一个链式队列,返回
{
DataQueue *d;
ListQueue *q;
d=(DataQueue *)malloc(sizeof(DataQueue));
q=(ListQueue *)malloc(sizeof(ListQueue));
q->front=d;
q->front->next=NULL;
q->rear=q->front;
printf("init queue successful.\n");
return q;
}

void InQueue(ListQueue *q,LinkTree *p) //把二叉树节点的指针p写入队列的data中
{
DataQueue *a;
a=(DataQueue *)malloc(sizeof(DataQueue));
a->data=p;
a->next=NULL;
q->rear->next=a;
q->rear=a; //rear对应最后进对的节点
}

LinkTree *DeQueue(ListQueue *q) //出队
{
DataQueue *a;
LinkTree *p;
if(q->front!=q->rear)
{
a=q->front->next; //q->front->next对应先入队的节点
p=a->data;
if(q->front->next!=q->rear)
q->front->next=a->next;
else if(q->front->next==q->rear) //front和rear重合要初始化一次
{
q->rear=q->front;
q->front->next=NULL;
}
free(a);
return p;

}
else
return NULL;
}

void level_travel(LinkTree *s) //层次遍历一棵头节点为s的树
{
int sta,top,sin[100],cen; //标记树的层次
sta=0;
top=0;
cen=1;
ListQueue *q;
LinkTree *p;
DataQueue *test;
q=InitQueue();
p=s;
InQueue(q,p);
sin[top++]=cen;
while(q->front!=q->rear)
{
p=DeQueue(q);
if(sin[sta]>sin[sta-1]||sta==0)
{
printf("\n第%d层节点:",sin[sta]);
}
printf(" %d ",p->data);
sta++;
if(p->lchild)
{
InQueue(q,p->lchild);
sin[top++]=sin[sta-1]+1;
}
if(p->rchild)
{
InQueue(q,p->rchild);
sin[top++]=sin[sta-1]+1;
}
test=q->front->next;
}
printf("\n");
}



void main()
{
int n=11;
int a[]={5,13,6,9,12,4,8,3,0,100,56};
LinkTree *s;
s=Create_tree(n,a);
dis_pre_tree(s);
printf("\n");
dis_post_tree(s);
printf("\n");
level_travel(s);
printf("\n");
}



Kevin_Perkins 2009-06-23
  • 打赏
  • 举报
回复

void LevelOrder()
{
if (root == NULL)
return;

queue<BTNode<T>*> travQueue;
travQueue.push(root);

while (!travQueue.empty())
{
Visit(travQueue.front()->element);
if (travQueue.front()->lChild != NULL)
travQueue.push(travQueue.front()->lChild);
if (travQueue.front()->rChild != NULL)
travQueue.push(travQueue.front()->rChild);
travQueue.pop();
}
}

3楼的描述的思想很清楚,在此我就不再赘言了。给出代码实现,仅供参考。
w0911h 2009-06-23
  • 打赏
  • 举报
回复
算法很简单,首先一个空队列,将根结点入队,然后循环从队列中取结点,对于每一个取出来的结点,如果有左孩子则将左孩子入队,如果有右孩子则将右孩子入队,这样循环直到队列为空,最后出队的序列就是层次遍历的序列
steven_007 2009-06-23
  • 打赏
  • 举报
回复
学习
sui_yuan_zhe 2009-06-23
  • 打赏
  • 举报
回复
帮顶··········
liang_8918 2009-06-23
  • 打赏
  • 举报
回复
我需要在我程序上进行的扩写,
还有,队的申明和层次结构的输出,不是就简单的一个层次结构算法~~

64,680

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧