我最近一直在想,并提出了两个选项来找到2-3-4树的顺序遍历。其中一个是递归方法,在节点类型上有一个switch case,另一个是迭代方法。对于背景,此遍历的目标是从上面的树中生成以下元素集。
[S]
/ \
[J O] [U]
/ | \ / \
[EH] [MN] [PQR] [T] [VWX]
{ {E} {H} {J} {M} {N} {O} {P} {Q} {R} {S} {T} {U} {V} {W} {Z} }
由于节点上只能有2个或3个子节点,因此我认为以下任一方法都可以工作(伪代码)。
第一种方法是根据节点的当前大小,在必要时从根左,中左,中右,右递归:
list = new list
234InOrder(Node cur):
switch(cur.numElems)
case 1: // 2-node
234InOrder(cur.child[0])
list.add(cur.child[0])
234InOrder(cur.child[1])
break;
case 2: // 3-node
234InOrder(cur.child[0])
list.add(cur.child[0])
234InOrder(cur.child[1])
list.add(cur.child[1])
234InOrder(cur.child[2])
break;
case 3: // 4-node
234InOrder(cur.child[0])
list.add(cur.child[0])
234InOrder(cur.child[1])
list.add(cur.child[1])
234InOrder(cur.child[2])
list.add(cur.child[2])
234InOrder(cur.child[3])
break;
或者迭代地转到最左边的节点,"得到"来自该节点的每个元素,返回到父节点,继续到下一个子节点,重复该过程。一旦看到所有的孩子,转到父/ root并从根的inorder继承者开始重复该过程(抱歉没有伪代码)。
哪种方法更适合在树中获取所需的元素集?
答案 0 :(得分:0)
我建议使用递归解决方案,因为它更易于实现和阅读。 你也可以使用循环来摆脱这三种情况。
假设您的节点数据结构是这样的:
class 234Node:
keys: list of KeyType
childs: list of Nodes
# with 1 <= len(items) == len(childs) - 1 <= 3
将是(以pythonic表示法):
def inorder_traversal(node, inorder):
if not node:
return
inorder_traversal(node.childs[0])
for i in range(len(node.keys)):
inorder.append(node.keys[i])
inorder_traversal(node.childs[i+1])
# and use
t = someTree
inorder = []
inorder_traversal(t.root, inorder)