一、按层遍历二叉树
很好理解,其实就是图的广度优先遍历,伪代码如下:
root入队
while 队不空
top=出队
打印top节点的权值
如果top节点有左子树,将左子树入队
如果top节点有右子树,将右子树入队
具体代码如下:
void layer(tlink root){
qlink queue=createqueue();
enqueue(queue,root);
tlink top;
while(!emptyqueue(queue)){
top=(tlink)dequeue(queue);
printf("%d ",top->vertex);
if(top->left)
enqueue(queue,top->left);
if(top->right)
enqueue(queue,top->right);
}
}
二、按层遍历二叉树并且同层节点在同一行输出
如:
对此二叉树遍历的结果应该是:
1,
2 , 3
4, 5, 6
7, 8
第一种方法,就是利用递归的方法,按层进行打印,我们把根节点当做第0层,之后层次依次增加,如果我们想打印第二层怎么办呢,利用递归的代码如下:
int zigzag2(tlink root,int height){
if(!root || height<0)
return 0;
if(!height){
printf("%d ",root->vertex);
return 1;
}
return zigzag2(root->left,height-1)+zigzag2(root->right,height-1);
}
调用函数的代码如下:
for(int i=0;i<10;i++){
if(!zigzag2(tree,i))
break;
printf("\n");
}
很明显。这个程序的效率极其低下。
第二种方法,我们可以设置两个队列,想象一下队列的特点,就是先进先出,首先把第0层保存在一个队列中,然后按节点访问,并把已经访问节点的左右孩子节点放在第二个队列中,当第一个队列中的所有节点都访问完成之后,交换两个节点。这样重复下去,知道所有层的节点都被访问,这样做的代价就是空间复杂度有点高。
代码如下:
void zigzag0(tlink root){
qlink queue1=createqueue(),queue2=createqueue();
tlink cur;
enqueue(queue1,root);
while(!emptyqueue(queue1)){
cur=(tlink)dequeue(queue1);
printf("%d ",cur->vertex);
if(cur->left)
enqueue(queue2,cur->left);
if(cur->right)
enqueue(queue2,cur->right);
if(emptyqueue(queue1)){
printf("\n");
exchangequeue(queue1,queue2);
}
}
free(queue1);
free(queue2);
}
第三种方法就是设置双指针,一个指向访问当层开始的节点,一个指向访问当层结束节点的下一个位置:
这是第一层访问的情况,当访问第0层之后的结构如下,把第0层的所有子节点加入之后:
访问完第1层之后:
代码如下:
void zigzag1(tlink root){
qlink queue=createqueue();
int current=0,end;
tlink top;
enqueue(queue,root);
while(current < queue->size){
end=queue->size;
while(current < end){
top=(tlink)queue->data[current];
printf("%d ",top->vertex);
if(top->left)
enqueue(queue,top->left);
if(top->right)
enqueue(queue,top->right);
current++;
}
printf("\n");
}
}
测试代码如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define FIX(function,tree) printf("%s:",#function);function(tree);printf("\n")
#define QCAPACITY 101
struct Queue{
int size;
int head;
int rear;
void *data[QCAPACITY];
};
typedef struct Queue *qlink;
struct Tnode{
int vertex;
struct Tnode *left;
struct Tnode *right;
};
typedef struct Tnode *tlink;
qlink createqueue(void){
qlink queue=malloc(sizeof(struct Queue));
queue->size=queue->head=queue->rear=0;
return queue;
}
int emptyqueue(qlink queue){
return queue->size==0;
}
void enqueue(qlink queue,void *item){
queue->data[queue->rear]=item;
queue->rear=(queue->rear+1)%QCAPACITY;
queue->size++;
}
void *dequeue(qlink queue){
void *ret=queue->data[queue->head];
queue->head=(queue->head+1)%QCAPACITY;
queue->size--;
return ret;
}
void prefix(tlink root){
if(!root)
return;
printf("%d ",root->vertex);
prefix(root->left);
prefix(root->right);
}
void infix(tlink root){
if(!root)
return;
infix(root->left);
printf("%d ",root->vertex);
infix(root->right);
}
void suffix(tlink root){
if(!root)
return;
suffix(root->left);
suffix(root->right);
printf("%d ",root->vertex);
}
tlink createnode(int vertex){
tlink node=malloc(sizeof(struct Tnode));
node->vertex=vertex;
node->left=node->right=NULL;
return node;
}
tlink insertnode(tlink tree,int vertex){
if(!tree)
return createnode(vertex);
if(tree->vertex > vertex)
tree->left=insertnode(tree->left,vertex);
else
tree->right=insertnode(tree->right,vertex);
return tree;
}
void exchangequeue(qlink queue1,qlink queue2){
qlink tmp=malloc(sizeof(struct Queue));
memcpy(tmp,queue1,sizeof(struct Queue));
memcpy(queue1,queue2,sizeof(struct Queue));
memcpy(queue2,tmp,sizeof(struct Queue));
free(tmp);
}
void zigzag0(tlink root){
qlink queue1=createqueue(),queue2=createqueue();
tlink cur;
enqueue(queue1,root);
while(!emptyqueue(queue1)){
cur=(tlink)dequeue(queue1);
printf("%d ",cur->vertex);
if(cur->left)
enqueue(queue2,cur->left);
if(cur->right)
enqueue(queue2,cur->right);
if(emptyqueue(queue1)){
printf("\n");
exchangequeue(queue1,queue2);
}
}
free(queue1);
free(queue2);
}
void zigzag1(tlink root){
qlink queue=createqueue();
int current=0,end;
tlink top;
enqueue(queue,root);
while(current < queue->size){
end=queue->size;
while(current < end){
top=(tlink)queue->data[current];
printf("%d ",top->vertex);
if(top->left)
enqueue(queue,top->left);
if(top->right)
enqueue(queue,top->right);
current++;
}
printf("\n");
}
}
int zigzag2(tlink root,int height){
if(!root || height<0)
return 0;
if(!height){
printf("%d ",root->vertex);
return 1;
}
return zigzag2(root->left,height-1)+zigzag2(root->right,height-1);
}
void layer(tlink root){
qlink queue=createqueue();
enqueue(queue,root);
tlink top;
while(!emptyqueue(queue)){
top=(tlink)dequeue(queue);
printf("%d ",top->vertex);
if(top->left)
enqueue(queue,top->left);
if(top->right)
enqueue(queue,top->right);
}
}
int main(int argc,char *argv[]){
int data[]={9,6,8,12,5,13,3,4,0,7,2,14,1};
int size=sizeof data/sizeof *data;
tlink tree=createnode(data[0]);
for(int i=1;i<size;i++)
tree=insertnode(tree,data[i]);
FIX(prefix,tree);
FIX(infix,tree);
FIX(suffix,tree);
FIX(layer,tree);
zigzag0(tree);
zigzag1(tree);
for(int i=0;i<10;i++){
if(!zigzag2(tree,i))
break;
printf("\n");
}
return 0;
}
最后打印结果如下:
前三行分别是前序、中序、后序