PAT_(树补充) 完全二叉树 BST 一般二叉树的构建

目录

1110 Complete Binary Tree (25分)

1115 Counting Nodes in a BST (30分)

1119 Pre- and Post-order Traversals (30分)

1127 ZigZagging on a Tree (30分)


1110 Complete Binary Tree (25分)

Given a tree, you are supposed to tell if it is a complete binary tree.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤20) which is the total number of nodes in the tree -- and hence the nodes are numbered from 0 to N−1. Then N lines follow, each corresponds to a node, and gives the indices of the left and right children of the node. If the child does not exist, a - will be put at the position. Any pair of children are separated by a space.

Output Specification:

For each case, print in one line YES and the index of the last node if the tree is a complete binary tree, or NO and the index of the root if not. There must be exactly one space separating the word and the number.

Sample Input 1:

9
7 8
- -
- -
- -
0 1
2 3
4 5
- -
- -

Sample Output 1:

YES 8

Sample Input 2:

8
- -
4 5
0 6
- -
2 3
- 7
- -
- -

Sample Output 2:

NO 1

 (16分待改)

#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<vector>
#include<queue>
#define pb push_back 
using namespace std;
const int maxn=100005;
int n,last,maxIndex = 0,exist[20];
vector<int> g[20];

void bfs(int root){ //CBT 除叶子节点外,每个节点都有两个子节点 
    int cnt=0;
	queue<int> qu;
	qu.push(root);
	while(!qu.empty()){
		int tmp=qu.front();qu.pop();
        if(tmp!=-1){
            cnt++;
			last=tmp;
            qu.push(g[tmp][0]);
            qu.push(g[tmp][1]); 
        }else {
            if(cnt==n) {printf("YES %d\n",last); return ;}
            else {printf("NO %d\n",root);return ;}
        }
    }
    
}
void dfs(int u, int index){
	if(u==-1) return;
	if(index>maxIndex) {
        maxIndex = index, last = u;
    }
	dfs(g[u][0], 2*index);  // 遍历左孩子
	dfs(g[u][1], 2*index+1);  // 遍历右孩子
}
int main(){
	scanf("%d",&n);
	char a,b;
	for(int i=0;i<n;i++){
		cin>>a>>b;
		int left= a=='-'?-1:a-'0';
		int right= b=='-'?-1:b-'0';
		g[i].pb(left);
		g[i].pb(right);
		exist[left]=1;exist[right]=1; 
	}
	
	int root;
	for(int i=0;i<n;i++){
		if(!exist[i]){
			root=i;break;
		}
	}
	//bfs(root);
	dfs(root,1);
    if(maxIndex==n){
        printf("YES %d",last);
    }else{
        printf("NO %d",root);
    }
	return 0;	
}

(25分)

#include <iostream>
using namespace std;

int E[20][2];  // 存储每个节点的左右孩子
int exist[20]; 
int maxIndex = 0, last;
void dfs(int u, int index)
{
	if(u==-1) return;
	if(index>maxIndex) maxIndex = index, last = u;
	dfs(E[u][0], 2*index);  // 遍历左孩子
	dfs(E[u][1], 2*index+1);  // 遍历右孩子
}
int main(int argc, char const *argv[])
{
	int N; cin >> N;
	for (int i = 0; i < N; i++)
	{
		string s1, s2; cin >> s1 >> s2;
		int left=-1, right=-1;
		if(s1!="-") sscanf(s1.c_str(), "%d", &left);
		if(s2!="-") sscanf(s2.c_str(), "%d", &right);
		exist[left] = exist[right] = 1;
		E[i][0]=left, E[i][1]=right;
	}
	int root;
	for (int i = 0; i < N; i++) if(exist[i]==0) root=i;
	dfs(root, 1);
	if(maxIndex==N) cout << "YES" << " " << last;
	else cout << "NO" << " " << root;
	return 0;
}

1115 Counting Nodes in a BST (30分)

A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties:

  • The left subtree of a node contains only nodes with keys less than or equal to the node's key.
  • The right subtree of a node contains only nodes with keys greater than the node's key.
  • Both the left and right subtrees must also be binary search trees.

Insert a sequence of numbers into an initially empty binary search tree. Then you are supposed to count the total number of nodes in the lowest 2 levels of the resulting tree.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤1000) which is the size of the input sequence. Then given in the next line are the N integers in [−1000,1000] which are supposed to be inserted into an initially empty binary search tree.

Output Specification:

For each case, print in one line the numbers of nodes in the lowest 2 levels of the resulting tree in the format:

n1 + n2 = n

where n1 is the number of nodes in the lowest level, n2 is that of the level above, and n is the sum.

Sample Input:

9
25 30 42 16 20 20 35 -5 28

Sample Output:

2 + 4 = 6

思路:显式(struct node),递归构建BST,dfs得到每层节点个数

struct node{
	int data;
	node *left,*right;
	node(int x){
		data=x;
		left=right=NULL;
	}
};
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<string>
#include<cstring>
#include<vector>
#include<set>
#include<map>
#include<cmath>
#define pb push_back 
using namespace std;
const int maxn=100005;
int n;
int maxndepth=-1,num[1005];
struct node{
	int data;
	node *left,*right;
	node(int x){
		data=x;
		left=right=NULL;
	}
};
node* insert(node *root,int x){
	if(root==NULL){
		root=new node(x); 
	}else{
		if(x > root->data)
			root->right=insert(root->right,x);
		else 
			root->left=insert(root->left,x);
	}
	return root;
}
void dfs(node *root,int depth){
	if(root==NULL){
		maxndepth=max(maxndepth,depth);
		return ;
	}
	num[depth]++;
	dfs(root->left,depth+1); 
	dfs(root->right,depth+1);
}
int main(){
	scanf("%d",&n);
	int x;
	node *root=NULL;
	for(int i=0;i<n;i++){
		scanf("%d",&x);
		root=insert(root,x);
	}
	dfs(root,0); 
	printf("%d + %d = %d\n",num[maxndepth-1],num[maxndepth-2],num[maxndepth-1]+num[maxndepth-2]);
	return 0;	
}

1119 Pre- and Post-order Traversals (30分)

Suppose that all the keys in a binary tree are distinct positive integers. A unique binary tree can be determined by a given pair of postorder and inorder traversal sequences, or preorder and inorder traversal sequences. However, if only the postorder and preorder traversal sequences are given, the corresponding tree may no longer be unique.

Now given a pair of postorder and preorder traversal sequences, you are supposed to output the corresponding inorder traversal sequence of the tree. If the tree is not unique, simply output any one of them.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤ 30), the total number of nodes in the binary tree. The second line gives the preorder sequence and the third line gives the postorder sequence. All the numbers in a line are separated by a space.

Output Specification:

For each test case, first printf in a line Yes if the tree is unique, or No if not. Then print in the next line the inorder traversal sequence of the corresponding binary tree. If the solution is not unique, any answer would do. It is guaranteed that at least one solution exists. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the end of the line.

Sample Input 1:

7
1 2 3 4 6 7 5
2 6 7 4 5 3 1

Sample Output 1:

Yes
2 1 6 4 7 3 5

Sample Input 2:

4
1 2 3 4
2 4 3 1

Sample Output 2:

No
2 1 3 4
题⽬⼤意:给出⼀棵树的结点个数n,以及它的前序遍历和后序遍历,输出它的中序遍历,如果中序遍历不唯⼀就输出No,且输出其中⼀个中序即可,如果中序遍历唯⼀就输出Yes,并输出它的中序

分析:⽤unique标记是否唯⼀,如果为true就表示中序是唯⼀的,已知⼆叉树的前序和后序是⽆法唯⼀确定⼀颗⼆叉树的,因为可能会存在多种情况,这种情况就是⼀个结点可能是根的左孩⼦也有可能是根的右孩⼦,如果发现了⼀个⽆法确定的状态,置unique =false⼜因为题⽬只需要输出⼀个⽅案,可以假定这个不可确定的孩⼦的状态是右孩⼦,

接下来的问题是如何求根结点和左右孩⼦划分的问题了,⾸先我们需要知道树的表示范围,需要四个变量,分别是前序的开始的地⽅prel,前序结束的地⽅prer,后序开始的地⽅postl,后序结束的地⽅postr,前序的开始的第⼀个应该与后序的最后⼀个是相等的,这个结点就是根结点,以后序的根结点的前⾯⼀个结点作参考,寻找这个结点在前序的位置,就可以根据这个位置来划分左右孩⼦,递归处理。

#include <iostream>
#include <vector>
#include<cstdio>
using namespace std;
vector<int> in, pre, post;
bool unique = true;
void getIn(int preLeft, int preRight, int postLeft, int postRight) {
 	if(preLeft == preRight) {
 		in.push_back(pre[preLeft]);
 		return;
 	}
 	if (pre[preLeft] == post[postRight]) {
 	int i = preLeft + 1;
 	while (i <= preRight && pre[i] != post[postRight-1]) i++;
 	if (i - preLeft > 1)
 		getIn(preLeft + 1, i - 1, postLeft, postLeft + (i - preLeft - 1) - 1);
 	else
 		unique = false;
 	in.push_back(post[postRight]);
 	getIn(i, preRight, postLeft + (i - preLeft - 1), postRight - 1);
 	} 
}
int main() {
 	int n;
 	scanf("%d", &n);
 	pre.resize(n), post.resize(n);
 	for (int i = 0; i < n; i++)
 		scanf("%d", &pre[i]);
 	for (int i = 0; i < n; i++)
 		scanf("%d", &post[i]);
 		
 	getIn(0, n-1, 0, n-1);
 	
 	printf("%s\n%d", unique == true ? "Yes" : "No", in[0]);
	 for (int i = 1; i < in.size(); i++)
		 printf(" %d", in[i]);
 	printf("\n");
 	return 0; 
}

这个题的代码真绝了,参考柳神

1127 ZigZagging on a Tree (30分)

Suppose that all the keys in a binary tree are distinct positive integers. A unique binary tree can be determined by a given pair of postorder and inorder traversal sequences. And it is a simple standard routine to print the numbers in level-order. However, if you think the problem is too simple, then you are too naive. This time you are supposed to print the numbers in "zigzagging order" -- that is, starting from the root, print the numbers level-by-level, alternating between left to right and right to left. For example, for the following tree you must output: 1 11 5 8 17 12 20 15.

zigzag.jpg

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤30), the total number of nodes in the binary tree. The second line gives the inorder sequence and the third line gives the postorder sequence. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print the zigzagging sequence of the tree in a line. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the end of the line.

Sample Input:

8
12 11 20 17 1 15 8 5
12 20 17 11 15 8 5 1

Sample Output:

1 11 5 8 17 12 20 15

之前写过二叉树的zigzag遍历,利用deque

Leetcode 105+106 从前序与中序遍历序列构造二叉树

思路:利用中序+后序遍历构造一般二叉树,然后zigzag遍历    

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<string>
#include<cstring>
#include<vector>
#include<set>
#include<deque>
#include<cmath>
#define pb push_back 
using namespace std;
const int maxn=100005;
int n;
vector<int> in,post;
struct TreeNode {
     int val;
     TreeNode *left;
     TreeNode *right;
     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
TreeNode *root;
TreeNode * dfs(int postl,int postr,int inl,int inr){
    if(postl>postr) return NULL;
    TreeNode *cur=new TreeNode(post[postr]);
    int i=inl;
    for(;i<=inr;i++){
        if(post[postr]==in[i]) break;
    }
    int x=i-inl; 
    cur->left=dfs(postl,postl+x-1,inl,i-1);
    cur->right=dfs(postl+x,postr-1,i+1,inr);
    return cur;
}
 void zigzagLevelOrder() {
 	int cnt=0;
        deque<TreeNode*> que;
        que.pb(root);
        bool zigzag = false;  
        TreeNode* tmp;  
        while (!que.empty()) {
            int Size = que.size();
            while (Size) { 
                if (zigzag) { // 前取后放 FIFO
                    tmp = que.front();
                    que.pop_front();
                    if (tmp->left) que.push_back(tmp->left); // 下一层顺序存放至尾
                    if (tmp->right) que.push_back(tmp->right);                
                } else { // 后取前放 FILO
                    tmp = que.back();
                    que.pop_back();
                    if (tmp->right) que.push_front(tmp->right); // 下一层逆序存放至首
                    if (tmp->left) que.push_front(tmp->left);
                }
                cnt++;
                printf("%d%c",tmp->val,cnt==n?'\n':' ');
                --Size;
            }
            zigzag = !zigzag;
        }
}
int main(){
	scanf("%d",&n);
	int x;
	for(int i=0;i<n;i++){
		scanf("%d",&x);
		in.pb(x);
	}
	for(int i=0;i<n;i++){
		scanf("%d",&x);
		post.pb(x);
	}
	root=dfs(0,n-1,0,n-1); 
	//printf("%d",root->val);
	zigzagLevelOrder();
	return 0;	
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值