首页 > 试题广场 >

树查找

[编程题]树查找
  • 热度指数:12084 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
有一棵树,输出某一深度的所有节点,有则输出这些节点,无则输出EMPTY。该树是完全二叉树。

输入描述:
输入有多组数据。
每组输入一个n(1<=n<=1000),然后将树中的这n个节点依次输入,再输入一个d代表深度。


输出描述:
输出该树中第d层得所有节点,节点间用空格隔开,最后一个节点后没有空格。
示例1

输入

4
1 2 3 4
2

输出

2 3
#include <bits/stdc++.h>
using namespace std;
int n,d,tree[1000],i;
int main()
{
    while(cin>>n){
        for(i =1;i<=n;i++)
        cin>>tree[i];
        cin>>d;
        if(d==1){
            cout<<tree[1];
        }else if(i+1<pow(2,d-1)){
            cout<<"EMPTY";
        }else{
            for(int j =pow(2,d-1);j<=pow(2,d)-1;j++)
            cout<<tree[j]<<" ";
        }
    }
    cout<<endl;
    return 0;
}

发表于 2020-02-25 15:46:39 回复(0)
/*
原理:完全二叉树每一层第一个节点的编号为2的正整数次幂
如:
 第一层第一个:1
 第二层第一个:2
 第三层第一个:4
 第四层第一个:1


如果不是最后一层,算出该层有多少个数,,则按序输出
若为最后一行,先算最后一行有多少个,再按序输出 


*/ 




#include<iostream> 
#include<cmath> 
using namespace std;

bool lastLayer(int n, int d)
{
    //一共n个结点,判断第d层是否为最后一层
    //log2(d)=log(d)/log(2) ,以2为底n的对数 
    int total = log(n) / log(2) + 1;//一共多少层 
    if(d==n) 
    {
        return true;
    }
    return false;

}


int main()
{
    int n;
    int a[1001] ;//最多1000个结点 
    int d;//要查找的深度 

    cin>>n;
    //将结点按照层序放入数组中,数组a[0]不用 
    for(int i=1; i<=n; i++)
    {
        cin>>a[i];
    }

    cin>>d;
    int total = log(n) / log(2) + 1;//一共多少层 
    if(d>total)
    {
        cout<<"EMPTY"<<endl; 
    }
    else if(!lastLayer(n, d)) //自定义函数lastLayer(); 
    {
        //要查找的层最多有多少个(满二叉树) 
        int d_num = pow(2, (d-1));
        //当前层的第一个数 = 当前层结点的个数 
        int first = d_num;
        //如果不是最后一层 
        for(int i=0; i<d_num; i++) 
        {
            cout<<a[first+i]<<" ";
        }
    }
    else
    {
        //是最后一层
        //最后一层个数为 总个数n - 之前所有层个数 
        int d_num = n - (pow(2,(d-1)) -1);
        int first = pow(2,(d-1));
        for(int i=0; i<d_num; i++)
        {
            cout<<a[first+i];
        }
    }



    return 0;
}
编辑于 2019-02-26 16:59:02 回复(0)
  • 根据第d层的结点所在的范围,输出相应的结点。
#include <stdio.h>
#include <math.h>
#include <string.h>

#define maxn 1010

int node[maxn];
int n, d;

int main() {
    while (scanf("%d", &n) != EOF) {
        memset(node, 0, sizeof(node));
        for (int i = 1; i <= n; i++) {
            scanf("%d", &node[i]);
        }
        scanf("%d", &d);
        int i = pow(2, d - 1);
        if (i <= n) {
            for (; i <= n && i < pow(2, d); i++) {
                printf("%d", node[i]);
                printf("%s", i != n  " " : "\n");
            }
        } else {
            printf("EMPTY\n");
        }
    }
    return 0;
}
  • 先建立一棵完全二叉树,然后使用层次遍历输出第d层的结点。
#include <cstdio>
#include <vector>
#include <queue>

using namespace std;

typedef struct _node
{
    int data;
    int layer;
    struct _node *lchild;
    struct _node *rchild;
}node;

node *newNode(int x)
{
    node *root = new node;
    root->data = x;
    root->layer = 1;
    root->lchild = root ->rchild = NULL;
    return root;
}

int n, d, num[1010];
vector<int> v;

void create(node *&root, int index)
{
    if (index > n)
        return;
    root = newNode(num[index]);
    create(root->lchild, 2 * index);
    create(root->rchild, 2 * index + 1);
}

void bfs(node *root, int d)
{
    queue<node *> q;
    q.push(root);  
    while(!q.empty())
    {
        node *now = q.front();
        q.pop();
        if (now->layer == d)
            v.push_back(now->data);
        if (now->lchild)
        {
            now->lchild->layer = now->layer + 1;
            q.push(now->lchild);
        }
        if (now->rchild)
        {
            now->rchild->layer = now->layer + 1;
            q.push(now->rchild);
        }
    }
}

int main()
{
    while (scanf("%d", &n) != EOF)
    {
        for (int i = 1; i <= n; i++)
        {
            scanf("%d", &num[i]);
        }
        scanf("%d", &d);
        node *root = NULL;
        create(root, 1);
        bfs(root, d);
        for (auto it = v.begin(); it != v.end(); ++it)
        {
            printf("%d%s", *it, it != v.end() - 1 ? " " : "\n" );
        }
        if (v.empty())
            printf("EMPTY\n");
    }
    return 0;
}
发表于 2022-03-17 13:15:30 回复(0)
#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
// 理解树的特征:
// 完全二叉树的节点个数 <= 2^h-1;
// 每一层的节点数为2^(h-1);
// 若层次遍历存放在已0开头的数组中,第h层的开始节点下标为2^(h-1)-1,结束节点下标为2^(h)-2
int main(void)
{
    int n;
    vector<int> a;
    
    while(cin >> n)
    {
        a.clear();
        
        for(int i = 0;i < n;i++)
        {
            int x;
            cin >> x;
            a.push_back(x);
        }
        
        int d;
        cin >> d;
        
        if(d == 1)
        {
            cout << a[0] << endl;
            break;
        }
        
        int first = pow(2,d - 1) - 1;//第d层的开始结点,减一是因为下标从0开始的
        int end = pow(2,d) - 2;//第d层的结束结点,减2是因为下标从0开始的,原本是减1
        
        if(first > n)//开始结点已然超过树本身所拥有的结点总数
        {
            cout << "EMPTY" << endl;
            break;
        }
        else
        {
            end = (end < (n - 1)) ? end : (n - 1);//判断结束结点是不是在最后一层,防止访问越界
            for(int i = first;i <= end;i++)
            {
                cout << a[i];
                if(i != end)
                    cout << ' ';
            }
        }
    }
    return 0;
}

编辑于 2021-02-17 15:53:05 回复(0)
//建立一个二维数组  第一层1个数据  第二层两个数据2的1次方....
#include<stdio.h>
(737)#include<math.h>
int main()
{
    int n,d,a[100],b[100][100];
    scanf("%d",&n);
    int i,j,k;
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);
    b[1][0]=a[0];//第一行一个数
    k=1;//数组a的下标
    for(i=2;i<=(log2(n)+1);i++)//深度从第二层开始
    {
        for(j=0;j<pow(2,i-1)&&k<n;j++)//k<n代表不要超过总数,完全二叉树
        {
            b[i][j]=a[k];
            k++;
        }
    }
    scanf("%d",&d);
    if(d>(log2(n)+1))
        printf("EMPTY");
    else{
        for(j=0;b[d][j]!=NULL;j++)
            printf("%d ",b[d][j]);
    }
}

发表于 2020-05-06 15:42:15 回复(0)
Java
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()){
            int n = scanner.nextInt();
            int[] nodes= new int[n];
            for (int i = 0; i < n ;i++) nodes[i] = scanner.nextInt();
            int d = scanner.nextInt();
            int start = (int) Math.pow(2,d-1)-1;
            if (start>=n){
                System.out.println("EMPTY");
                continue;
            }
            int len  = (int)Math.pow(2,d-1);
            for (int i = start; i <start+len ; i++) System.out.print(nodes[i]+" ");
            System.out.println();
        }
    }
}




编辑于 2020-03-18 19:18:36 回复(0)
#include<bits/stdc++.h>
int main(){
    int n,d;
    while(scanf("%d",&n)!=EOF){
        int a[1001]={0};
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        scanf("%d",&d);
        if(d-1>log(n)/log(2)) printf("EMPTY\n");
        else
            for(int i=(1<<(d-1));i<(1<<d)&&i<n+1;i++)
                printf("%d ",a[i]);
    }
}
编辑于 2019-03-19 17:20:32 回复(0)
#include <cmath>
#include <iostream>
using namespace std;

int main()
{
    int n,d;
    int a[1001];
    cin >> n;
    for (int i = 1; i <= n; ++i)
    {
        cin >> a[i];
    }
    cin >> d;
    
    int iBeg = pow(2,d-1);
    int iEnd = pow(2,d) - 1;
    
    if(iBeg > n)
    {
        cout << "EMPTY" << endl;
    }
    else
    {
        iEnd = (iEnd > n) ? n : iEnd;
        for(int i = iBeg; i <= iEnd; ++i)
        {
            cout << a[i];
            if(i != iEnd)
                cout << ' ';
        }
    }
    
    return 0;
}

发表于 2019-01-05 20:23:40 回复(0)
#include<iostream>
using namespace std;
int mi(int x)//求2的x次幂
{
    if (x == 0)
        return 1;
    else
        return 2 * mi(x - 1);
}
int main()
{
    int a[1000], n,m,sum=0;
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> a[i];
    cin >> m;
    for (int i = 0; i < m-1; i++)
        sum += mi(i);//求深度为d之前的个数
    if (n <= sum)
    {
        cout << "EMPTY" << endl;
        return 0;
    }
    for (int j = sum; j < n&&j < sum + mi(m-1); j++)//输出深度为d的
    {
        if (j == n -1|| j == (sum + mi(m-1)-1))
            cout << a[j] << endl;
        else
            cout << a[j] << " ";
    }
    return 0;
}

发表于 2018-06-30 17:00:04 回复(0)

python 5行解法

while True:
    try:
        a, b, c, start = int(input()), list(map(int, input().split())), int(input()), 0
        for i in range(c - 1):
            start += 2 ** i
        res = b[start:start + 2 ** (c - 1)]
        print(" ".join(map(str, res)) if res else "EMPTY")

    except:
        break
发表于 2017-10-01 15:09:12 回复(2)
#include <cstdio>
#include <cmath>

const int N = 1000;

int main()
{
	int tree[N], n, d;
	while (scanf("%d", &n) != EOF)
	{
		for (int i = 0; i < n; i++)
		{
			scanf("%d", &tree[i]);
		}
		scanf("%d", &d);
		int start = (int)pow(2, d - 1);
		if (start > n)
		{
			printf("EMPTY\n");
		}
		else
		{
			int end = pow(2, d) - 1 > n ? n : (int)pow(2, d) - 1;
			for (int i = start - 1; i < end - 1; i++)
			{
				printf("%d ", tree[i]);
			}
			printf("%d\n", tree[end - 1]);
		}
	}
	return 0;
}

发表于 2017-06-06 11:55:16 回复(2)
#include <string.h> #include <iostream> #include <algorithm> #include <valarray>  using namespace std; int main() { int n;  scanf("%d", &n);  int arr[n+1];  for (int i = 1; i <= n; ++i) {
        scanf("%d", &arr[i]);  } int c;  scanf("%d",&c);  if (n <= pow(2, c - 1) - 1) {
        printf("EMPTY");  } else { int j;  if(n<pow(2,c)-1) {
            j = n;  } else {
            j = pow(2,c)-1;  } for (int i = pow(2, c - 1); i <= j; ++i) {
            printf("%d ", arr[i]);  }
    }
}
发表于 2023-02-16 21:38:37 回复(0)
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		while(scanner.hasNext()) {
			int n = scanner.nextInt();
			int[] arr = new int[n];
			
			for (int i = 0; i < n; i++) {
				arr[i] = scanner.nextInt();
			}
			
			int d = scanner.nextInt();
			
			if ( n >= Math.pow(2, d)-1) {
				//树的层数至少有d+1
				for (int i = (int)Math.pow(2, d-1)-1; i < Math.pow(2, d)-1 ; i++) {
					System.out.print(arr[i] + " ");
				}
			}else if (n >= Math.pow(2, d-1) && n < Math.pow(2, d)-1) {
				//树的层数为d
				for (int i = (int)Math.pow(2, d-1)-1; i < n; i++) {
					System.out.print(arr[i]+" ");
				}
			}else {
				//树的层数小于d
				System.out.println("EMPTY");
			}
			
		}
	}
}

编辑于 2024-03-24 21:14:55 回复(0)
#include<stdio.h>
#include<math.h>
#include<vector>
using namespace std;
int main(){
    int N;
    int tmp;
    scanf("%d",&N);
    vector<int> vec;
    vec.push_back(-1);
    for(int i=0;i<N;i++){
        scanf("%d",&tmp);
        vec.push_back(tmp);
    }
    int M;
    scanf("%d",&M);
    int pos = pow(2,M-1);
    if(pos>vec.size()){ printf("EMPTY"); return 0;}
    for(int i=pos;i<2*pos;i++){
        if(i>vec.size()) return 0;
        printf("%d ",vec[i]);
    }
}

编辑于 2024-03-10 10:13:20 回复(0)
#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;

int main() {
    int n;
    while (cin >> n) {
        vector<int>tree(n + 1); //树结点值
        //1号单元为根结点,0号单元未用
        for (int i = 1; i <= n; i++) {
            cin >> tree[i];
        }
        int d;
        cin >> d;
        int start = pow(2, d - 1);  //起始结点编号
        if (start > n) {
            cout << "EMPTY" << endl;
        } else {
            int end = min(n, (int)pow(2, d) - 1);   //终止结点编号
            for (int i = start; i <= end; i++) {
                cout << tree[i];
                i == end ? cout << endl : cout << " ";
            }
        }
    }
    return 0;
}

编辑于 2024-03-07 20:33:02 回复(0)
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <queue>
using namespace std;

struct Node {
    int high;
    int root;
    struct Node* left;
    struct Node* right;
};//二叉树结点
bool isprint = false;
void postOrder(Node*head,int m) {
    if (head->root<=0) {
        return;
    }
    postOrder(head->left,m);
    postOrder(head->right,m);
    if (head->high == m) {
        isprint = true;
        printf("%d ", head->root);
    }
   
    return;
}
int main() {
    queue<int> myQueue;
    queue<Node*> nodeQueue;
    int n;
    int index = 1;
    while (EOF!=scanf("%d", &n)) {
        for (int i = 0; i < n; ++i) {
            int a;
            scanf("%d", &a);
            myQueue.push(a);
        }
        Node* root=new Node;
        root->high = index;
        nodeQueue.push(root);
        while (true) {
            Node*node = nodeQueue.front();
            nodeQueue.pop();
            Node* left = new Node;
            Node* right = new Node;
            node->left=left;
            node->right= right;
            if (myQueue.empty()) {
                break;
            }      
            index = node->high;
            index += 1;
            node->root = myQueue.front();
            myQueue.pop();
            node->left->high = index;
            node->right->high = index;
            nodeQueue.push(node->left);
            nodeQueue.push(node->right);
        }
        int m;
        scanf("%d", &m);
        postOrder(root, m);
        if(!isprint){
            printf("EMPTY");
        }
    }
}
编辑于 2024-02-25 17:17:49 回复(0)
#include <cstdio>
#include <iostream>
using namespace std;

int main() {
    int n, d;
    int a[1010];
    while (scanf("%d", &n) != EOF) {
        for (int i = 0; i < n; i++) {
            scanf("%d", &a[i]);
        }
        scanf("%d", &d);
        int b = 1;
        for (int i = 1; i < d; i++) {
            b *= 2;
        }
        b -= 1;
        int e = 2 * b;
        if (n <= e)e = n;
        for (int i = b; i <= e; i++) {
            printf("%d", a[i]);
            if (i != e)printf(" ");
        }
        if (b > n) {
            printf("EMPTY");
        }
    }
}

发表于 2023-03-29 23:27:30 回复(0)
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

int main() {
    int n, d;
    while (cin >> n){
        vector<int> va(n);
        for (int& i : va) cin >> i;
        cin >> d;
        int i = (int)pow(2, d - 1) - 1;
        if (i >= n){
            cout << "EMPTY" << endl;
            continue;
        }
        int j = (int)pow(2, d) - 2;
        if (j >= n) j = n - 1;
        while (i < j){
            cout << va[i] << " ";
            ++i;
        }
        cout << va[j] << endl;
    }
}

发表于 2023-03-01 20:45:45 回复(0)
#include<iostream>
#include<queue>
#include<cmath>
#include<algorithm>
using namespace std;
int main(){
    int n;
    int v[1000];
    cin >> n;
    for(int i = 0;i < n;i++)
        cin >> v[i];
    int d;
    cin >> d;
    int index = -1;
    for(int i = 0;i < d;i++)
        index += pow(2, i);
    int start = index - pow(2, d - 1) + 1;
    if(start >= n) cout << "EMPTY" << endl;
    else{
        index = min(index, n - 1);
        for(int i = start; i <= index;i++)
            cout << v[i] << " ";
        cout << endl;
    }
}

发表于 2022-05-14 23:01:40 回复(0)
找清楚每一层的起点和终点的下标规律即可。
#include<iostream>
#include<cmath>
const int N=1005;

int tree[N];
int main() {
    int n,d;
    while(scanf("%d",&n)!=EOF) {
        for(int i=1;i<=n;i++) {
            scanf("%d",&tree[i]);
        }
        scanf("%d",&d);
        int st=(int)pow(2,d-1);
        if(st>n){
            printf("EMPTY\n");
        }
        else {
            int en=pow(2,d)-1>n? n : (int)pow(2,d)-1;
            for(int i=st;i<=en;i++) {
                printf("%d ",tree[i]);
            }
            printf("\n");
        }
    }
}


发表于 2022-04-03 17:15:53 回复(0)

问题信息

难度:
100条回答 8600浏览

热门推荐

通过挑战的用户

查看代码