【算法学习笔记】二叉树遍历

一。 先序遍历

根结点->左子树->右子树

[cpp]  view plain  copy
  1. void preorder(node* root){  
  2.     if(root == NULL){  
  3.         return;   //到达空树,递归边界   
  4.     }  
  5.     printf("%d\n", root->data);   //访问根结点root,例如将其数据域输出  
  6.     preorder(root->lchild);       //访问左子树   
  7.     preorder(root->rchild);       //访问右子树   
  8. }   

二。 中序遍历

左子树->根结点->右子树

[cpp]  view plain  copy
  1. void inorder(node* root){  
  2.     if(root == NULL){  
  3.         return;   //到达空树,递归边界   
  4.     }  
  5.     preorder(root->lchild);       //访问左子树   
  6.     printf("%d\n", root->data);   //访问根结点root,例如将其数据域输出  
  7.     preorder(root->rchild);       //访问右子树   
  8. }   

只要知道根结点,就可以根据根结点在中序遍历序列中的位置区分出左子树和右子树


三。 后序遍历

左子树->右子树->根结点

[cpp]  view plain  copy
  1. void postorder(node* root){  
  2.     if(root == NULL){  
  3.         return;   //到达空树,递归边界   
  4.     }  
  5.     preorder(root->lchild);       //访问左子树   
  6.     preorder(root->rchild);       //访问右子树   
  7.     printf("%d\n", root->data);   //访问根结点root,例如将其数据域输出  
  8. }   

四。 层序遍历

层序遍历相当于对二叉树从根结点开始的广度优先搜索。

[cpp]  view plain  copy
  1. void LayerOrder(node* root){  
  2.     queue<node*> q;    //注意队列中是存地址  
  3.     q.push(root);      //将根结点地址入队  
  4.     while(!q.empty()){  
  5.         node* now = q.front();     //取出队首元素  
  6.         q.pop();  
  7.         printf("%d ", now->data);  //访问队首元素  
  8.         if(now->lchild != NULL)  q.push(now->lchild);   //左子树非空  
  9.         if(now->rchild != NULL)  q.push(now->rchild);   //右子树非空   
  10.     }   
  11. }   


栗子:

假设一棵二叉树结点的值都是正整数,给出该二叉树的中序序列和后序序列,请输出该二叉树的层次遍历序列。


代码实现:

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn = 50;
struct node{
	int data;
	node* lchild;
	node* rchild;
}; 
int pre[maxn], in[maxn], post[maxn];  //先序, 中序, 后序
int n;  //结点个数
//当前二叉树的后序序列区间为[postL,postR],中序序列区间为[inL,inR]
//create函数返回构建出的二叉树的根结点地址
node* create(int postL, int postR, int inL, int inR) {
	if(postL > postR){
		return NULL;   //后序序列长度小于等于0时,直接返回 
	}
	node* root = new node;  //新建一个新的结点,用来存放当前二叉树的根结点
	root->data = post[postR];  //新结点的数据域为根结点的值
	int k;
	for(k = inL; k <= inR; k++){
		if(in[k] == post[postR]){   //在中序序列中找到in[k]==post[postR]的结点(根结点) 
			break;
		}
	} 
	int numLeft = k - inL;  //左子树的结点个数
	//返回左子树的根结点地址,赋值给root的左指针
	root->lchild = create(postL, postL+numLeft-1, inL, k-1);
	//返回右子树的根结点地址,赋值给root的右指针
	root->rchild = create(postL + numLeft, postR-1, k+1, inR);
	return root;   //返回根结点地址  
}
int num = 0;   //已输出的结点个数
void BFS(node* root){
	queue<node*> q;   //注意队列里是存地址
	q.push(root);     //将根结点地址入队
	while(!q.empty()){
		node* now = q.front();   //取出队首元素
		q.pop();
		printf("%d",now->data);  //访问队首元素 
		num++;
		if(num < n)   printf(" ");
		if(now->lchild != NULL) q.push(now->lchild);  //左子树非空
		if(now->rchild != NULL) q.push(now->rchild);  //右子树非空 
	} 
} 
int main(){
	scanf("%d", &n);
	for(int i = 0; i<n; i++){
		scanf("%d", &post[i]);
	} 
	for(int i = 0; i<n; i++){
		scanf("%d", &in[i]); 
	}
	node* root = create(0, n-1, 0, n-1);  //建树
	BFS(root);
	return 0; 
}




运行结果:



猜你喜欢

转载自blog.csdn.net/u014322206/article/details/78638352