简体   繁体   English

镜像通用树 - 我的错误是什么?

[英]Mirroring a Generic Tree - What's my mistake?

I'm dealing with a Generic Tree I'm representing in this way:我正在处理我以这种方式表示的通用树:

class GenericTree:
    """ A tree in which each node can have any number of children. 
    
        Each node is linked to its parent and to its immediate sibling on the right
    """ 
    def __init__(self, data):
        self._data = data
        self._child = None
        self._sibling = None
        self._parent = None        

And I have to mirror it, and recursion is allowed.我必须镜像它,并且允许递归。 I solved it in this way:我以这种方式解决了它:

def mirror(self):
        """ Modifies this tree by mirroring it, that is, reverses the order
            of all children of this node and of all its descendants
            
            - MUST work in O(n) where n is the number of nodes
            - MUST change the order of nodes, NOT the data (so don't touch the data !)
            - DON'T create new nodes            
            - It is acceptable to use a recursive method.
                    
            
            Example:
            
            a     <-    Becomes:    a
            ├b                      ├i
            │├c                     ├e
            │└d                     │├h
            ├e                      │├g
            │├f                     │└f 
            │├g                     └b
            │└h                      ├d
            └i                       └c
            
              
        """
        mylist=[] #Initializing a list
        if self._child: #If GenTree has children:
            current=self._child #initalizing the variable for the while loop
            while current: #until there are root's sons
                mylist.append(current) #I put it them in the list
                current=current._sibling #Going ahead to put all the sons in the list
            self._child=mylist[-1] #The _child is now the "rightest" one, i.e. the son that points to None
            #Now I iterate within the list in the opposite direction:

            for i in range(-len(mylist),0):
                mylist[i]._sibling=mylist[i+1] if i<-1 else None #I go from right to left #and I reverse in this way the sense of the list (if the sons were ROOT|->a->b->c, now they should be ROOT|->c->b->a
            for i in range(-len(mylist),0):
                mylist[i].mirror() #Doing the recursion for each son using them as roots

But It's not working: Here's an example of an error generated by my code:但它不起作用:这是我的代码生成的错误示例:

AssertionError: Children sizes are different !

ACTUAL    EXPECTED
a         a
├b        ├b
│└d       │├d          <--- DIFFERENT !
└e        │└c
          └e

What am I doing wrong?我究竟做错了什么?

Consider the following:考虑以下:

for i in range(-1, -10, -1):
  print(i)
-1                                                                     
-2
-3
-4
-5
-6
-7
-8
-9  

This is what you want to do if you intend to reverse the siblings in the list, but what you are doing is to start from -9 and go to -1 , which is from the beginning of the list to its end.如果您打算反转列表中的兄弟姐妹,这就是您想要做的,但是您要做的是从-9和 go 开始到-1 ,即从列表的开头到结尾。

So, the sibling of the node at -1 becomes the node at -2 , etc. up until the sibling for element at 0 or -len(mylist) becomes None .因此,位于-1的节点的兄弟节点变为位于-2的节点,依此类推,直到位于0-len(mylist)的元素的兄弟节点变为None

Change your loop as follows:改变你的循环如下:

            for i in range(-1, -len(mylist), -1):
                mylist[i]._sibling=mylist[i-1]
            mylist[0]._sibling = None

To avoid all of the hassle of negative indexing you can also reverse your list and index it from the start as follows:为了避免负面索引的所有麻烦,您还可以反转您的列表并从一开始就对其进行索引,如下所示:

            mylist.reverse()
            for i in range(len(mylist)-1):
              mylist[i]._sibling = mylist[i+1]
            mylist[-1]._sibling = None

As others explained, you are still accessing the list items in their original order, even when using negative indexes.正如其他人解释的那样,即使使用负索引,您仍然可以按原始顺序访问列表项。

Still, I'd like to point out that such code challenges are intended for you to not use a standard list as helper, but to solve this without using such auxiliary data structure.不过,我想指出,此类代码挑战旨在让您不使用标准列表作为帮助程序,而是在不使用此类辅助数据结构的情况下解决此问题。

You can reverse a linked list by traversing it with 3 references, one lagging behind the other, and another leading in front of it.您可以通过使用 3 个引用遍历链表来反转链表,一个在另一个后面,另一个在它前面。 In Python, you can even do it with 2 references and tuple assignment.在 Python 中,您甚至可以使用 2 个引用和元组分配来实现。

As the siblings structure is essentially a linked list, you can use that approach:由于兄弟结构本质上是一个链表,您可以使用该方法:

    def mirror(self):
        # Reverse linked list of siblings
        prev = None
        current = self._child
        while current:
            current.mirror()  # Recursion
            # Create backwards link and move forward
            current._sibling, prev, current = prev, current, current._sibling
        self._child = prev

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM