试图在Python中实现树并计算它的高度

发布于 2025-02-11 09:46:09 字数 1308 浏览 1 评论 0原文

class node:
    parent=None
    data=None
    children=[]


def __init__(self, parent, data):
    self.data=data
    self.parent=parent


def set_parent(self, parent):
    self.parent=parent

def set_data(self, data):
    self.data=data

def create_node(parent, data):
    return node(parent, data)

class tree:
    nodes=[]
    root=node(None, None)

    def set_root(self, data, parent=None):
        self.root=node(parent, data)
        return self.root

    def get_root(self):
        return self.root

   def get_nodes(self):
        return self.nodes


def cal_height(Tree):
    h=[]
    if len(Tree.root.children)==0:
        return 1
    for child in Tree.root.children:
        t=tree()
        t.set_root(child.parent, child.data)
        height= 1+ cal_height(t)
        h.append(height)
    return max(h)




l1=input()
l=input().split()
Tree=tree()
for n, i in enumerate(l):
    if n==-1:
        Tree.nodes.append(Tree.set_root(i))

    else:
        Tree.nodes.append(create_node(n, i))

for p in Tree.nodes:
    for c in Tree.nodes:
        if p.data==c.parent:
            p.children.append(c)

for j in Tree.nodes:
    print(j.children)

我一直在尝试创建一棵树并计算分配的高度。这是我到目前为止写的代码,但显然,没有一个孩子的节点附加。

代码的输入以 - 例如 - 4 -1 4 1 1

带有-1的索引值是根节点,而其他输入表示相应的值是其父节点。

class node:
    parent=None
    data=None
    children=[]


def __init__(self, parent, data):
    self.data=data
    self.parent=parent


def set_parent(self, parent):
    self.parent=parent

def set_data(self, data):
    self.data=data

def create_node(parent, data):
    return node(parent, data)

class tree:
    nodes=[]
    root=node(None, None)

    def set_root(self, data, parent=None):
        self.root=node(parent, data)
        return self.root

    def get_root(self):
        return self.root

   def get_nodes(self):
        return self.nodes


def cal_height(Tree):
    h=[]
    if len(Tree.root.children)==0:
        return 1
    for child in Tree.root.children:
        t=tree()
        t.set_root(child.parent, child.data)
        height= 1+ cal_height(t)
        h.append(height)
    return max(h)




l1=input()
l=input().split()
Tree=tree()
for n, i in enumerate(l):
    if n==-1:
        Tree.nodes.append(Tree.set_root(i))

    else:
        Tree.nodes.append(create_node(n, i))

for p in Tree.nodes:
    for c in Tree.nodes:
        if p.data==c.parent:
            p.children.append(c)

for j in Tree.nodes:
    print(j.children)

I have been trying to create a tree and calculate it's height for an assignment. This is the code I've written so far but apparently, none of the children's nodes are being appended.

The input to the code is given as, for example-
4 -1 4 1 1

the index value with -1 is the root node, while the other inputs indicate that corresponding values are their parent nodes.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冷情妓 2025-02-18 09:46:09

您的代码中存在这些问题:

  • 儿童被定义为类属性,因此每当您查看j.children时,它始终是 所有节点共享的列表。您的班级不应具有任何类属性。对于数据parent属性,您的也将它们定义为实例属性,因此不会出现问题。修复如下:

     类节点:
        #删除类属性
    
        def __init __(自我,父,数据):
            self.data =数据
            self.parent = parent
            self.Children = []#添加
     

  • 条件p.data == c.parent永远不正确,因为它将字符串与数字进行比较。为了避免这种情况,请首先将输入列表转换为程序开始时的数字列表:

      l = list(map(int,input()。split()))
     
  • 枚举将以 first the Index返回元组,而< em>然后值。您以相反的方式拆开了元组,因此永远无法正确建造树。更改:

      n,i在枚举(l)中:
     

    to:

      i,n in Enumerate(l)中的n:
     
  • 叶节点的高度应为0,因为高度的形式定义是从根到叶子的最长路径的长度。路径的长度在边缘的数量中表示。由于只有一个节点的树中没有边缘,因此该节点的高度应为0。

    so:

     如果len(tree.root.children)== 0:
        返回0#不是1
     

  • cal_height使用此语句设置新的根部时会出错:

      t.set_root(child.parent,child.data)
     

    在这里,您可以制作一个没有孩子的节点!因此,即使儿童有孩子,也不会考虑他们。递归调用cal_height现在不会带来任何有用的东西:它将始终返回1。

  • cal_height不需要创建新的树和节点实例。您已经有了树,此功能不需要更改它。它应该是只读操作。

    需要对此功能进行全面审查。我提出了这一点:

      def cal_height(tree):
    
        DEF高度(节点):
            如果不是节点:
                返回-1
            返回1 + max(MAP(高度,Node.Children),默认值= -1)
    
        返回高度(树根)
     

随着这些更改,它将起作用。

没有树,

您实际上根本不需要创建树或节点。这可以通过仅列出每个节点的 的列表来完成。如果在每个节点(索引)中,您请按照父录制为止,直到遇到-1,那么您确实走到 up 并知道您启动的原始节点的深度。通过在途中注册所有节点的深度,您可以避免一遍又一遍地旅行相同的子路。深度最大的节点的深度等于树的高度。

扰流板解决方案:

def get_height(父母):
深度= [-1] * len(父母)

def get_depth(i):
如果i == -1:
返回-1
如果深度[i] == -1:
深度[i] = 1 + get_depth(父母[i])
返回深度[i]

因为我在范围(len(父母)):
get_depth(i)
返回最大(深度)

n =输入()
父母= list(MAP(int,input()。split()))
高度= get_height(父母)
打印(高度)

There are these issues in your code:

  • children is defined as a class attribute, so whenever you look at j.children, it is always the same list that is shared by all nodes. Your class should not have any class attributes. For the data and parent attributes, you have also defined them as instance attributes, so there the problem does not occur. Fix as follows:

    class node:
        # removed class attributes
    
        def __init__(self, parent, data):
            self.data=data
            self.parent=parent
            self.children = []  # added
    
  • The condition p.data==c.parent is never true, because it compares a string with a number. To avoid this, first convert the input list to a list of numbers at the start of your program:

    l = list(map(int, input().split()))
    
  • enumerate will return a tuple with first the index, and then the value. You unpacked that tuple in the opposite way, and so the tree could never be built correctly. Change:

    for n, i in enumerate(l):
    

    to:

    for i, n in enumerate(l):
    
  • The height for a leaf node should be 0, since the formal definition of height is the length of the longest path from the root to a leaf. The length of a path is expressed in the number of edges. As there is no edge in a tree with just one node, the height should be 0 for such a node.

    So:

    if len(Tree.root.children)==0:
        return 0  # not 1
    
  • cal_height goes wrong when it sets a new root with this statement:

    t.set_root(child.parent, child.data)
    

    Here you make a node that has no children! So even if child had children, they will not be considered. The recursive call to cal_height will not bring anything useful now: it will always return 1.

  • cal_height shouldn't need to create new tree and node instances. You already have the tree, and this function should not need to change anything to it. It should be a read-only operation.

    This function needs to be completely reviewed. I propose this:

    def cal_height(Tree):
    
        def height(node):
            if not node:
                return -1
            return 1 + max(map(height, node.children), default=-1)
    
        return height(Tree.root)
    

With these changes it will work.

Without tree

You actually don't need to create a tree or nodes at all. This can be done with a mere list that logs the depth of each node. If from each node (index) you follow the parent references until you encounter -1, then you really walk up the tree and know the depth of the original node you started from. By registering the depths for all the nodes along the way you can avoid traveling the same subpaths over and over again. The node that has the greatest depth, has a depth that is equal to the height of the tree.

Spoiler solution:

def get_height(parents):
depths = [-1] * len(parents)

def get_depth(i):
if i == -1:
return -1
if depths[i] == -1:
depths[i] = 1 + get_depth(parents[i])
return depths[i]

for i in range(len(parents)):
get_depth(i)
return max(depths)

n = input()
parents = list(map(int,input().split()))
height = get_height(parents)
print(height)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文