层序遍历二叉树,以及拓展问题,同层同行输出

一、按层遍历二叉树

很好理解,其实就是图的广度优先遍历,伪代码如下:

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;
}


最后打印结果如下:

前三行分别是前序、中序、后序



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值