树2—二叉树的表达

树2—二叉树的表达

编写一个程序,输出结点u的如下信息。

  • u的结点编号

  • u的深度

  • u的父结点

  • u的高

  • u的兄弟结点

  • u结点类型

  • u的子结点数

输入

结点的个数n。

u_{i} l_{i} r_{i}

\cdots

每个结点u和子结点l,r的编号,不存在子结点时,l和r为-1。

输入示例:

9

0 1 4

1 2 3

2 -1 -1

3 -1 -1

4 5 8

5 6 7

6 -1 -1

7 -1 -1

8 -1 -1

输出示例:

node 0: p=-1 sibling=-1 d=0 h=3 degree=2 root
node 1: p=0 sibling=4 d=1 h=1 degree=2 internal node
node 2: p=1 sibling=3 d=2 h=0 degree=0 leaf
node 3: p=1 sibling=2 d=2 h=0 degree=0 leaf
node 4: p=0 sibling=1 d=1 h=2 degree=2 internal node
node 5: p=4 sibling=8 d=2 h=1 degree=2 internal node
node 6: p=5 sibling=7 d=3 h=0 degree=0 leaf
node 7: p=5 sibling=6 d=3 h=0 degree=0 leaf
node 8: p=4 sibling=5 d=2 h=0 degree=0 leaf

        之前已经学过树的一些基本的表示方法, 本题可以使用结构体数组实现。

struct node { int p, l, r; };
node t[max];

        p表示该结点的父结点,l和r分别表示该结点的左子结点和右子结点。

        用递归方法求结点的高:

int getHeight(int u) {
	int h1 = 0, h2 = 0;
	if (t[u].l != nil)h1 = getHeight(t[u].l)+1;
	if (t[u].r != nil)h2 = getHeight(t[u].r)+1;
	return h[u] = (h1 > h2 ? h1 : h2);
}

        这个算法会访问每一个结点,所以复杂度为O(n)。

        同样用递归的方法来求深度:

void getDepth(int u, int di) {
	if (u == nil)return;
	d[u] = di;
	if (t[u].l != nil)getDepth(t[u].l, di + 1);
	if (t[u].r != nil)getDepth(t[u].r, di + 1);
	
}

        完整的代码如下:

#include<iostream>
using namespace std;
#define max 999
#define nil -1

int n, d[max], h[max],s[max];
struct node { int p, l, r; };
node t[max];

void getDepth(int u, int di) {
	if (u == nil)return;

	d[u] = di;

	if (t[u].l != nil)getDepth(t[u].l, di + 1);
	if (t[u].r != nil)getDepth(t[u].r, di + 1);
	
}

int getHeight(int u) {
	int h1 = 0, h2 = 0;
	if (t[u].l != nil)h1 = getHeight(t[u].l)+1;
	if (t[u].r != nil)h2 = getHeight(t[u].r)+1;
	return h[u] = (h1 > h2 ? h1 : h2);
}

int getSibling(int u) {
	if (t[u].p == nil)return nil;
	if (t[t[u].p].l != nil && t[t[u].p].l != u)return t[t[u].p].l;
	if (t[t[u].p].r != nil && t[t[u].p].r != u)return t[t[u].p].r;
	return nil;
}


void print(int u) {
	cout << "node " << u<<": ";
	cout << "p=" << t[u].p<<" ";
	cout << "sibling=" << getSibling(u)<<" ";
	cout << "d=" << d[u]<<" ";
	cout << "h=" << h[u]<<" ";
	int deg = 0;
	if (t[u].l != nil)deg++;
	if (t[u].r != nil)deg++;
	cout << "degree=" << deg << " ";

	if (t[u].p == nil) { cout << "root" << endl; }
	else if (t[u].l == nil && t[u].r == nil) { cout << "leaf" << endl; }
	else cout << "internal node" << endl;
}
int main() {
	
	int c,l,r,root=0;
	cin >> n;

	for (int i = 0; i < n; i++) { t[i].p = t[i].l = t[i].r = nil; }
	
	for (int i = 0; i < n; i++) {
		cin >> c >> l >> r;
		if (l != nil) {
			t[c].l = l;
			t[l].p = c;
		}
		if (r != nil) {
			t[c].r = r;
			t[r].p = c;
		}
	}

	for (int i = 0; i < n; i++) {
		if (t[i].p == nil)root = i;
	}

	getDepth(root, 0);
	getHeight(root);
	
	int i = 0;
	for ( i = 0; i < n; i++) {
		print(i);
	}

	return 0;
}

读《挑战程序设计竞赛》第二十天(侵删)2021.3.16

( 2021.7.11 第一次修改)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值