C语言数据结构上机作业:树

为什么我什么也不会啊


三道题都是没有用树的数据结构,仅仅利用了节点之间的关系。没有真正的建立树。我也不会 

题目:完全二叉树的子树 

问题描述

对一棵完全二叉树,采用自上而下、自左往右的方式从1开始编号,我们已知这个二叉树的最后一个结点是n,现在的问题是结点m所在的子树一共包括多少个结点?

输入格式

输入数据包括多行,每行给出一组测试数据,包括两个整数m,n (1 <= m <= n <= 1000000000)。0 0表示输入结束。

输出格式

对于每一组测试数据,输出一行,该行包含一个整数,给出结点m所在子树中包括的结点的数目。

完全二叉树:完全二叉树与满二叉树的区别(有图)_Android_Ape-CSDN博客_完全二叉树

代码 

//完全二叉树的子树
/*
性质:
如果从上到下从左到右排序的话,对于第k个元素,2k和2k+1个元素是其左右子树。
解题思路:
利用栈的dfs遍历子树,利用二叉树的性质,判断子树是否存在,逐步遍历完
*/
#include<iostream>
#include<stack>
using namespace std;

int main()
{
    int n,m;
    int sum,top;//计算每个子树的节点数,top当前值
    //if(m==n==1)
    while(1)//大循环
    {
        scanf("%d%d",&m,&n);
        if(m==0&&n==0)
            return 1;
        stack <int> list;//栈存放每一层的数据。dfs遍历整个二叉树
        list.push(m);sum=1;
        while(list.size())
        {//终止条件:栈空
            top=list.top();
            list.pop;
            if(2*top<n)
             {sum++;list.push(2*top);}   
            if((2*top+1)<n)
              {list.push(2*top+1);sum++;}  
        
        }
        printf("%d\n",sum);
    } 
}

 

题目:完全二叉树的公共父结点 

问题描述

有一棵无限大的完全二叉树,该二叉树自上而下、自左而右从1开始编号。从某一个结点到根结点(编号是1的结点)都有一条唯一的路径,比如从5到根结点的路径是(5, 2, 1),从4到根结点的路径是(4, 2, 1),从根结点1到根结点的路径上只包含一个结点1,因此路径就是(1)。对于两个结点x和y,假设他们到根结点的路径分别是(x1, x2, ... ,1)和(y1, y2,...,1),那么必然存在两个正整数i和j,使得从xi 和yj 开始,有xi = yj,xi + 1 = yj + 1,xi + 2 = yj + 2,...

现在的问题就是,给定x和y,要求他们的最近公共父节点,即xi(也就是 yj)。

输入格式

         输入包含多组数据,每组数据包含两个正整数x和y(1≤x, y≤2^31-1)。

输出格式

         对应每一组数据,输出一个正整数xi,即它们的首个公共父节点。每输出一个数字后要换行 

#include <stdio.h>

int main() {
	int x, y;
	while (1) {
		scanf("%d%d", &x, &y);
		if (x == 0 && y == 0)
			return 0;

		while (1) {
			if (x == y) {
				printf("%d\n", x);
				break;
			} else if (x > y)
				x = x / 2;
			else
				y = y / 2; //int形会自动去余
		}
	}
}

题目:完全二叉树的公共父结点 

问题描述

对一棵完全二叉树,输出某一深度的所有节点,有则输出这些节点,无则输出EMPTY。

输入格式

         输入有多组数据。

每组数据第一行输入一个结点数n(1<=n<=1000),第二行将树中的这n个节点依次输入(每个结点存储的数据是一个数字),n个结点编号方式是层间从上到下、层内从左到右依次编号;第三行输入一个d代表深度。

当n=0时,表示输入结束。

输出格式

         每组数据在一行上输出该树中第d层的所有节点,节点间用空格隔开。每组数据输出完成后要换行。

#include <stdio.h>

int power(int n) {
	int count = 1;
	if (n == 0)
		return 1;
	for (int i = 1; i <= n; i++)
		count = count * 2;
	return count;
}

int main() {
	int n, d, flog;
	int i, j;
	while (1) {
		int tree[500] = {0};
		scanf("%d", &n);
		if (n == 0)
			return 1;
		for (i = 1; i <= n; i++)
			scanf("%d", &tree[i]);
		scanf("%d", &d);

		flog = 1;
		//其实就是输出2^n到2^n-1之间的数组
		for (i = power(d - 1); i < power(d) && i <= n; i++) {
			flog = 0;
			printf("%d ", tree[i]);
		}
		if (flog)
			printf("EMPTY");
		printf("\n");
	}
}

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值