关于二叉树层次遍历算法的队列程序出错(很可能是链式队列的指针出问题)

猫已经找不回了 2008-09-11 10:05:01
我首先建了一个二叉树,然后想用队列缓存的办法来实现二叉树的层次遍历。二叉树建立式单独调试过,没有问题。但是队列则出现了问题。调试报了很多数据结构引用错误等error,这里不一一报出,求人帮忙找出原因,实在很不解。下面贴出代码,谢谢有心人了。



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

ListQueue *InitQueue() //初始化一个链式队列,返回
{
DataQueue *d;
d=(DataQueue *)malloc(sizeof(DataQueue));
ListQueue *q;
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;
q->front->next=a->next;
free(a);
return p;
}
else
return NULL;
}

void level_travel(LinkTree *s) //层次遍历一棵头节点为s的树
{
printf("init queue successful.\n");
ListQueue *q;
LinkTree *p;
q=InitQueue();
printf("init queue successful.\n");
p=s;
InQueue(q,p);
while(q->front!=q->rear)
{
p=DeQueue(q);
printf(" %d",p->data);
if(p->lchild)
InQueue(q,p->lchild);
if(p->rchild)
InQueue(q,p->rchild);
}
printf("\n");
}




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");
level_travel(s);
printf("\n");
}
...全文
283 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
4楼讲的没错。。好几天没来,那天忽然发现了。。。现在可以了.
dropship 2008-09-15
  • 打赏
  • 举报
回复
不给你贴全部代码了,你两个函数写错了。没有考虑队列空的时候。
入队列时,如果队列为空,则需要把front指针next指向队头
出队列是,如果队列为空,需要把rear指针和front置同。
已经改好,打印结果为:
OK,create C.
OK,create Tree.
5 4 3 0 13 6 9 8 12 100 56
init queue successful.
init queue successful.
init queue successful.
5 4 13 3 6 100 0 9 56 8 12

---------------------------------------
修改代码:
void InQueue(ListQueue *q,LinkTree *p) //把二叉树节点的指针p写入队列的data中
{
DataQueue *a;
a=(DataQueue *)malloc(sizeof(DataQueue));
a->data=p;
a->next=NULL;
//问题在这里,第一个元素从队头出去的时候,队列为空
//但此时加入新元素时,你没有将front指针的next域指向它
//第一次出队之所以正确,是因为你第一次front和rear一样,所以没错误
if(q->front == q->rear)
q->front->next = a;
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;
q->front->next=a->next;
free(a);
//如果队空,则rear指针应该和front相同
if(q->front->next == NULL)
q->rear = q->front;
return p;
}
else
return NULL;
}

BTW:你的代码写的还不错,呵呵。
dfrtgvb 2008-09-15
  • 打赏
  • 举报
回复
你两个函数写错了。没有考虑队列空的时候。
dropship 2008-09-14
  • 打赏
  • 举报
回复
看起来蛮简单的程序,等我装好vs给你看下
dropship 2008-09-14
  • 打赏
  • 举报
回复
现在没时间调,你可以把单个问题拿出来。
cacheJava 2008-09-14
  • 打赏
  • 举报
回复
1. 耐心调试一下,有利于提高
2. 尽量锻炼认真思考后,有了完整的思路,然后再开始写程序。
3. 尽量写完就可以清晰保证正确,减少debug过程,有助于上升算法实现能力

33,007

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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