C++数据结构 第二次作业

问题 A: 满二叉树的前序遍历

题目描述

给你一个满二叉树的层次遍历序列,请编程输出该二叉树的前序遍历序列。

输入

第一行是n(n小于26),表示有n个节点。第二行是该满二叉树的节点对应字母的层次遍历序列。

输出

输出该满二叉数的前序遍历序列。

样例输入 Copy

3
B A C

样例输出 Copy

BAC
#include<iostream>
using namespace std;
char TreeNode[27];

void front(int n)
{
	if(TreeNode[n]!=NULL){
	
    cout<<TreeNode[n];//改变这句话的位置实现前中后序不同遍历 

	front(2*n+1);//左孩子
	
	front(2*n+2);//右孩子

	}

}
int main()
{
	
	int n;cin>>n;
	for(int i=0;i<n;i++){
	cin>>TreeNode[i];
	}
	front(0);

}


问题 B: 满二叉树的中序遍历

题目描述

给你一个满二叉树的层次遍历序列,请编程输出该二叉树的中序遍历序列。

输入

第一行是n(n小于26),表示有n个节点。第二行是该满二叉树的节点对应字母的层次遍历序列。

输出

输出该满二叉数的中序遍历序列。

样例输入 Copy

3
B A C

样例输出 Copy

ABC
#include<iostream>
using namespace std;
char TreeNode[27];

void front(int n)
{
	if(TreeNode[n]!=NULL){

	front(2*n+1);//左孩子

    cout<<TreeNode[n];//改变这句话的位置实现前中后序不同遍历 
	
	front(2*n+2);//右孩子

	}

}
int main()
{
	
	int n;cin>>n;
	for(int i=0;i<n;i++){
	cin>>TreeNode[i];
	}
	front(0);

}

问题 C: 满二叉树的后序遍历

题目描述

给你一个满二叉树的层次遍历序列,请编程输出该二叉树的后序遍历序列。

输入

第一行是n(n小于26),表示有n个节点。第二行是该满二叉树的节点对应字母的层次遍历序列。

输出

输出该满二叉数的后序遍历序列。

样例输入 Copy

3
B A C

样例输出 Copy

ACB
#include<iostream>
using namespace std;
char TreeNode[27];

void front(int n)
{
	if(TreeNode[n]!=NULL){

	front(2*n+1);//左孩子
	
	front(2*n+2);//右孩子

    cout<<TreeNode[n];//改变这句话的位置实现前中后序不同遍历 

	}

}
int main()
{
	
	int n;cin>>n;
	for(int i=0;i<n;i++){
	cin>>TreeNode[i];
	}
	front(0);

}

问题 D: 任意二叉树的前序遍历

题目描述

有若干个节点,每个节点上都有编号,把这些节点随意地构成二叉树,请编程输出该二叉树的前序遍历序列。

输入

第一行是n(n小于100),表示有n个节点,每个节点按从1到n依次编号。第一行后有n行,每行三个正整数i、l、r,分别表示节点i及对应的左右孩子的编号,如果不存在孩子则以-1表示。三个整数之间用一个空格隔开。

输出

输出该二叉数的前序遍历序列。

样例输入 Copy

4
1 2 4
3 1 -1
2 -1 -1
4 -1 -1

样例输出 Copy

3 1 2 4
#include<iostream>
using namespace std;
const int N = 110;//把N拎出来是为了方便改N的值

struct Node //用结构体是因为每一次需要三个数据
{
	int l, r;//left & right
	int val;//代表第一列输入的数据
}a[N];

int n;
bool judge[N];//用来判断该节点是否为根

void front(int u)//其他遍历就改变函数名 和 cout位置
{
	cout << u << " ";
	if (a[u].l != -1) front(a[u].l);
	if (a[u].r != -1) front(a[u].r);
}

int main() {
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		int x, l, r;
		cin >> x >> l >> r;
		a[x].l = l;
		a[x].r = r;
		if (l != -1) judge[l] = 1;//证明左孩子不是根
		if (r != -1) judge[r] = 1;//证明右孩子不是根
	}
	int root = 0;
	for (int i = 1; i <= n; i++)
	{
		if (!judge[i]) {//n个编号对应n个位置,该位置没被证明不是根的 即为根(找根)
			root = i;
			break;
		}
	}
	front(root);
	return 0;
}

问题 E: 任意二叉树的中序遍历

题目描述

有若干个节点,每个节点上都有编号,把这些节点随意地构成二叉树,请编程输出该二叉树的中序遍历序列。

输入

第一行是n(n小于100),表示有n个节点,每个节点按从1到n依次编号。第一行后有n行,每行三个正整数i、l、r,分别表示节点i及对应的左右孩子的编号,如果不存在孩子则以-1表示。三个整数之间用一个空格隔开。

输出

输出该二叉数的中序遍历序列。

样例输入 Copy

4
1 2 4
3 1 -1
4 -1 -1
2 -1 -1

样例输出 Copy

2 1 4 3
#include<iostream>
using namespace std;
const int N = 110;//把N拎出来是为了方便改N的值

struct Node //用结构体是因为每一次需要三个数据
{
	int l, r;//left & right
	int val;//代表第一列输入的数据
}a[N];

int n;
bool judge[N];//用来判断该节点是否为根

void middle(int u)//其他遍历就改变函数名 和 cout位置
{
	if (a[u].l != -1) middle(a[u].l);
	cout << u << " ";
	if (a[u].r != -1) middle(a[u].r);
}

int main() {
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		int x, l, r;
		cin >> x >> l >> r;
		a[x].l = l;
		a[x].r = r;
		if (l != -1) judge[l] = 1;//证明左孩子不是根
		if (r != -1) judge[r] = 1;//证明右孩子不是根
	}
	int root = 0;
	for (int i = 1; i <= n; i++)
	{
		if (!judge[i]) {//n个编号对应n个位置,该位置没被证明不是根的 即为根(找根)
			root = i;
			break;
		}
	}
	middle(root);
	return 0;
}

问题 F: 任意二叉树的后序遍历

题目描述

有若干个节点,每个节点上都有编号,把这些节点随意地构成二叉树,请编程输出该二叉树的后序遍历序列。

输入

第一行是n(n小于100),表示有n个节点,每个节点按从1到n依次编号。第一行后有n行,每行三个正整数i、l、r,分别表示节点i及对应的左右孩子的编号,如果不存在孩子则以-1表示。三个整数之间用一个空格隔开。

输出

输出该二叉数的后序遍历序列。

样例输入 Copy

4
1 2 4
4 -1 -1
2 -1 -1
3 1 -1

样例输出 Copy

2 4 1 3
#include<iostream>
using namespace std;
const int N = 110;//把N拎出来是为了方便改N的值

struct Node //用结构体是因为每一次需要三个数据
{
	int l, r;//left & right
	int val;//代表第一列输入的数据
}a[N];

int n;
bool judge[N];//用来判断该节点是否为根

void last(int u)//其他遍历就改变函数名 和 cout位置
{
	if (a[u].l != -1) last(a[u].l);
	if (a[u].r != -1) last(a[u].r);
	cout << u << " ";
}

int main() {
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		int x, l, r;
		cin >> x >> l >> r;
		a[x].l = l;
		a[x].r = r;
		if (l != -1) judge[l] = 1;//证明左孩子不是根
		if (r != -1) judge[r] = 1;//证明右孩子不是根
	}
	int root = 0;
	for (int i = 1; i <= n; i++)
	{
		if (!judge[i]) {//n个编号对应n个位置,该位置没被证明不是根的 即为根(找根)
			root = i;
			break;
		}
	}
	last(root);
	return 0;
}

问题 G: FBI树

题目描述

我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为 B 串,全“1”串称为 I 串,既含“0”又含“1”的串则称为 F 串。
FBI 树是一棵二叉树,它的结点类型也包括 F 结点,B 结点和 I 结点三种。由一个长度为 2N 的“01”串 S 可以构造出一棵 FBI 树 T,递归的构造方法如下:
(1) T 的根结点为 R,其类型与串 S 的类型相同;
(2) 若串 S 的长度大于 1,可将串 S 从中间分开,分为等长的左右子串 S1 和 S2;由左子串 S1 构造 R 的左子树 T1,由右子串 S2 构造 R 的右子树 T2。

现在给定一个长度为 2N 的“01”串,请用上述构造方法构造出一棵 FBI 树,并输出它的后序遍历序列。
 

输入

第一行是一个整数 N(0≤N≤10),第二行是一个长度为 2N 的“01”串。

输出

包括一行,这一行只包含一个字符串,即 FBI 树的后序遍历序列。

样例输入 Copy

3 
10001011

样例输出 Copy

IBFBBBFIBFIIIFF

法1:

#include<iostream>
#include<cmath>
using namespace std;
int N;
char *FBI=new char[100];
char* S = new char[100];
char judge(int i,int len)
{
	char flag = 0;
	int j = i;
	for (; i < j + len; i++)
	{
		if (S[i] == '0')
		{
			if (flag == 0)
				flag = 'B';
			if (flag == 'I')
			{
				flag = 'F';
				break;
			}
		}
		if (S[i] == '1')
		{
			if (flag == 0)
				flag = 'I';
			if (flag == 'B')
			{
				flag = 'F';
				break;
			}
		}
	}
	return flag;
}
void houxu(int i)
{
	if (i < pow(2,N + 1)-1)
	{
		houxu(2*i + 1);
		houxu(2 * i + 2);
		cout << FBI[i];
	}
}
int main()
{
	cin >> N;
	cin >> S;
	int i=1, j,k, m ,len=pow(2,N),len1;
	FBI[0] = 'F';
	for (j = 0; j < N; j++)
	{
		m = 0; 
		for (k = 0; k < pow(2, j + 1); k++)
		{
			len1 = len / pow(2, j + 1);
			FBI[i] = judge(m , len1);
			i++; m = m + len1;
		}
	}
	houxu(0);
	return 0;
}

法2:

#include<iostream>
#include<cmath>
#include<string>
using namespace std;
struct TreeNode{
	char data;
	TreeNode*left;
	TreeNode*right;
	TreeNode(char p)
	{
		data=p;
		left=NULL;
		right=NULL;
	}
};
TreeNode* Tree(int T[],int m,int n)//m:每一小段从m(下标)开始;n:每一小段的末位置;(n+m)/2:他左孩子的末尾位置,右孩子的起始位置
{
	bool k=true,g=true;
	//if(m==n)return NULL;
	//cout<<"m="<<m<<"n="<<n;
	for(int i=m;i<n;i++)
	{
		if(T[i]==0)
			k=false;
		else
			g=false;
	}
	TreeNode*temp=NULL;
	if(k==false&&g==false)
		temp=new TreeNode('F');
	if(k==false&&g==true)
		temp=new TreeNode('B');
	if(g==false&&k==true)
		temp=new TreeNode('I');
	if(n-m>1)temp->left=Tree(T,m,(n+m)/2);//每一层都是八个数,每次都取一半
	if(n-m>1)temp->right=Tree(T,(n+m)/2,n);
	return temp;
}
void lateOrder(TreeNode*root)
{
	//cout<<"*"<<endl;
	if(root==NULL)return; 
	lateOrder(root->left);
	lateOrder(root->right);
	cout<<root->data;
	return;
}
int main(){
	int n;
	cin>>n;
	string s;
	cin>>s;
	int len=pow(2,n);
	int *T=new int [len];
	for(int i=0;i<len;i++)
	{
		T[i]=s[i]-'0';//0对应的ascii的值是48,数字对应的ascii不是本身,所以减去‘0’之后才是本身的数。
	}
	TreeNode*root=Tree(T,0,len);
	lateOrder(root);
	return 0;
}

问题 H: 满二叉树的深度

题目描述

给你一个满二叉树的层次遍历序列,请编程输出该二叉树的深度。

输入

第一行是n(n小于26),表示有n个节点。第二行是该满二叉树的节点对应字母的层次遍历序列。

输出

输出该满二叉数的深度。

样例输入 Copy

3
B A C

样例输出 Copy

2
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
	int n;
	cin>>n;
	char ch;
	cin>>ch;
	int num=n;
	int count=0;
	int a=0;
	while(num)
	{
		num=num-pow(2,a);
		a++;
		count++;
	}
	cout<<count;
	
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

参宿七625

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

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

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

打赏作者

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

抵扣说明:

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

余额充值