建立二叉搜索树及根据中序遍历序列和先序(或后序)遍历序列建立二叉树与二叉树先序、中序、后序、层次(记录当前层次的和不记录的)遍历实现


二叉树原理层面就不赘述了,可以看看文末的参考链接,直接上干货代码!

树(结点)的构建:

struct Node {
	int data;
	Node *left,*right;
	Node(){//声明无参构造方法 
		
	}
	Node(int d) { //注意要这样写才能用这个:new Node(a[l1]);
		data = d;
	}
};

二叉树的建立

建立二叉搜索树

//递归建立二叉搜索树
void cre(Node* &t, int x, int level) {
	if(t==NULL) {
		t = new Node;//创建对象,由于定义了有参构建,所以要声明无参构造方法 
		t->left = t->right = NULL;
		t->data = x;
//		cnt[level]++;
//		if(level>mmax) mmax = level;
		return;
	}
	if(x<=t->data) cre(t->left, x, level+1);
	else cre(t->right, x, level+1);
}

根据中序和先序遍历序列建树

Node* PreInCreate(int l1,int r1,int l2,int r2,int level) { //根据先序以及中序遍历建树
	if(l2>r2) return NULL;//要根据中序序列l2,r2而不是l1,r1,来判断是否有无左右子树
	v[level].push_back(a[l1]);//带层次的层次遍历!! 
	Node *root = new Node(a[l1]);//确定当前的根,必然是先序序列的下一个字符
	int i;
//	cout<<"111"<<endl;
	for(i=l2; b[i]!=a[l1]; i++); //确定根在中序序列位置
	int llen=i-l2;//计算左子树的长度
	root->left=PreInCreate(l1+1,l1+llen,l2,i-1,level+1);//左子树
	root->right=PreInCreate(l1+llen+1,r1,i+1,r2,level+1);//右子树
	return root;//别忘记返回节点
}

根据中序和后序遍历序列建树

Node* PostInCreate(int l1,int r1,int l2,int r2,int level) { //根据后序以及中序遍历建树
	if(l2>r2) return NULL;//要根据中序序列l2,r2而不是l1,r1,来判断是否有无左右子树
	v[level].push_back(a[r1]);//带层次的层次遍历!! 
	Node *root=new Node(a[r1]);//确定当前的根,必然是后序序列的最后一个字符
	int i;
	for(i=l2; b[i]!=a[r1]; i++); //确定根在中序序列位置
	int llen=i-l2;//计算左子树的长度
	root->left=PostInCreate(l1,l1+llen-1,l2,i-1,level+1);//左子树
	root->right=PostInCreate(l1+llen,r1-1,i+1,r2,level+1);//右子树
	return root;//别忘记返回节点
}

二叉树的遍历

先序遍历(递归)

void PreTravse(Node *root) { //先序遍历,根左右
	if(root==NULL)return;
	printf("%d",root->data);//根
	PreTravse(root->left);//左
	PreTravse(root->right);//右
}

中序遍历(递归)

void InTravse(Node *root) { //中序遍历,左根右
	if(root==NULL)return;
	InTravse(root->left);//左
	printf("%d",root->data);//根
	InTravse(root->right);//右
}

后序遍历(递归)

void PostTravse(Node *root) { //后序遍历,左右根
	if(root==NULL)return;
	PostTravse(root->left);//左
	PostTravse(root->right);//右
	printf("%d",root->data);//根
}

层次遍历

void LevelTravse(Node *root) {//层次遍历 
	queue<Node*> q;
	q.push(root);
	Node *p;
	while(!q.empty()) {
		p=q.front();
		q.pop();
		cout<<p->data<<" ";
		if(p->left) q.push(p->left);
		if(p->right) q.push(p->right);
	}
}

完整代码(可直接运行)

//根据中序+先序或中序+后序遍历序列建立二叉树
#include <bits/stdc++.h>
using namespace std;
int a[10000],b[10000];//a是PreOrder或者是PostOrder,b是InOrder
int n;
vector<int> v[10000];//v[层次],每层次中每个结点的{结点值} 
struct Node {
	int data;
	Node *left,*right;
	Node(){//声明无参构造方法 
		
	}
	Node(int d) { //注意要这样写才能用这个:new Node(a[l1]);
		data = d;
	}
};
//递归建立二叉搜索树
void cre(Node* &t, int x, int level) {
	if(t==NULL) {
		t = new Node;//创建对象,由于定义了有参构建,所以要声明无参构造方法 
		t->left = t->right = NULL;
		t->data = x;
//		cnt[level]++;
//		if(level>mmax) mmax = level;
		return;
	}
	if(x<=t->data) cre(t->left, x, level+1);
	else cre(t->right, x, level+1);
}

Node* PreInCreate(int l1,int r1,int l2,int r2,int level) { //根据先序以及中序遍历建树
	if(l2>r2) return NULL;//要根据中序序列l2,r2而不是l1,r1,来判断是否有无左右子树
	v[level].push_back(a[l1]);//带层次的层次遍历!! 
	Node *root = new Node(a[l1]);//确定当前的根,必然是先序序列的下一个字符
	int i;
//	cout<<"111"<<endl;
	for(i=l2; b[i]!=a[l1]; i++); //确定根在中序序列位置
	int llen=i-l2;//计算左子树的长度
	root->left=PreInCreate(l1+1,l1+llen,l2,i-1,level+1);//左子树
	root->right=PreInCreate(l1+llen+1,r1,i+1,r2,level+1);//右子树
	return root;//别忘记返回节点
}
Node* PostInCreate(int l1,int r1,int l2,int r2,int level) { //根据后序以及中序遍历建树
	if(l2>r2) return NULL;//要根据中序序列l2,r2而不是l1,r1,来判断是否有无左右子树
	v[level].push_back(a[r1]);//带层次的层次遍历!! 
	Node *root=new Node(a[r1]);//确定当前的根,必然是后序序列的最后一个字符
	int i;
	for(i=l2; b[i]!=a[r1]; i++); //确定根在中序序列位置
	int llen=i-l2;//计算左子树的长度
	root->left=PostInCreate(l1,l1+llen-1,l2,i-1,level+1);//左子树
	root->right=PostInCreate(l1+llen,r1-1,i+1,r2,level+1);//右子树
	return root;//别忘记返回节点
}
void PreTravse(Node *root) { //先序遍历,根左右
	if(root==NULL)return;
	printf("%d",root->data);//根
	PreTravse(root->left);//左
	PreTravse(root->right);//右
}
void InTravse(Node *root) { //中序遍历,左根右
	if(root==NULL)return;
	InTravse(root->left);//左
	printf("%d",root->data);//根
	InTravse(root->right);//右
}
void PostTravse(Node *root) { //后序遍历,左右根
	if(root==NULL)return;
	PostTravse(root->left);//左
	PostTravse(root->right);//右
	printf("%d",root->data);//根
}
void LevelTravse(Node *root) {//层次遍历 
	queue<Node*> q;
	q.push(root);
	Node *p;
	while(!q.empty()) {
		p=q.front();
		q.pop();
		cout<<p->data<<" ";
		if(p->left) q.push(p->left);
		if(p->right) q.push(p->right);
	}
}
int main() {
	Node *root=NULL;
//	int n;
	cin>>n;
	for(int i=0; i<n; i++) {
		cin>>a[i];//先or后序遍历序列
	}
	for(int i=0; i<n; i++) {
		cin>>b[i];
	}
	int mode;
	cin>>mode;//0为先序,1为后序
	if(mode==0) {
		root = PreInCreate(0,n-1,0,n-1,1);
		cout<<"先序遍历:\n";
		PreTravse(root);
		cout<<endl;
		cout<<"中序遍历:\n";
		InTravse(root);
		cout<<endl;
		cout<<"后序遍历:\n";
		PostTravse(root);
		cout<<endl;
		cout<<"层次遍历\n";
		LevelTravse(root);
		cout<<endl;
		//带层次的层次遍历!! 
		for(int i=1;v[i].size()!=0;i++){
			cout<<i<<endl;
			for(auto t:v[i]){
				cout<<t<<" ";
			}
			cout<<endl;
		}

	} else {
		root=PostInCreate(0,n-1,0,n-1,1);
		cout<<"后序遍历:\n";
		PostTravse(root);
		cout<<endl;
		cout<<"中序遍历:\n";
		InTravse(root);
		printf("\n");
		cout<<"先序遍历:\n";
		PreTravse(root);
		cout<<endl;
		cout<<"层次遍历\n";
		LevelTravse(root);
		cout<<endl;
		//带层次的层次遍历!! 
		for(int i=1;v[i].size()!=0;i++){
			cout<<"level: "<<i<<endl;
			for(auto t:v[i]){
				cout<<t<<" ";
			}
			cout<<endl;
		}
	}

}

参考链接

根据后序遍历(先序遍历)和中序遍历建树
看原理数据结构——二叉树先序、中序、后序及层次四种遍历(C语言版)
【算法模板】二叉树的三种遍历方式,以及根据两种遍历方式建树
二叉树层次遍历算法——C/C++

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GCTTTTTT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值