二叉树的遍历

本文详细介绍了二叉树的四种遍历方式:先序、中序、后序及层序遍历,并提供了对应的C/C++代码实现。此外,还探讨了如何通过先序和中序、后序和中序序列构建二叉树的方法,以及二叉树的静态实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先序遍历

void preorder(){
 if(root == NULL){
  return ;
 }
 printf("%d\n",root->data);//访问根结点
 preorder(root->lchild);  //访问左子树
 preorder(root->rchild);  //访问右子树
}

先序遍历的性质:

对一棵二叉树的先序遍历序列而言,序列的第一个结点必定是根结点。

中序遍历

void inorder(node * root){
	if(root == NULL){
		return ;
	}
	inorder(root->lchild);//访问左子树 
	printf("%d\n",root->data);//访问根结点 
	inorder(root->rchild);//访问右子树 
}

中序遍历序列的性质:

可以通过判断根结点在中序遍历序列中的位置来区分出左右子树。

后序遍历

void postorder(node * root){
	if(root == NULL){
		return ;
	}
	postorder(root->lchild);//访问左子树 
	postorder(root->rchild);//访问右子树
	printf("%d\n",root->data);//访问根结点 
} 

后序遍历的性质:

对于后序遍历序列而言,最后一个结点必定是根结点。

层序遍历

void LayerOrder(node * root){
	queue<node*> q;//注意队列里存地址 
	q.push(root);  //将根结点地址入队 
	while(!q.empty()){
		node* now = q.front();//取出队首元素 
		q.pop();
		printf("%d",now->data);//访问队首元素 
		if(now->lchild != NULL) q.push(now->lchild);//左子树非空 
		if(now->rchild != NULL) q.push(now->rchild);//右子树非空 
	}
}

当题目种需要求出结点所在层次时,则需要添加表示层次的变量layer :

struct node {
	int data;
	int layer;
	node* lchild;
	node* rchild;
};
//层序遍历
void LayerOrder(node* root){
	queue<node*> q;//注意队里存放地址 
	root->layer = 1; //根结点层号为 1 
	q.push(root);//将根结点地址入队 
	while(!q.empty()){
		node* now = q.front();
		q.pop();
		printf("%d ",now->data);
		if(now->lchild != NULL){//左子树非空 
			now->lchild->layer = now->layer + 1;
			q.push(now->lchild);
		}
		if(now->rchild!=NULL){//右子树非空 
			now->rchild->layer = now->layer + 1;
			q.push(now->rchild);
		}
	} 
} 

给定先序序列与中序序列得出这棵二叉树

node* create(int preL,int preR,int inL,int inR){
	if(preL > preR){
		return NULL;
	}
	node* root = new node;
	root->data = pre[preL];
	int k;
	for(k = inL;k <= inR;k++){
		if(in[k]==pre[preL]){
			break;
		}
	}
	//左子树结点个数 
	int numLeft =  k-inL;
	//左子树先序区间[preL+1,preL+numLeft],中序区间[inL,k-1]
	root->lchild = create(preL+1,preL+numLeft,inL,k-1); 
	//右子树先序区间[preL+numLeft+1,preR],中序区间[k+1,inR] 
	root->rchild = create(preL+numLeft+1,preR,k+1,inR);
	//返回根结点地址 
	return root;
} 

后序序列与中序序列得出二叉树的做法类同。

二叉树的静态实现

具体实现如下:

//二叉链表实现 
struct node {
	typename data;
	node* lchild;
	node* rchild;
}; 
//静态二叉链表实现
struct node {
	typename data;
	int lchild;
	int rchild;
}Node[maxn];
 

静态链表定义下,实现结点的动态生成:

int index = 0;
int newNode(int v){
	Node[index].data = v;//数据域
	Node[index].lchild = -1;//以-1或maxn表示空,因为数组范围为0 ~ maxn-1
	Node[index].rchild = -1;
	return index++;
} 

二叉树插入、查找、建立:

void search(int root,int x,int newdata){
	  if(root == -1){
	  	return ;
	  }
	  if(Node[root].data == x){
	  	Node[root].data = newdata;
	  }
	  search(Node[root].lchild,x,newdata);
	  search(Node[root].rchild,x,newdata);
}
//插入 
void insert(int &root,int x){
	if(root == -1){
		root = newNode(x);
		return ;
	}
	if(由二叉树性质x应该插在左子树){
       insert(Node[root].lchild,x);
	}else{
		insert(Node[root].rchild,x);
	}
} 
//建立
void create(int data[],int n){
	int root = -1;
	for(itn i=0;i< n;i++){
		insert(root,data[i]); 
	}
	return root;
} 

二叉树遍历:

//先序遍历
void preorder(int root){
	if(root == -1){
		return;
	}
	printf("%d\n",Node[root].data);
	preorder(Node[root].lchild);
	preorder(Node[root].rchild);
} 
//中序遍历
void inorder(int root){
	if(root == -1){
		return;
	}
	inorder(Node[root].lchild);
	printf("%d\n",Node[root].data);
	inorder(Node[root].rchild);
}  
//后序遍历
void postorder(int root){
	if(root == -1){
		return;
	}
	postorder(Node[root].lchild);
	postorder(Node[root].rchild);
	printf("%d\n",Node[root].data);
} 
//层序遍历
void LayerOrder(int root){
	queue<int> q;
	q.push(root);
	while(!q.empty()){
	  int now = q.front();
	  q.pop();
	  printf("%d ",Node[now].data);
	  if(Node[now].lchild != -1) q.push(Node[now].lchild);
	  if(Node[now].rchild != -1) q.push(Node[now].rchild); 
        }
} 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值