您的位置:首页 > 其它

广度优先搜索二叉树

2013-09-13 16:36 134 查看
深度优先搜索二叉树包括递归和非递归的,我的另个一博客里面写的有。

这里阐述一下广度优先搜索遍历:

其主要思想是采用队列的形式,

首先根节点入队,循环判断当前队列非空,访问队列头节点,然后出队列,

如果左子树非空,左子树根节点入队;

如果右子树非空,右子树根节点入队。

代码如下:

Queue.h

#ifndef QUEUE_H_
#define QUEUE_H_

typedef int Item;
//树的结构
typedef struct Node_t
{

Item data;
struct 	Node_t* lchild;
struct	Node_t* rchild;
}node_t, *tree;

//队列元素的结构
typedef struct node
{
tree tr;
struct node* next;
}Node,*PNode;

//队列的头尾指针
typedef struct
{
PNode front;
PNode rear;
int size;

}Queue;

/*构造一个空队列*/
Queue* InitQueue();

/*销毁一个队列*/
void DestroyQueue(Queue* pqueue);

/*清空一个队列*/
void ClearQueue(Queue* pqueue);

/*判断一个队列是否为空*/
int IsEmpty(Queue* pqueue);

/*返回队列大小*/
int GetSize(Queue* pqueue);

/*返回对头元素*/
PNode GetFront(Queue* pqueue,tree pitem);

/*返回队尾元素*/
PNode GetRear(Queue* pqueue,tree pitem);

/*将新元素入队*/
PNode EnQueue(Queue* pqueue,tree item);

/*将队头元素出队*/
PNode DelQueue(Queue* pqueue,tree* pitem);

/*遍历队列,并对各项数据调用visit函数*/
void QueueTraverse(Queue* pqueue,void (*visit)(PNode));

#endif


Queue.c

#include "Queue.h"
#include <malloc.h>
#include <stdio.h>

/*构造一个空队列*/
Queue* InitQueue()
{
Queue* pqueue = (Queue*)malloc(sizeof(Queue));
if(pqueue!=NULL)
{
pqueue->front = NULL;
pqueue->rear = NULL;
pqueue->size = 0;

}
return pqueue;
}

/*销毁一个队列*/
void DestroyQueue(Queue* pqueue)
{
if(IsEmpty(pqueue)!=1)
ClearQueue(pqueue);

free(pqueue);
}

/*清空一个队列*/
void ClearQueue(Queue* pqueue)
{
while(IsEmpty(pqueue)!= 1)
{
DelQueue(pqueue,NULL);

}
}
/*判断一个队列是否为空*/
int IsEmpty(Queue* pqueue)
{
if(pqueue->front==NULL&&pqueue->rear==NULL&& pqueue->size ==0)
return 1;
else
return 0;
}
/*返回一个队列的大小*/
int GetSize(Queue* pqueue)
{
return pqueue->size;
}
/*返回队头元素*/
PNode GetFront(Queue* pqueue,tree pitem)
{
if(IsEmpty(pqueue)!=1&& pitem!=NULL)//队列不空
pitem = pqueue->front->tr;
return pqueue->front;

}

/*返回队尾元素*/
PNode GetRear(Queue *pqueue,tree pitem)
{
if(IsEmpty(pqueue)!=1&& pitem!=NULL)
{
pitem = pqueue->rear->tr;
}
return  pqueue->rear;

}
/*将新元素入队列*/
PNode EnQueue(Queue* pqueue,tree item)
{

PNode pnode = (PNode)malloc(sizeof(Node));

if(pnode!=NULL)
{
pnode->tr = item;
pnode->next = NULL;
if(IsEmpty(pqueue))
{
pqueue->front = pnode;
}
else
{
pqueue->rear->next = pnode;
}
pqueue->rear = pnode;
pqueue->size++;

}
return pnode;
}

/*队头元素出队*/
PNode DelQueue(Queue* pqueue, tree* pitem)
{
PNode pnode = pqueue->front;
if(IsEmpty(pqueue)!=1&&pnode!=NULL)
{
//if(pitem!=NULL)
*pitem = pnode->tr;
pqueue->size--;
pqueue->front = pnode->next;
free(pnode);
if(pqueue->size ==0)
pqueue->rear =NULL;

}

return pqueue->front;
}

/*遍历队列*/
void QueueTraverse(Queue* pqueue,void (*visit)(PNode))
{

PNode pnode = pqueue->front;
int i = pqueue->size;
while(i--)
{
visit(pnode);
pnode = pnode->next;
}

}


test.c

#include "Queue.h"
#include <stdio.h>
#include <stdlib.h>
void visit(PNode pq)
{

printf("该节点的元素为: %d\n",pq->tr->data );

}
//广度优先遍历二叉树
void Bitree_traverse(Queue *pq, tree p)
{

tree t;
if(p!= NULL)
EnQueue(pq,p);//根节点入队
while(IsEmpty(pq)!= 1)//队列循环判空
{
visit(pq->front);//访问队列头结点,也是广度优先访问的数据结点
DelQueue(pq,&t);//队头元素出队,只有获得队头元素,才能让它的左右子结点入队。

if(t->lchild!=NULL)
EnQueue(pq,t->lchild);//左子树根节点入队
if(t->rchild!=NULL)
EnQueue(pq,t->rchild);//右子树根节点入队

}
}

int main()
{

Queue* pq = InitQueue();
tree p;
p= (tree)malloc(sizeof(Node_t));
p->data = 1;
p->lchild = (tree)malloc(sizeof(Node_t));

p->lchild->data = 2;
p->lchild->lchild = (tree)malloc(sizeof(Node_t));
p->lchild->rchild =NULL;
p->lchild->lchild->data = 3;

p->lchild->lchild->lchild =NULL;
p->lchild->lchild->rchild =(tree)malloc(sizeof(Node_t));

p->lchild->lchild->rchild->data =4;

p->lchild->lchild->rchild->lchild=NULL;
p->lchild->lchild->rchild->rchild =NULL;

p->rchild = (tree)malloc(sizeof(Node_t));

p->rchild->data = 5;
p->rchild->lchild = (tree)malloc(sizeof(Node_t));
p->rchild->lchild->data = 6;

p->rchild->lchild->lchild =NULL;
p->rchild->lchild->rchild =NULL;
p->rchild->rchild = (tree)malloc(sizeof(Node_t));

p->rchild->rchild->data = 7;
p->rchild->rchild->lchild =NULL;
p->rchild->rchild->rchild =NULL;
//广度优先遍历二叉树

printf("广度优先遍历当前的二叉树:\n");

Bitree_traverse(pq, p);
free(p->rchild->rchild);
free(p->rchild->lchild);
free(p->lchild->lchild->rchild);
free(p->lchild->lchild);
free(p->lchild);
free(p->rchild);
free(p);
ClearQueue(pq);

if(IsEmpty(pq))
printf("成功将队列置为空\n");
DestroyQueue(pq);

printf("队列已被销毁\n");
return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: