根据前序中序还原二叉树+后续遍历+求树的高度

前序遍历:先访问当前节点,再访问当前节点的左子树,最后访问当前节点的右子树。对于二叉树,深度遍历与此同。规律:根在前;子树在根后且左子树比右子树靠前,且第一个就是根节点;

中序遍历:先访问当前节点的左子树,然后访问当前节点,最后是当前节点的右子树,二叉树,中序遍历会得到数据升序效果。规律:根在中;左子树在跟左边,右子树在根右边,左边部分是根结点的左子树的中序遍历序列,右边部分是根结点的右子树的中序遍历序列 ;

后序遍历:先访问当前节点的左子树,然后是当前节点的又子树,最后是当前节点。规律:根在后;子树在根前且左子树比右子树靠前,且最后一个节点是根节点。

前序+中序还原二叉树

  1. 根据前序序列的第一个元素建立根结点;
  2. 在中序序列中找到该元素,确定根结点的左右子树的中序序列;
  3. 在前序序列中确定左右子树的前序序列;
  4. 由左子树的前序序列和中序序列建立左子树;
  5. 由右子树的前序序列和中序序列建立右子树。
    如:已知一棵二叉树的先序遍历序列和中序遍历序列分别是abdgcefh、dgbaechf,求二叉树及后序遍历序列。
    先序:abdgcefh—>a bdg cefh

中序:dgbaechf—->dgb a echf

得出结论:a是树根,a有左子树和右子树,左子树有bdg结点,右子树有cefh结点。
先序:bdg—>b dg

中序:dgb —>dg b

得出结论:b是左子树的根结点,b无右子树,有左子树。
先序:dg—->d g

中序:dg—–>dg

得出结论:d是b左子树的根节点,d无左子树,g是d的右子树

然后对于a 的右子树类似可以推出

最后还原+后序遍历+高度代码实现

#include <iostream>
#include <string>
using namespace std;
typedef struct bintree{
	struct bintree* lchild;
	struct bintree*rchild;
	char val;
}Bintree;
Bintree *settree(string  arr, string arr2,int len){
	if (len == NULL)   return  NULL;
	Bintree* root = new Bintree;
	int i;
	root->val = arr[0];  //前序遍历第一个为根节点
	for (i = 0; i < len; ++i){ //中序遍历中根节点左边为左子树,右边为有子树
		if (arr2[i] == arr[0])
			break;
	}
	root->lchild=settree(arr.substr(1,i), arr2, i);//左子树
	 //右子树
	root->rchild = settree(arr.substr(i + 1, len - i - 1),
		arr2.substr(i + 1, len - i - 1), len - i - 1);
	return root;
}
int Gettree(Bintree* root){ //得到树的高度
	int H, L, R;
	if (root == NULL) return 0;
	else{
		L = Gettree(root->lchild);
		R = Gettree(root->rchild);
		H = L > R ? L + 1 : R + 1;
	}
	return H;
}
void aftertree(Bintree* root){  //后续遍历
	if (root == NULL)  return;
	else{
		aftertree(root->lchild);
		aftertree(root->rchild);
		cout << root->val;
	}
	
}
int main(){
	string arr;
	string arr2;
	int len;
	while (cin>>len){
			cin >> arr;  //输入前序遍历
			cin >> arr2;  //输入中序遍历
			Bintree *root = settree(arr, arr2, len);
			aftertree(root);
			cout << endl;
			int hight = Gettree(root);
			cout << hight << endl;

	}
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二叉树的链式存储结构可以通过定义一个结构体来实现,结构体中包含一个数据域和两个指向左右子树的指针。具体实现如下: ``` typedef struct TreeNode{ int data; struct TreeNode *left; struct TreeNode *right; }TreeNode, *Tree; Tree createTree(){ int data; scanf("%d", &data); if(data == -1){ // -1表示空节点 return NULL; } Tree root = (Tree)malloc(sizeof(TreeNode)); root->data = data; root->left = createTree(); root->right = createTree(); return root; } ``` 以上代码实现了二叉树的链式存储结构的创建,其中createTree()函数使用前序遍历的方式输入二叉树的节点数据,-1表示空节点。 接下来是二叉树遍历,分别实现前序中序后序遍历: ``` void preOrder(Tree root){ if(root == NULL){ return; } printf("%d ", root->data); preOrder(root->left); preOrder(root->right); } void inOrder(Tree root){ if(root == NULL){ return; } inOrder(root->left); printf("%d ", root->data); inOrder(root->right); } void postOrder(Tree root){ if(root == NULL){ return; } postOrder(root->left); postOrder(root->right); printf("%d ", root->data); } ``` 以上代码分别实现了前序中序后序遍历,其中preOrder()函数实现了前序遍历,inOrder()函数实现了中序遍历,postOrder()函数实现了后序遍历。 最后是主函数功能菜单的创建,可以使用switch语句实现: ``` int main(){ Tree root = NULL; int choice; do{ printf("1. 创建二叉树\n"); printf("2. 前序遍历\n"); printf("3. 中序遍历\n"); printf("4. 后序遍历\n"); printf("0. 退出\n"); scanf("%d", &choice); switch(choice){ case 1: printf("请输入二叉树的节点数据,-1表示空节点:\n"); root = createTree(); break; case 2: printf("前序遍历结果为:"); preOrder(root); printf("\n"); break; case 3: printf("中序遍历结果为:"); inOrder(root); printf("\n"); break; case 4: printf("后序遍历结果为:"); postOrder(root); printf("\n"); break; case 0: printf("程序已退出!\n"); break; default: printf("输入有误,请重新输入!\n"); break; } }while(choice != 0); return 0; } ``` 以上代码实现了一个简单的二叉树遍历程序,用户可以通过菜单选择需要的功能。注意,在实际使用中,需要在程序结束时释放二叉树的内存空间。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值