【数据结构】基于前序序列和中序序列的字符串建立二叉树

根据数据结构的内容,我们已知:前+中  / 后+中 / 层+中,均可唯一确定一棵二叉树。

在本文中,将介绍基于前序和中序序列的建立二叉树的方式。

 


1. 问题描述

已知二叉树的前序序列 和中序序列字符数组,编写算法建立二链表的二叉树。

测试数据:
              前序序列{ ABHFDECKG }
              中序序列{ HBDFAEKCG } 

 


2. 解决方案

假设已知前序序列prestr,中序序列instr。按照以下步骤解决问题:

1. 将prestr的首字母取出,即为当前树的根结点root
2. 搜索instr中root的位置pos(从0开始)
3. 将prestr中从root向后pos个字符设为prestr1,剩余字符串设为prestr2;
   将instr中pos之前的子串设为instr1,将instr中pos之后的子串设为instr2
4. 分别将prestr1和instr1,prestr2和instr2打包,返回步骤1

重复进行上述步骤,直到划分出的子串长度为0

 


3. 代码

//字符串建树
#include<iostream>
#include<cstdio>
#include<string>

using namespace std;

struct Node {
	char data;
	Node* lch;
	Node* rch;
	Node(char x) :data(x), lch(NULL), rch(NULL) {}
};

Node* Create(Node* root, string prestr, string instr)
{
	if (prestr.size() == 0)
		return NULL;
	else
	{
		char fir = prestr[0];
		root = new Node(fir);

		int pos = instr.find(fir);
		string prestr1 = prestr.substr(1, pos);
		string prestr2 = prestr.substr(pos + 1);
		string instr1 = instr.substr(0, pos);
		string instr2 = instr.substr(pos + 1);

		root->lch = Create(root->lch, prestr1, instr1);
		root->rch = Create(root->rch, prestr2, instr2);

	}

	return root;
}

void preorder(Node* root)
{
	if (root == NULL) return;

	cout << root->data;
	preorder(root->lch);
	preorder(root->rch);

	return;
}

void inorder(Node* root)
{
	if (root == NULL) return;

	inorder(root->lch);
	cout << root->data;
	inorder(root->rch);

	return;
}

void postorder(Node* root)
{
	if (root == NULL) return;

	postorder(root->lch);
	postorder(root->rch);
	cout << root->data;

	return;
}

int main()
{
	string prestrs, instrs;
	prestrs = "ABHFDECKG";
	instrs = "HBDFAEKCG";
	Node* root = NULL;
	root = Create(root, prestrs, instrs);

	printf("preoder:");
	preorder(root);
	printf("\n");
	printf("inoder:");
	inorder(root);
	printf("\n");
	printf("postoder:");
	postorder(root);
	printf("\n");

	return 0;
}

在上述代码中,我们灵活的使用了string类的方法,包括.find(),.substr()等,可以直接实现我们的设计方案。

 


4. 拓展:基于层序序列建立二叉树

那么基于层序序列,我们应该如何建立二叉树呢?

假设给定的数据是:

const char *data = "ABCDEG000F00H";

其中字母代表根结点存储的数据,字母‘0’代表结点为空。

代码如下:

//字符串建树
#include<iostream>
#include<cstdio>
#include<string>

using namespace std;

struct Node {
	char data;
	Node* lch;
	Node* rch;
	Node(char x):data(x),lch(NULL),rch(NULL){}
};

int i = 1;

Node* Create(Node* root,const char *data,int i,int m)
{
	if (data[i] == '0'|| i>=m) //注意此处一定要限制i的范围
		return NULL;
	else
	{
		root = new Node(data[i]);
		root->lch = Create(root->lch, data,2*i+1,m);
		root->rch = Create(root->rch, data,2*i+2,m);

	}

	return root;
}

void preorder(Node* root)
{
	if (root == NULL) return;

	cout << root->data;
	preorder(root->lch);
	preorder(root->rch);

	return;
}

void inorder(Node* root)
{
	if (root == NULL) return;

	inorder(root->lch);
	cout << root->data;
	inorder(root->rch);

	return;
}

void postorder(Node* root)
{
	if (root == NULL) return;

	postorder(root->lch);
	postorder(root->rch);
	cout << root->data;
	
	return;
}

int main()
{
	const char *data = "ABCDEG000F00H";
	int m = strlen(data);

	Node* root = NULL;
	root = Create(root,data,0,m);

	printf("preoder:");
	preorder(root);
	printf("\n");
	printf("inoder:");
	inorder(root);
	printf("\n");
	printf("postoder:");
	postorder(root);
	printf("\n");

	return 0;
}

应该注意的点是如何根据当前结点的编号,推导出两个子结点的编号。

 


5. 总结

目前为止,树这一章节复习结束了。感觉难度适中吧,接下来就到了图的章节了。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值