2013-03-10 3 views
0

트리 구조를 구현하려고하지만 트리에서 데이터를 인쇄하려고 할 때 예기치 않은 결과가 표시됩니다.내 파이썬 트리의 문제점

올바른 결과는 다음과 같습니다

root 
- A1 
-- A2 
--- A3 
---- A4 
----- A5 

하지만 내가 가지고 :

root 
- A1 
-- A1 
--- A2 
~ infinite loop 

내 코드에 어떤 문제가 있습니까? 대답 해줄 수 있나요?

#!/usr/bin/python 
class TreeNode : 
    def __init__(self,key,obj=dict()) : 
     print 'Node with '+key+' is created' 
     self.key=key 
     self.child=obj 
    def add_child(self, key, obj) : 
     self.child[key]=obj 
     print 'child len ', 
     print len(self.child) 
    def get_child(self) : 
     for key in self.child.keys() : 
      print key, 
      pass 
     print '' 
     return self.child 
    def find_child(self,key) : 
     return self.child[key] 
    def is_leap(self) : 
     print 'is_leap ', 
     print len(self.child) 
     if len(self.child)==0 : 
      return 1 
     else : return 0 
    def append_rec(self,hier,data,depth) : 
     # hier & data are lists 
     if len(hier)== 1 : 
      print 'end of hierachy. append complete @ depth ', 
      print depth 
      return 

     tmp = hier[0] 
     tmp_child = hier[1:] 
     name = str(hier[0]) 
     print 'self ', 
     print tmp, 
     print 'childs ', 
     print tmp_child 
     child_list = self.get_child() 
     if child_list != None : 
      if not name in child_list.keys() : 
       lc = TreeNode(name) 
       self.add_child(name,lc) 
       return lc.append_rec(hier[1:],data,depth+1) 
      else : 
       lc =child_list[name] 
       return lc.append_rec(hier[1:],data,depth+1) 
    def print_all(self,depth) : 
     for i in range(depth) : print '-', 
     print self.key 
     if len(self.child) == 0 : return 
     if depth > 10 : 
      print 'depth limit over' 
      return 
     else : 
      for k in self.child.keys() : 
       print 'Looking child having key = '+k 
       return (self.child[k]).print_all(depth+1) 




    # recursive method 
class Tree : 
    index = 0 
    # root node of tree 
    def __init__(self) : 
     self.root=TreeNode('root') 
     self.index=0 
    def get_child(self) : 
     return self.root.get_child() 
    def print_all(self) : 
     self.root.print_all(0) 
    def traverse(self) : 
     node=self.root 
     depth=0 

     childs = node.get_child() 
     if node.is_leap() : return 
     else : 
      for c in childs.keys() : 
       print c, 
       return self.traverse_rec(childs[c],depth+1) 
     print ' end' 

    def traverse_rec(self,node,depth) : 
     i=0 
     print 'depth ', 
     print i, 
     childs = node.get_child() 
     if node.is_leap() : return 
     else : 
      for c in childs.keys() : 
       print c, 
       return self.traverse_rec(childs[c],depth+1) 
     print ' end' 


    def append(self,tup) : 
     # root 
     tmp = tup[0].split('/') 
     data = tup[1] 
     print 'root ['+data+']', 
     tmp_child = tmp[1:] 
     name = str(tmp[0]) 
     # if treenode with name tmp[0] 
     child_list = self.root.get_child() 
     if child_list != None : 
      if not name in child_list.keys() : 
       #print 'name = '+name 
       lc = TreeNode(name) 
       self.root.add_child(name,lc) 
       lc.append_rec(tmp_child,data,1) 
      else : 
       lc=child_list[name] 
       lc.append_rec(tmp_child,data,1) 


tree = Tree() 
test_string = ('A1/A2/A3/A4/A5','example1') 
tree.append(test_string) 
tree.print_all() 
+1

처음에는 (데이터 컨테이너 인) 노드가 길 * 너무 많아 보이는 것 같습니다 ... – Makoto

답변

1

기본 인수는 한 번만 평가됩니다. 따라서 명시적인 obj 인수없이 TreeNode을 만들 때마다 dict에 할당됩니다.

이 문제를 해결하는 한 가지 방법은 대신 기본 인수로 None을 사용하는 것입니다.

def __init__(self,key,obj=None) : 
    print 'Node with '+key+' is created' 
    self.key=key 
    self.child=obj if obj is not None else {} 

또 다른 옵션은 방어 복사본을하는 것입니다. 이것은 원하지 않을 때 우연히 참조로 dict을 전달하는 경우에 도움이 될 것입니다.하지만 다른 버그를 가릴 수도 있습니다. 또한 이것은 보통 당신이 원하는 것이지만 항상 그런 것은 아닌 얕은 복사만을 수행 할 것입니다.

def __init__(self,key,obj=dict()) : 
    print 'Node with '+key+' is created' 
    self.key=key 
    self.child=obj.copy() 
+0

작동 중입니다. 조언 해 주셔서 감사합니다. :) – syk

+0

@ 사용자 내 대답이 문제를 해결했다면 받아 들여야합니다. – Antimony