MIPS中二叉树中最长的路径

时间:2018-05-13 11:09:42

标签: algorithm assembly mips

以这种方式给出二叉树:

.data
tree: .word a
a: .word 5, b, c
b: .word 2, d, e 
c: .word 1, 0, 0
d: .word 5, f, g
e: .word 9, 0, h
f: .word 0, 0, 0
g: .word 6, i, 0
h: .word 55, 0, j
i: .word 4, 0, 0
j: .word 8, 0, 0

树看起来像这样:How the tree looks like 所以最长的路径是经过i-g-d-b-e-h-j的7路。

所以我的问题是如何实现这个? 我需要在堆栈中使用多少空间?

我需要使用0-4到左边孩子的值4-8和右边孩子的8-12值?

我的意思是如何从根目录进入下一个孩子?

1 个答案:

答案 0 :(得分:1)

  

如何移动此数据?

给定指向$a0中节点的指针,左右指针距节点起点的4字节偏移量。 (节点结构的第一个成员似乎是一个整数,但你不需要对它做任何事情。)所以 lw $t1, 4($a0) 加载第二个结构成员(即{ {1}}),node->left加载lw $t2, 8($a0)

您可以通过与零寄存器进行比较来检查NULL,即node->right,如下所示:
0

我认为您的搜索算法应该进行树遍历,查找具有最大beq $t1, $0, left_was_zero 的节点。正常的有序遍历将考虑每个节点一次。

递归算法是显而易见的方法,但您可能希望在寄存器中保留一些持久状态,即在递归调用中将它们用作全局变量。所以你可以保持很多状态"生活"在寄存器中而不是以一个天真的C编译器的方式实际传递/返回它。我将使用全局寄存器变量表示它。

maxdepth(left) + maxdepth(right)

您可以使用实际递归来实现此功能;这可能比跟踪您是否在节点的左子树或右子树中以及在调用堆栈上使用堆栈数据结构更容易。带有返回地址的register unsigned longest_len asm("$t8") = 0; register node* longest_root asm("$t9") = NULL; // private helper function // returns max depth, updates global registers along the way static unsigned traverse(node *root) { unsigned left_depth=0, right_depth=0; if (root->left) left_depth = traverse(root->left); if (root->right) right_depth = traverse(root->right); unsigned sum = left_depth + right_depth; if (sum >= longest_len) { // update global registers longest_len = path + 1; // path includes *this* node longest_root = root; } // you can probably save an instruction somewhere by optimizing the +1 stuff between the retval and the longest_len check int retval = left_depth + 1; // $v0 if (left_depth < right_depth) retval = right_depth + 1; // +1 to include this node return retval; } node *find_longest_path(node *tree) { longest_len = 0; // longest_root = NULL; // will always be overwritten traverse(tree); return longest_root; } / jal是一种方便的方式来跟踪要返回的块。

无论如何,这应该直接转化为MIPS asm;它甚至可能使用全局寄存器变量进行编译(使用gcc),因为我认为我使用了jr https://gcc.gnu.org/onlinedocs/gcc/Global-Register-Variables.html

的正确语法