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

时间:2022-03-08 10:10:03
写了一个二叉树的程序,只是层次遍历不会写,请大家帮帮忙~~~
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);
}



拜托拜托,很急~~~

7 个解决方案

#1


帮顶··········

#2


学习

#3


算法很简单,首先一个空队列,将根结点入队,然后循环从队列中取结点,对于每一个取出来的结点,如果有左孩子则将左孩子入队,如果有右孩子则将右孩子入队,这样循环直到队列为空,最后出队的序列就是层次遍历的序列

#4



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楼的描述的思想很清楚,在此我就不再赘言了。给出代码实现,仅供参考。

#5


层次遍历不会??

给你一段二叉树的


#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");
}



#6


这个就是层次遍历,怕你看不明白,上面就贴了上下文。

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

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");
}

#7


我需要在我程序上进行的扩写,
还有,队的申明和层次结构的输出,不是就简单的一个层次结构算法~~

#1


帮顶··········

#2


学习

#3


算法很简单,首先一个空队列,将根结点入队,然后循环从队列中取结点,对于每一个取出来的结点,如果有左孩子则将左孩子入队,如果有右孩子则将右孩子入队,这样循环直到队列为空,最后出队的序列就是层次遍历的序列

#4



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楼的描述的思想很清楚,在此我就不再赘言了。给出代码实现,仅供参考。

#5


层次遍历不会??

给你一段二叉树的


#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");
}



#6


这个就是层次遍历,怕你看不明白,上面就贴了上下文。

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

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");
}

#7


我需要在我程序上进行的扩写,
还有,队的申明和层次结构的输出,不是就简单的一个层次结构算法~~