我实现了递归二进制搜索树,并且一旦设置了根,就很难添加节点。从概念上讲,我知道我需要做的事情,并举了一个简单的例子(如果图片怪异,我深表歉意)。 $ a0寄存器将具有一个变量的地址,该变量包含指向树的根节点的指针(即,指向根节点的指针的指针)。 $ a1寄存器是要添加到树中的数字。因此,遍历该示例,一开始$ a0将指向ptr_root,后者将指向新创建的根节点。节点结构包含当前节点的值(偏移量0),指向左子节点的指针(偏移量4)和指向右子节点的指针(偏移量8)。当您查看代码时,您会看到几行代码,其中使用了一个名为allocate_mem的例程,该例程使用这些字长字段来初始化结构。现在,一旦build_tree再次为另一个数字运行,如果有根,它将向右或向左递归。 它应该做的是更新$ a0,使其现在指向当前节点的左/右子节点。这就是我遇到的麻烦。我的程序现在无法运行,因为我进行的更改使我使用了不存在的内存。但是,当它确实运行时,它将仅显示根节点。我怀疑我是在加载left的值(而不是指针)还是没有更新指针。真正让我失望的是如何到达左侧或右侧的孩子,当然还要更新指针。有什么想法吗?
.globl allocate_mem
.globl ptr_root
#
# Name: build_tree
#
# Description: creates a new node with the provided number, and then insert
# this new node in the proper position in the binary search
# tree, updating whatever pointer is necessary.
#
# Arguments: a0 the address of the variable that contains the pointer to
# the root node of the tree (i.e., a pointer to a pointer to
# the root node).
# a1 the number to be inserted into the tree
#
build_tree:
addi $sp,$sp,-8
sw $ra, 4($sp)
sw $s0, 0($sp)
beq $a0, $zero, new_root
slt $t1, $a1, $s0
bne $t1, $zero, go_left
# lw $s0, 0($a0)
la $s0, 0($a0)
la $t5, 8($s0)
move $a0, $t5
jal build_tree
new_root:
li $a0, 3
jal allocate_mem
la $t3, ptr_root
lw $t4, 0($t3)
sw $a1, 0($v0)
sw $zero, 4($v0)
sw $zero, 8($v0)
sw $v0, 0($t3)
j finished
go_left:
# lw $s0, 0($a0)
la $s0, 0($a0)
la $t5, 4($s0)
move $a0, $t5
jal build_tree
finished:
lw $ra, 4($sp)
lw $s0, 0($sp)
addi $sp,$sp,8
jr $ra
编辑:仅更新我的进度。我做了一些研究,试图使我的程序正常工作,但还是没有运气。我能够运行它,但它仍然仅设置根目录。我的猜测是我要么覆盖$ a0,要么没有正确设置子树。在每次递减build_tree之前,我必须保存$ a0,但是无论如何,它要么导致访问不存在的内存,要么根本不执行任何操作。在最顶层,我尝试过将s寄存器保存在专用于存储$ a0的堆栈中,并在向左或向右移动时对$ a0进行单个加载,并带有必要的偏移量。但是我想那是不对的。另外,在图片中,我希望将12放在根中,不确定我在想什么放在3中,因为那没有意义。所以假装那是12。