采用循环队列解决二叉树的层次遍历:
思路:对成功创建的二叉链树进行层次遍历,这里采用循环队列的思想来解决,主要是从根节点开始,将结点进队(下标rear+1,接着进队),然后(front + 1)将元素出对,此时,对出对结点的左右孩子进行判断,有孩子,将孩子进队,先判断左孩子,再判断右孩子,接下来的操作与之前的一样,将孩子进队,接下来的操作与之前一样。
下图红色表示5是将其出对。
代码如下:
#include <stdio.h>
#include <stdio.h>
#include <malloc.h>
#define maxsize 50
typedef char elemtype;
typedef struct node{
elemtype data;
struct node *lchild;//指向左孩子
struct node *rchild;//指向右孩子
}bnode;
//构造二叉树
void createtree(bnode *&b, char *str)
{
bnode *st[maxsize],*p ; //创建结构体类型的指针栈数组
int top = -1,k,j=0; //top是 数组下标,初始为-1;
char ch = str[j];
b = NULL; //空二叉树
while(ch != '\0')
{
switch(ch)
{
//下面3步是用来将数据入栈和设置k值的作用.
case '(': st[++top]=p;k=1;break;
case ')': top--;break;
case ',': k = 2;break;
default:
p = (bnode *)malloc(sizeof(bnode)); //创建一个结构体树节点指针类型
//创建完成之后,将数据赋值给创建的节点,并新创建的节点的左右指针初始化为空(NULL)
p ->data = ch;
p ->lchild =NULL;
p ->rchild =NULL;
if(b==NULL) //参数中传入的b是空,这一步用来构建根节点。
{
b = p;
}
else{
switch(k) //构建完根结点之后,将循环传入的字符元素data经过k判断是当作左孩子还是右孩子。
{
case 1:st[top]->lchild = p;break;
case 2:st[top]->rchild = p;break;
}
}
}
j++;
ch = str[j];
}
}
void aspectsearch(bnode *b)//层次遍历(递归思想)
{
if(b) //只要结点不为空
{
int front,rear; //这里要用到循环队列的思想
front = rear = 0;
bnode *que[maxsize]; //定义一个结点类型的指针数组,数组存储的是指向每个结点的指针 ,最为循环队列
bnode *p;
//下面两步是将结点进对
rear = (rear+1)%maxsize;
que[rear] =b;
while(rear!=front)//这里表示循环队列不为空多列
{
//下面是出对,并打印出对元素。 先移动在出队
front = (front+1)%maxsize; //下标+1
p = que[front]; //再出对
printf("%c ", p->data);
if(p->lchild != NULL) //出对结点元素,再判断结点的左右孩子,如果有就将其进队。
{
rear = (rear +1)%maxsize;
que[rear] = p->lchild;
}
if(p->rchild!=NULL)
{
rear = (rear+1)%maxsize;
que[rear] = p->rchild;
}
}
}
}
int main()
{
bnode *b;
printf("创建二叉树; \n");
createtree(b,"A(B(D(,G)),C(E,F))");
printf("层次遍历的结果: ");
aspectsearch(b);
return 0;
}
程序运行如下: