二叉树的层次遍历说简单也简单,说难也难。下面是我读编程之美和研究数据结构结合大神的博客来实现的二叉树的层次遍历,这里只给出三种简单高效的解法。
数据结构
typedef char datatype;
typedef struct bintreenode
{
datatype data;
struct bintreenode* lchild,*rchild;
}bintree;
方法一
采用广度优先遍历的思想,利用队列实现二叉树的层次遍历。
void levelorder(bintree* t)
{
queue<bintree*> que;
bintree* p;
if(t)
que.push(t);
do
{
p = que.front();
que.pop();
cout << p->data << " ";
if (p->lchild)
que.push(p->lchild);
if (p->rchild)
que.push(p->rchild);
} while (!que.empty());
}
方法二
有时需要分层遍历二叉树,这时比较好的解法是在入队列的时候在每层的末尾添加一个标识符。具体解法如下
//插入一个空指针表示一层的结束
void levelorder3(bintree* t)
{
queue<bintree*> que;
bintree* p;
que.push(t);
que.push();
while(!que.empty())
{
p = que.front();
que.pop(0);
if (p)
{
cout << p->data << " ";
if (p->lchild)
que.push(p->lchild);
if (p->rchild)
que.push(p->rchild);
}
else if (!que.empty())
{
que.push(0);
cout << endl;
}
}
}
方法三
这个方法是我自己实现的,不使用STL中的队列,而是自己建立一个队列来实现。
void levelorder(bintree* t)
{
//建立循环队列,能满足7层的满二叉树遍历
const int maxsize = 64;
bintree* queue[maxsize];
int front,rear;
//利用队列实现层次遍历
/*front 指向最先进入的元素,rear指向队尾(待插入的元素位置),不考虑队列满的情况(rear+1)%maxsize = front*/
front = 0;rear = 1;
queue[0] = t; //根结点插入
bintree* p;
while(front != rear)
{
p = queue[front];
front = (front+1)%maxsize;
printf("%c",p->data);
//上面出了一次队列,所以不用检查队列满的情况。
if (p->lchild != NULL)
{
queue[rear] = p->lchild;
rear = (rear+1)%maxsize;
}
if (p->rchild != NULL && (rear+1)%maxsize != front)
{
//(rear+1)%maxsize != front,检查防止队列满的情况。
queue[rear] = p->rchild;
rear = (rear+1)%maxsize;
}
}
}