2013-03-10 84 views
0

我試圖實現一個樹結構,但是當我試圖在我的樹中打印數據時, 顯示了意外的結果。我的Python樹有什麼問題

正確的結果將是:

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 2013-03-10 05:29:27

回答

1

在Python中,默認參數只計算一次。因此,每次創建TreeNode而沒有明確的obj參數時,它都會被分配到字典字典。

解決此問題的一種方法是使用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 {} 

另一種選擇是做一個防禦性的副本。這將有助於在您不想要的時候通過引用意外傳遞字典,但這意味着它可能會掩蓋其他錯誤。還要注意,這隻會做一個淺拷貝,這通常是你想要的,但並非總是如此。

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

它的工作。感謝您的建議。 :) – syk 2013-03-10 05:52:23

+0

@用戶如果我的答案解決了您的問題,您應該接受它。 – Antimony 2013-03-10 13:09:14