Problem:
Binary Tree A rooted binary tree is a tree with a root node in which every node has at most two children. Your task is to write a program which reads a rooted binary tree T and prints the following information for each node u of T :  node ID of u  parent of u  sibling of u  the number of children of u  depth of u  height of u  node type (root, internal node or leaf)  If two nodes have the same parent, they are siblings . Here, if u and v have the same parent, we say u is a sibling of v (vice versa). The height of a node in a tree is the number of edges on the longest simple downward path from the node to a leaf. Here, the given binary tree consists of n nodes and evey node has a unique ID from 0 to n -1. Input The first line of the input includes an integer n , the number of nodes of the tree. In the next n lines, the information of each node is given in the following format:  id left right   id is the node ID, left is ID of the left child and right is ID of the right child. If the node does not have the left (right) child, the left ( right ) is indicated by -1 . Output Print the information of each node in the following format:  node  id : parent = p , sibling = s , degree = deg , depth = dep , height = h , type   p is ID of its parent. If the node does not have a parent, print -1 .  s is ID of its sibling. If the node does not have a sibling, print -1 .  deg , dep and h are the number of children, depth and height of the node respectively.  type is a type of nodes represented by a string ( root , internal node or leaf . If the root can be considered as a leaf or an internal node, print root . Please follow the format presented in a sample output below. Constraints  1 ≤ n ≤ 25  Sample Input 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 Sample Output 1 node 0: parent = -1, sibling = -1, degree = 2, depth = 0, height = 3, root
node 1: parent = 0, sibling = 4, degree = 2, depth = 1, height = 1, internal node
node 2: parent = 1, sibling = 3, degree = 0, depth = 2, height = 0, leaf
node 3: parent = 1, sibling = 2, degree = 0, depth = 2, height = 0, leaf
node 4: parent = 0, sibling = 1, degree = 2, depth = 1, height = 2, internal node
node 5: parent = 4, sibling = 8, degree = 2, depth = 2, height = 1, internal node
node 6: parent = 5, sibling = 7, degree = 0, depth = 3, height = 0, leaf
node 7: parent = 5, sibling = 6, degree = 0, depth = 3, height = 0, leaf
node 8: parent = 4, sibling = 5, degree = 0, depth = 2, height = 0, leaf   Reference Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.

Solution (Python):
class node():
    def __init__(self, id, parent, child, depth, type_t, sibling, height=0):
        self.id = id
        self.parent = parent
        self.child = child
        self.depth = depth
        self.type_t = type_t
        self.sibling = sibling
        self.height = height


def add(t, d, i, parent, depth, sibling):
    type_t = 'internal node'
    if d[i][1] == -1 and d[i][2] == -1:
        type_t = 'leaf'
    if depth == 0:
        type_t = 'root'

    child = []
    if d[i][1] >= 0:
        child.append(d[i][1])
    if d[i][2] >= 0:
        child.append(d[i][2])

    new_node = node(i, parent, child, depth, type_t, sibling)
    t.append(new_node)
    sib = -1
    if len(child) == 1:
        add(t, d, child[0], i, depth + 1, sib)
    elif len(child) == 2:
        add(t, d, child[0], i, depth + 1, child[1])
        add(t, d, child[1], i, depth + 1, child[0])


def calc_height(t, i):
    if len(t[i].child) == 0:
        return 0
    max_h = -1
    for c in t[i].child:
        max_h = max(max_h, calc_height(t, c))
    return max_h + 1


N = int(input())
tree = []
data = [[] for i in range(N)]
for i in range(N):
    data[i] = [int(i) for i in input().split()]

data.sort(key=lambda x: x[0])
root = [True for i in range(N)]
for d in data:
    for c in d[1:]:
        if c == -1:
            continue
        root[c] = False

root_index = root.index(True)
add(tree, data, root_index, -1, 0, -1)

tree.sort(key=lambda x: x.id)

for i in range(N):
    h = calc_height(tree, i)
    tree[i].height = h


for t in tree:
    print(f'node {t.id}: parent = {t.parent}, sibling = {t.sibling},'
          f' degree = {len(t.child)}, depth = {t.depth},'
          f' height = {t.height}, {t.type_t}')

Solution (Python):
class BinaryTree:
    def __init__(self, node, children):
        self.node = node
        for i in range(2):
            try:
                children.remove(-1)
            except:
                pass
            
        self.children = children
        self.parent = -1
        try:
            self.sibling = self.parent.children.remove(self.node)[0]
        except:
            self.sibling = -1
        
        self.degree = len(children)
        self.depth = 0
        self.height = 0
        if len(children) == 0:    
            self.status = "leaf"
        else:
            self.status="root"
    
    def display(self):
        print("""node %d: parent = %d, sibling = %d, degree = %d, depth = %d, height = %d, %s"""
             %(self.node, self.parent, self.sibling, self.degree, self.depth, self.height, self.status))

n = int(input())
NODE_DICT = {}
root_search = {}
for loop in range(n):
    tmp_input = list(map(int, input().split()))
    tmp = BinaryTree(tmp_input[0], tmp_input[1:])
    NODE_DICT[tmp_input[0]] = tmp
    root_search[tmp_input[0]] = True
    
for loop in range(n):
    for element in NODE_DICT[loop].children:
        root_search[element] = False

for element in range(n):
    if root_search[element]:
        root = element

def Process(NODE_DICT, node, depth):
    
    NODE_DICT[node].depth = depth
    
    if len(NODE_DICT[node].children) != 0:
        if depth != 0:
            NODE_DICT[node].status = "internal node"
        height_list = []
        if len(NODE_DICT[node].children) == 2:
            NODE_DICT[NODE_DICT[node].children[0]].sibling, NODE_DICT[NODE_DICT[node].children[1]].sibling \
            = NODE_DICT[node].children[1], NODE_DICT[node].children[0]
        
        for child in NODE_DICT[node].children:
            NODE_DICT[child].parent = NODE_DICT[node].node
            Process(NODE_DICT, child, depth+1)
            height_list.append(NODE_DICT[child].height+1)
            
        NODE_DICT[node].height = max(height_list)
        
    else:
        if depth == 0:
            NODE_DICT[node].status = "root"
        NODE_DICT[node].height = 0
    
Process(NODE_DICT, root, 0)

for loop in range(len(NODE_DICT)):
    NODE_DICT[loop].display()

Solution (Python):

import sys


class Node:
    def __init__(self):
        self.parent = -1
        self.left = None
        self.right = None
        self.height = None
        self.depth = None
        self.sibling = -1
        self.type = 'internal node'
        self.deg = 0


def calc_depth(A, i):
    if A[i].depth:
        return A[i].depth

    if A[i].parent == -1:
        A[i].depth = 0
    else:
        A[i].depth = calc_depth(A, A[i].parent) + 1
    return A[i].depth


def calc_height(A, i):
    if A[i].height:
        return A[i].height

    if (A[i].left == -1) & (A[i].right == -1):
        A[i].height = 0
        return A[i].height

    if A[i].left == -1:
        A[i].height = calc_height(A, A[i].right) + 1
    elif A[i].right == -1:
        A[i].height = calc_height(A, A[i].left) + 1
    else:
        A[i].height = max(calc_height(A, A[i].left), calc_height(A, A[i].right)) + 1

    return A[i].height


n = int(input())

tree = []
for i in range(n):
    node = Node()
    tree.append(node)

for i in range(n):
    A = list(map(int, sys.stdin.readline().strip().split()))
    tree[A[0]].left = A[1]
    tree[A[0]].right = A[2]
    if A[1] != -1:
        tree[A[1]].parent = A[0]
        tree[A[1]].sibling = A[2]
        tree[A[0]].deg += 1
    if A[2] != -1:
        tree[A[2]].parent = A[0]
        tree[A[2]].sibling = A[1]
        tree[A[0]].deg += 1
    if (A[1] == -1) & (A[2] == -1):
        tree[A[0]].type = 'leaf'

for i in range(n):
    calc_depth(tree, i)
    height = calc_height(tree, i)
    if tree[i].parent == -1:
        node_type = 'root'
    else:
        node_type = tree[i].type

    print('node {}: parent = {}, sibling = {},'
          ' degree = {}, depth = {}, height = {}, {}'.format(i, tree[i].parent, tree[i].sibling,
                                                             tree[i].deg, tree[i].depth, height,
                                                             node_type))

Solution (Python):
n = int(input())

nodes = []
for _ in range(n):
    x = list(map(int, input().split()))
    nodes.append(x)
    
class Tree:
    def __init__(self, n):
        
        
        self.nodes = {node: {'parent': None, 'children': [], 'depth': None, 'height': None, 'sibling': None} for node in range(n)}
        
    def add_node_with_child(self, node, childlen):
        for c in childlen:
            self.nodes[node]['children'].append(c)
            self.nodes[c]['parent'] = node
    
    def get_parent(self, node):
        return self.nodes[node]['parent']
    
    def get_children(self, node):
        return self.nodes[node]['children']
        
    def get_depth(self, node):
        if self.nodes[node]['depth'] != None:
            return self.nodes[node]['depth']
        elif self.nodes[node]['parent'] == None:
            self.nodes[node]['depth'] = 0
            return 0
        else:
            depth = self.get_depth(self.nodes[node]['parent']) + 1
            self.nodes[node]['depth'] = depth
            return depth
        
    def get_height(self, node):
        if self.nodes[node]['height'] != None:
            return self.nodes[node]['height']
        elif len(self.nodes[node]['children']) == 0:
            self.nodes[node]['height'] = 0
            return 0
        elif self.nodes[node]['height'] == None:
            children = self.nodes[node]['children']
            children_h = [self.get_height(c)+1 for c in children]
            self.nodes[node]['height'] = max(children_h)
            return self.nodes[node]['height']
        
    def get_sibling(self, node):
        if self.nodes[node]['sibling'] != None:
            return self.nodes[node]['sibling']
        elif self.nodes[node]['parent'] == None:
            self.nodes[node]['sibling'] = []
            return self.nodes[node]['sibling']
        else:
            p = self.nodes[node]['parent']
            sibling = set(self.get_children(p))
            sibling.remove(node)
            self.nodes[node]['sibling'] = list(sibling)
            return self.nodes[node]['sibling']
        
RootedTree = Tree(n)
for t in nodes:
    node = t[0]
    childlen = []
    if t[1] != -1:
        childlen.append(t[1])
    if t[2] != -1:
        childlen.append(t[2])
    RootedTree.add_node_with_child(node, childlen)
    
for node in range(n):
    parent = RootedTree.get_parent(node)
    if parent == None:
        parent = -1
    depth = RootedTree.get_depth(node)
    height = RootedTree.get_height(node)
    childlen = RootedTree.get_children(node)
    degree = len(childlen)
    childlen = ', '.join(list(map(str, childlen)))
    sibling = RootedTree.get_sibling(node)
    if len(sibling) == 0:
        sibling = -1
    else:
        sibling = sibling[0]
    
    if parent == -1:
        node_type = 'root'
    elif childlen == '':
        node_type = 'leaf'
    else:
        node_type = 'internal node'
    
    print('node {}: parent = {}, sibling = {}, degree = {}, depth = {}, height = {}, {}'.format(node, parent, sibling, degree, depth, height, node_type))

Solution (Python):
class Node:

    def __init__(self, _id):
        self.id = _id
        self.left = None
        self.right = None
        self.parent = None

    def add_left(self, node):
        node.parent = self
        self.left = node

    def add_right(self, node):
        node.parent = self
        self.right = node

    @property
    def parent_id(self):
        if self.parent is None:
            return -1
        else:
            return self.parent.id

    @property
    def deg(self):
        count = 0
        if self.right is not None:
            count += 1
        if self.left is not None:
            count += 1
        return count

    @property
    def sibling_id(self):
        if self.parent is None or self.parent.deg == 1:
            return -1
        else:
            if self.parent.left == self:
                return self.parent.right.id if self.parent.right is not None else -1
            else:
                return self.parent.left.id if self.parent.left is not None else -1

    @property
    def node_type(self):
        if self.parent is None:
            return 'root'
        if self.left is None and self.right is None:
            return 'leaf'
        return 'internal node'

    @property
    def height(self):
        if self.left is None:
            left = -1
        else:
            left = self.left.height
        if self.right is None:
            right = -1
        else:
            right = self.right.height
        return max(left, right) + 1

    @property
    def depth(self):
        if self.parent is None:
            return 0
        else:
            return self.parent.depth + 1

    def __eq__(self, other):
        return self.id == other.id

    def __repr__(self):
        return 'node {}: parent = {}, sibling = {}, degree = {}, depth = {}, height = {}, {}'.format(
            self.id, self.parent_id, self.sibling_id, self.deg, self.depth, self.height, self.node_type)


def main():
    n = int(input())
    nodes = [Node(i) for i in range(n)]
    for _ in range(n):
        ID, left, right = map(int, input().split(' '))
        if left != -1:
            nodes[ID].add_left(nodes[left])
        if right != -1:
            nodes[ID].add_right(nodes[right])
    for node in nodes:
        print(node)


if __name__ == '__main__':
    main()

Solution (Python):
import sys
input = sys.stdin.readline

class Node:
    def __init__(self):
        self.parent = -1
        self.left = -1
        self.right = -1
        self.sibling = -1
        self.typ = "leaf"
        self.degree = 0

def getDepth(G, v, d=0):
    G[v].depth = d
    if G[v].right != -1:
        getDepth(G, G[v].right, d+1)
    if G[v].left != -1:
        getDepth(G, G[v].left, d+1)

def getHeight(G, v):
    h1, h2 = 0, 0
    if G[v].right != -1:
        getHeight(G, G[v].right)
        h1 = G[G[v].right].height + 1
    if G[v].left != -1:
        getHeight(G, G[v].left)
        h2 = G[G[v].left].height + 1
    G[v].height = max(h1, h2)

def main():
    n = int(input())
    G = [Node() for _ in range(n)]
    for _ in range(n):
        idx, l, r = map(int, input().split())
        G[idx].left = l
        G[idx].right = r
        if l != -1:
            G[l].parent = idx
            G[idx].typ = "internal node"
            G[idx].degree += 1
        if r != -1:
            G[r].parent = idx
            G[idx].typ = "internal node"
            G[idx].degree += 1
        if l != -1 and r != -1:
            G[l].sibling = r
            G[r].sibling = l
    root = [i for i, x in enumerate(G) if x.parent == -1][0]
    G[root].typ = 'root'
    getDepth(G, root)
    getHeight(G, root)
    for i, x in enumerate(G):
        print('node {}: parent = {}, sibling = {}, degree = {}, depth = {}, height = {}, {}'.format(i, x.parent, x.sibling, x.degree, x.depth, x.height, x.typ))

if __name__ == '__main__': main()

Solution (Python):
import sys


class Node():

	def __init__(self,id,left,right):
		
		self.id = id
		self.left = left
		self.right = right
		self.parent = -1
		self.sibling = -1
		self.degree = 0
		self.depth = 0
		self.height = 0

def define_depth(Nodes,node):

	if node.left == -1 and node.right == -1: 
		return

	if node.left != -1:
		Nodes[node.left].depth = node.depth + 1
		define_depth(Nodes,Nodes[node.left])
	if node.right != -1:
		Nodes[node.right].depth = node.depth + 1
		define_depth(Nodes,Nodes[node.right])

def define_height(Nodes,node):

	h1 = 0
	h2 = 0

	if node.left != -1:
		h1 += define_height(Nodes,Nodes[node.left]) + 1
	if node.right != -1:
		h2 += define_height(Nodes,Nodes[node.right]) + 1

	return max(h1,h2)

def find_root(Nodes,node):

	if node.parent == -1:
		return node.id

	return find_root(Nodes,Nodes[node.parent])


def test():

	n = int(sys.stdin.readline())
	Nodes = [Node(0,0,0)] * n
	root = 0

	
	for i in range(n):

		inputs = list(map(int,sys.stdin.readline().split()))
		id = inputs[0]
		left = inputs[1]
		right = inputs[2]

		tmp_node = Node(id,left,right)
		Nodes[id] = tmp_node

	
	for node in Nodes:

		child_count = 0

		
		if node.right != -1:
			Nodes[node.right].parent = node.id
			child_count += 1
		if node.left != -1:
			Nodes[node.left].parent = node.id
			child_count += 1

		
		node.degree = child_count

		
		if node.right != -1 and node.left != -1:
			Nodes[node.right].sibling = node.left
			Nodes[node.left].sibling = node.right

	
	root = find_root(Nodes,Nodes[0])

	
	define_depth(Nodes,Nodes[root])

	
	for node in Nodes:
		node.height = define_height(Nodes,node)

	for i in range(n):

		print(f"node {Nodes[i].id}: ",end='')
		print(f"parent = {Nodes[i].parent}, ",end='')
		print(f"sibling = {Nodes[i].sibling}, ",end='')
		print(f"degree = {Nodes[i].degree}, ",end='')
		print(f"depth = {Nodes[i].depth}, ",end='')
		print(f"height = {Nodes[i].height}, ",end='')

		if Nodes[i].parent == -1:
			print(f"root")
		elif Nodes[i].left == -1 and Nodes[i].right == -1:
			print(f"leaf")
		else:
			print(f"internal node")



if __name__ == "__main__":
	test()

Solution (Python):
class binaryTreeNode:
    def __init__(self, x):
        self.val = x
        self.right = None
        self.left = None

n = int(input())
hashMap = {}
rootL = list(range(n))
index = 0
while index < n:
    inputL = list(map(int, input().split()))
    if not inputL[0] in hashMap:
        hashMap[inputL[0]] = binaryTreeNode(inputL[0])
    parent = hashMap[inputL[0]]
    if inputL[1] != -1:
        rootL.remove(inputL[1])
        if inputL[1] in hashMap:
            leftN = hashMap[inputL[1]]
            parent.left = leftN
        else:
            leftN = binaryTreeNode(inputL[1])
            hashMap[inputL[1]] = leftN
            parent.left = leftN
    if inputL[2] != -1:
        rootL.remove(inputL[2])
        if inputL[2] in hashMap:
            rightN = hashMap[inputL[2]]
            parent.right = rightN
        else:
            rightN = binaryTreeNode(inputL[2])
            hashMap[inputL[2]] = rightN
            parent.right = rightN
    index+=1

answerL = ['']*n
root = hashMap[rootL[0]]
def lookNode(parentV, node, sibling, depth):
    if node != None:
        answer = ''
        answer+='node '+str(node.val)+': '
        answer+='parent = '+str(parentV)+', '
        if sibling != None:
            answer+='sibling = '+str(sibling.val)+', '
        else:
            answer+='sibling = '+str(-1)+', '
        if node.right != None and node.left != None:
            answer+='degree = '+str(2)+', '
        elif node.right == None and node.left == None:
            answer+='degree = '+str(0)+', '
        else:
            answer+='degree = '+str(1)+', '
        answer+='depth = '+str(depth)+', '
        height = 0
        if node.right == None and node.left == None:
            height = 0
        else:
            height = max(lookNode(node.val, node.left, node.right, depth+1), lookNode(node.val, node.right, node.left, depth+1))+1
        answer+='height = ' +str(height)+', '
        if parentV == -1:
            answer+='root'
        elif node.right == None and node.left == None:
            answer+='leaf'
        else:
            answer+='internal node'
        answerL[node.val] = answer
        return height
    else:
        return 0
lookNode(-1, root, None, 0)
for ans in answerL:
    print(ans)

Solution (Python):
import sys
input = sys.stdin.readline
from collections import deque

n = int(input())
P = [-1]*n
C = [[] for i in range(n)]
D = [[] for i in range(n)]
T = [[] for i in range(n)]
S = [-1]*n
deg = [0]*n
H = [-1]*n

Q1 = deque()
Q2 = deque()

for i in range(n):
  s = [int(i) for i in input().split()]
  id = s[0]
  l = s[1]
  r = s[2]
  C[id] = (l,r)
  if l != -1:
    P[l] = id
    S[l] = r
    deg[id] += 1
  if r != -1:
    P[r] = id
    S[r] = l
    deg[id] += 1
  if deg[id] == 0:
    T[id] = "leaf"
    Q2.append(id)
    H[id] = 0

for i in range(n):
  if P[i] == -1:
    root = i
    T[i] = "root"
  elif T[i] == []:
    T[i] = "internal node"

Q1.append(root)
D[root] = 0

while Q1:
  x = Q1.popleft()
  for nx in C[x]:
    if nx != -1:
      Q1.append(nx)
      D[nx] = D[x] + 1
while Q2:
  x = Q2.popleft()
  nx = P[x]
  if nx != -1:
    Q2.append(nx)
    H[nx] = max(H[x] + 1, H[nx])

for i in range(n):
  print("node {}: parent = {}, sibling = {}, degree = {}, depth = {}, height = {}, {}".format(i,P[i],S[i],deg[i],D[i],H[i],T[i]))

Solution (Python):
n = int(input())

"""親情報を入れる'p'、子情報を入れる'c'、深さを記録する'd'の、3つの辞書を作成"""
p, c, d = {}, {}, {}

for i in range(n):
    num, *children = input().split()
    c[num] = children
    for j in c[num]:
        if j != '-1':
            p[j] = num

def checkdepth(num, depth):
    d[num] = depth
    for i in c[num]:
        if i != '-1':
            checkdepth(i, depth+1)

"""高さを調べる関数。heightの引数には常に0を渡す"""
def checkheight(num, height):
    if c[num][0] != '-1':
        h1 = checkheight(c[num][0], height+1)
    else:
        h1 = height
    if c[num][1] != '-1':
        h2 = checkheight(c[num][1], height+1)
    else:
        h2 = height
    return max(h1, h2)

root = (set(c) - set(p)).pop()
p[root] = '-1'
checkdepth(root, 0)

def checksibling(num):
    if p[num] != '-1':
        for i in c[p[num]]:
            if i != '-1' and i != num:
                return i
                break
    return '-1'

def checkdegree(num, degree=0):
    for i in c[num]:
        if i != '-1':
            degree += 1
    return degree

for i in range(n):
    i = str(i)
    sibling = checksibling(i)
    degree = checkdegree(i, 0)
    if p[i] == '-1':
        nodetype = 'root'
    elif degree == 0:
        nodetype = 'leaf'
    else:
        nodetype = 'internal node'
    print('node {}: parent = {}, sibling = {}, degree = {}, depth = {}, height = {}, {}'.format(i, p[i], sibling, degree, d[i], checkheight(i, 0), nodetype))

Solution (Python):
class node:
    def __init__(self,parent, left, right):
        self.parent=parent
        self.left=left
        self.right=right

class binaryTree:

    def __init__(self, datas):
        
        
        self.T=[]
        for d in datas:
            self.T.append(node(-1, -1, -1))

        for d in datas:
            self.T[d[0]].left=d[1]
            self.T[d[0]].right=d[2]

        for d in datas:

            id=d[0]
            if(self.T[id].left != -1):
                self.T[self.T[id].left].parent = id
            if (self.T[id].right != -1):
                self.T[self.T[id].right].parent = id

        rootid=-1
        for d in datas:
            if(self.T[d[0]].parent == -1):
                rootid = d[0]
                

        self.Depth=[-1 for _ in range(len(datas))]
        self.Height=[-1 for _ in range(len(datas))]

        self.setDepth(rootid,0)

        for i in range(len(datas)):
            self.setHeight(i)


    def setDepth(self,id,depth):
        if(id!=-1):
            self.Depth[id]=depth
            self.setDepth(self.T[id].left, depth+1)
            self.setDepth(self.T[id].right, depth + 1)
            return
        return

    def setHeight(self, id):
        h1=0
        h2=0

        if(self.T[id].left != -1):
            h1=self.setHeight(self.T[id].left)+1
        if(self.T[id].right !=-1):
            h2=self.setHeight(self.T[id].right)+1
        self.Height[id]=max(h1,h2)
        return max(h1,h2)

    def getSibring(self,id):
        p=self.T[id].parent
        right=-1
        left=-1

        if(p!=-1):
            right=int(self.T[p].right)
        if(p!=-1):
            left=int(self.T[p].left)

        

        if(p == -1):
            return -1
        elif id != left and left != -1 :
            return left
        elif id != right and right != -1 :
            return right
        else:
            return -1


    def printNode(self,id):
        p=self.T[id].parent
        r=self.T[id].right
        l=self.T[id].left

        strs=""
        strs = strs+"node "+ str(id)+":"

        if(p==-1):
            strs=strs+" parent = -1"
        else:
            strs = strs + " parent = " + str(self.T[id].parent)
        strs=strs+", sibling = "+str(self.getSibring(id))

        deg=0
        if(r!=-1):
            deg=deg+1
        if(l!=-1):
            deg=deg+1
        strs=strs+", degree = "+str(deg)
        strs=strs+", depth = "+str(self.Depth[id])
        strs=strs+", height = "+str(self.Height[id])

        if(self.T[id].parent == -1):
            strs=strs+", root"
        elif(self.T[id].right == -1 and self.T[id].left == -1):
            strs=strs+", leaf"
        else:
            strs=strs+", internal node"

        return strs

n=int(input())
dlist=[]
for i in range(n):
    dlist.append(list(map(int,(input().split()))))
t=binaryTree(dlist)
for i in range(n):
    print(t.printNode(i))

Solution (Python):
from collections import deque

n = int(input())
C = [[] for i in range(n)]
Cnum = [0 for i in range(n)]
P = [-1 for i in range(n+1)]
S = [-1 for i in range(n+1)]
Dep = [0 for i in range(n)]
Deg = [0 for i in range(n)]
H = [0 for i in range(n)]
Typ = ["leaf" for i in range(n)]
for i in range(n):
    id,left,right=map(int,input().split( ))
    C[id] = [left,right]
    P[left] = id
    P[right] = id
    S[left] = right
    S[right] = left
    if left != -1:
            Deg[id] += 1
            Typ[id] = "internal node"
    if right != -1:
            Deg[id] += 1
            Typ[id] = "internal node"
for i in range(n):
    if P[i] == -1:
        root = i

Typ[root] = "root"

D = deque()
D.append(root)

while len(D)>0:
    t = D.popleft()
    d = Dep[t]
    left = C[t][0]
    right = C[t][1]
    if left != -1:
        D.append(left)
        Dep[left] = d+1
    if right != -1:
        D.append(right)
        Dep[right] = d+1

def height_child(i):
    global C,Cnum,H

    if C[i] == [-1,-1]:
        return [0,0]

    h = max(height_child(C[i][0])[0], height_child(C[i][1])[0])+1
    c = height_child(C[i][0])[1] + height_child(C[i][1])[1] + 2
    H[i] = h
    Cnum[i] = c

    return [h,c]

height_child(root)



for i in range(n):
 print('node {}: parent = {}, sibling = {}, degree = {}, depth = {}, height = {}, {}'.format(i,P[i],S[i],Deg[i],Dep[i],H[i],Typ[i]))

Solution (Python):
class Node:
    def __init__(self, p=-1, l=-1, r=-1):
        self._p = p
        self._l = l
        self._r = r

T = []
Depth = []
Height = []

def get_sibling(index):
    global T
    if T[index]._p == -1:
        return -1
    if T[T[index]._p]._l != index:
        return T[T[index]._p]._l
    if T[T[index]._p]._r != index:
        return T[T[index]._p]._r
    return -1

def print_node(index):
    global Depth
    global Height
    global T
    
    deg = 0
    if T[index]._l != -1:
        deg += 1
    if T[index]._r != -1:
        deg += 1
    
    print('node %d: parent = %d, sibling = %d, degree = %d, depth = %d, height = %d, '%(index, T[index]._p, get_sibling(index), deg, Depth[index], Height[index]), end='')

    if T[index]._p == -1:
        print('root')
    elif T[index]._l == -1 and T[index]._r == -1:
        print('leaf')
    else:
        print('internal node')

if __name__ == '__main__':
    n = int(input())

    for i in range(n):
        T.append(Node(-1, -1, -1))
        Depth.append(-1)
        Height.append(-1)

    for i in range(n):
        index, l_child, r_child = map(int, input().split())
        T[index]._l = l_child
        T[index]._r = r_child
        if l_child != -1:
            T[l_child]._p = index
        if r_child != -1:
            T[r_child]._p = index

    root = -1
    for i in range(n):
        if T[i]._p == -1:
            root = i
            break

    def rec(node, dep):
        Depth[node] = dep

        lh = rh = 0
        if T[node]._l != -1:
            lh = rec(T[node]._l, dep + 1) + 1
        if T[node]._r != -1:
            rh = rec(T[node]._r, dep + 1) + 1

        Height[node] = max(lh, rh)
        return Height[node]

    rec(root, 0)

    for i in range(n):
        print_node(i)

Solution (Python):
def compute_depth(node: int, depth: int) -> None:
    global trees
    trees[node]["depth"] = depth
    for child in trees[node]["children"]:
        compute_depth(child, depth + 1)


def compute_height(node: int, height: int) -> None:
    global trees
    trees[node]["height"] = height
    parent = trees[node]["parent"]
    if -1 != parent:
        compute_height(parent, height + 1)


if __name__ == "__main__":
    node_num = int(input())
    trees = {idx:
             {"parent": -1, "sibling": -1, "children": [], "depth": 0, "height": 0,
              "node_type": ""} for idx in range(node_num)}

    for _ in range(0, node_num):
        node, *children = map(lambda x: int(x), input().split())
        if (-1 != children[0]) and (-1 != children[1]):
            trees[node]["children"] = children
            trees[children[0]]["sibling"], trees[children[1]]["sibling"] = children[1], children[0]
            trees[children[0]]["parent"] = trees[children[1]]["parent"] = node
        elif [-1, -1] != children:
            child = children[0] * children[1] * (-1)
            trees[node]["children"] = [child]
            trees[child]["parent"] = node

    for node, values in sorted(trees.items(), key=lambda x: x[1]["parent"]):
        if -1 == values["parent"]:
            trees[node]["node_type"] = "root"
            compute_depth(node, 0)
        else:
            if [] == values["children"]:
                trees[node]["node_type"] = "leaf"
            else:
                trees[node]["node_type"] = "internal node"

    for node, values in sorted(filter(lambda x: x[1]["node_type"] == "leaf", trees.items()), key=lambda x: x[1]["depth"]):
        compute_height(node, 0)

    for node, values in trees.items():
        print("node {}: parent = {}, sibling = {}, degree = {}, depth = {}, height = {}, {}".format(
            node, values["parent"], values["sibling"], len(values["children"]), values["depth"], values["height"], values["node_type"]
        ))