我正在尝试以看起来更好的方式打印树。当前,我在节点之前添加选项卡以显示其级别。即:
top
middle
bottom
middle1
我想做的是用Unicode行替换这些标签,以显示它们如何链接。即:
top
├── middle
│ └── bottom
└── middle1
这就是CHAIDS树的工作,这是我想要实现的。
我的当前代码:
import pickle
class Node:
def __init__(self, data=None):
self.data = data
self.nextNodes = []
self.level = 0
def printNodes(self, startPoint=None):
if startPoint:
if self.data == startPoint:
print(('\t' * self.level) + self.data)
if self.nextNodes:
for i in self.nextNodes:
i.level = self.level + 1
i.printNodes()
self.level = 0
else:
if self.nextNodes:
for i in self.nextNodes:
i.printNodes(startPoint)
else:
print(('\t' * self.level) + self.data)
if self.nextNodes:
for i in self.nextNodes:
i.level = self.level + 1
i.printNodes()
self.level = 0
def findVal(self, value):
if self.data != value:
if self.nextNodes:
for i in self.nextNodes:
if i.findVal(value):
return True
else:
return True
def deleteRequest(self, data, startPoint=None):
if startPoint:
if self.data == startPoint:
if self.nextNodes:
for counter, i in enumerate(self.nextNodes):
if i.data == data:
self.nextNodes.pop(counter)
return True
for i in self.nextNodes:
return i.deleteRequest(data)
else:
if self.nextNodes:
for i in self.nextNodes:
return i.deleteRequest(data, startPoint)
else:
if self.nextNodes:
for counter, i in enumerate(self.nextNodes):
if i.data == data:
self.nextNodes.pop(counter)
return True
for i in self.nextNodes:
return i.deleteRequest(data)
def modifyRequest(self, data, newData, startPoint=None, childModification=None):
if startPoint:
if startPoint == self.data or childModification:
if self.data == data:
self.data = newData
else:
if self.nextNodes:
for i in self.nextNodes:
return i.modifyRequest(data, newData, startPoint, childModification)
else:
if self.data == data:
self.data = newData
return True
else:
if self.nextNodes:
for i in self.nextNodes:
return i.modifyRequest(data, newData)
def insertRequest(self, data, parent):
if self.data == parent:
for i in self.nextNodes:
if i.data == data:
return False
temp = Node(data)
self.nextNodes.append(temp)
return True
else:
if self.nextNodes:
for i in self.nextNodes:
return i.insertRequest(data, parent)
class Head:
def __init__(self):
self.headNode = None
def printList(self, startPoint=None):
print('--TREE--')
self.headNode.printNodes(startPoint)
print('\n')
def findVal(self, value):
if self.headNode.findVal(value):
print("'%s' found" % value)
else:
print("'%s' not found" % value)
def insertNode(self, data, parent):
if self.headNode.insertRequest(data, parent):
print("Successfully added a node %s" % data)
else:
print("Unsuccessfully added a node")
def deleteNode(self, data, startingPoint=None):
if self.headNode.deleteRequest(data, startingPoint):
print("Node %s has been successfully deleted" % data)
else:
print("Node %s has not been deleted - it was not found or it was the head node" % data)
def modifyNode(self, data, newData, startingPoint=None):
if self.headNode.modifyRequest(data, newData, startingPoint):
print("Node %s has successfully changed to %s" % (data, newData))
else:
print("Node modification unsuccessful")
help = ''''
---TREE---
use treeN to use tree
-p x prints the tree, 'x' being the optional starting point
-fv x finds value 'x' in tree
-i x y inserts a node, with 'x' being the data and 'y' being the parent
can't have multiple siblings with the same name
-d x y deletes a node with 'x' being the data type and optional 'y' being the parent(excluding)
-m x y z modifies a node, with 'x' being the old data, 'y' being the new data
and 'z' being the optional parent(excluding)
-s x save to a file, 'x' being the file name, exclude extension
-l x load a tree from a file, 'x' being the file name, exclude extension
-exit exits the program
Rules:
+ one command per input
+ use ; as separators, leave no spaces
'''
print(help)
inp = input("Name of head Node: ")
tree = Head()
NH = Node(inp)
tree.headNode = NH
while True:
try:
inp = input('Enter command, type ? for help')
if inp == '?':
print(help)
command = inp.split(';')
commandL = len(command)
cmdPrompt = command[0]
if cmdPrompt == '-exit':
break
elif cmdPrompt == '-p':
if commandL != 1 and commandL != 2:
print("Incorrect amount of arguments")
continue
else:
if commandL == 2:
tree.printList(command[1])
else:
tree.printList()
elif cmdPrompt == '-fv':
if commandL != 2:
print("Incorrect amount of arguments")
continue
else:
tree.findVal(command[1])
elif cmdPrompt == '-i':
if commandL != 3:
print("Incorrect amount of arguments")
continue
else:
tree.insertNode(command[1], command[2])
elif cmdPrompt == '-d':
if commandL != 2 and commandL != 3:
print("Incorrect amount of arguments")
print(command)
continue
else:
if commandL == 2:
tree.deleteNode(command[1])
elif commandL == 3:
tree.deleteNode(command[1], command[2])
elif cmdPrompt == '-m':
if commandL != 3 and commandL != 4:
print("Incorrect amount of arguments")
continue
elif commandL == 3:
tree.modifyNode(command[1], command[2])
elif commandL == 4:
tree.modifyNode(command[1], command[2], command[3])
elif cmdPrompt == '-s':
if commandL != 2:
print("Incorrect amount of arguments")
continue
else:
fName = command[1] + '.p'
pickle.dump(tree, open(fName, 'wb'))
print("Successfully saved to file '%s'" % fName)
elif cmdPrompt == '-l':
if commandL != 2:
print("Incorrect amount of arguments")
continue
else:
fName = command[1] + '.p'
tree = pickle.load(open(fName, 'rb'))
print("Successfully loaded tree '%s'" % fName)
except BaseException as error:
print("Something went wrong: %s" % error)
print('done')
现在,我正在使用我认为的预定方式遍历树-
这棵树不是二叉树,这意味着每个节点可以有任意数量的子代,不受左右限制。
考虑到每个节点有多少个孩子,我已经尝试过将级别和所需的符号发送给每个孩子,但是由于树变得更加复杂,所以它不起作用。