在 MIPS 中使用递归搜索二叉树

时间:2021-03-27 23:24:19

标签: mips

我需要为下面的二叉树搜索编写一段代码(搜索函数)。

给出了一个伪代码示例并读取:

const Initial_State={
    current:null
}

export function UserReducer(state=Initial_State, action:any){
  switch (action.type){
    case 'ADD_USER':
        return{
            ...state,
            current: action.user
        };
    case 'DELETE_USER':
        return{
            ...state,
            current: null
        };
    default:
        return state;
  }
}

整个 MIPS 代码如下:

The code for search could look like:
call store_path
##           if (value == 1)
##             return 1
##           if (left tree exists)
##             if (search(left tree, depth+1))
##              return 1
##           if (right tree exists)
##             return search(right tree, depth+1)
##           return 0

我已经开始编写搜索功能:

    .text       
        .globl __start 
__start:        # execution starts here

    la $a0,tree
    li $a1,0
    jal search  # search the tree

    jal print_path  # print the path
            # to the node with val=1
    li $v0,10
    syscall     # au revoir....


#------------------------------------------------
# store_path - store pointer at level n in the path
#   a0 - holds pointer to string
#   a1 - level to use in path
#------------------------------------------------
store_path:
    sll $t0,$a1,2   # each pointer is 4 bytes
    sw $a0,path($t0)# save pointer to the name
    addi $t0,$t0,4  # make the next entry 
    sw $0,path($t0) #  equal to 0.
    jr $ra


#------------------------------------------------
# print_path() - print the items stored in path 
#------------------------------------------------
print_path:
        li $t0,0        # i 
        sll $t1,$t0,2   # each pointer is 4 bytes
        lw $a0,path($t1)
next:   li $v0,4    
        syscall         # print path[i]
        addi $t0,$t0,1  # i++
        sll $t1,$t0,2   # each pointer is 4 bytes
        lw $a0,path($t1)
        beqz $a0,done
        move $t1,$a0
        la $a0,arrow
        li $v0,4
        syscall         # print "-->"
        move $a0,$t1
        b next
done:   la $a0,endl
        li $v0,4
        syscall         # print newline
        jr $ra
path:   .space 80

tree:   .word name0, node1, node2, 0
node1:  .word name1, node3, node4, 0
node2:  .word name2, node5, node6, 0
node3:  .word name3, node7, 0, 0
node4:  .word name4, node8, node9, 0
node5:  .word name5, 0, 0, 0
node6:  .word name6, node10, node11, 0
node7:  .word name7, 0, 0, 0
node8:  .word name8, 0, 0, 0
node9:  .word name9, node12, node13, 0
node10: .word name10, 0, 0, 0
node11: .word name11, 0, 0, 0
node12: .word name12, node14, node15, 0
node13: .word name13, 0, 0, 0
node14: .word name14, 0, 0, 1
node15: .word name15, node16, node17, 0
node16: .word name16, 0, 0, 0
node17: .word name17, 0, 0, 0

name0:  .asciiz "apple"
name1:  .asciiz "orange"
name2:  .asciiz "bananna"
name3:  .asciiz "pear"
name4:  .asciiz "plum"
name5:  .asciiz "peach"
name6:  .asciiz "nectarine"
name7:  .asciiz "pineapple"
name8:  .asciiz "grapefruit"
name9:  .asciiz "grape"
name10: .asciiz "melon"
name11: .asciiz "avocado"
name12: .asciiz "star"
name13: .asciiz "mango"
name14: .asciiz "passion"
name15: .asciiz "cantaloupe"
name16: .asciiz "watermelon"
name17: .asciiz "apricot"
    
endl:   .asciiz "\n"
arrow:  .asciiz "-->"

关于如何实现 +1 深度和左右树搜索的任何提示或技巧将不胜感激!

1 个答案:

答案 0 :(得分:0)

  1. $t0 用于跟踪要推送的整数数量 到堆栈上。 $t1 用作临时变量以允许 在堆栈内轻松交换。 $s0 用于跟踪 栈底地址。 $s5 用来保存地址 高于 $sp;如果发生交换,也用于遍历地址 堆栈。 $s6 用于保存 $s5 的值。 $s7 用来保存 $s5 以下的地址。 $a1 保存底部的地址 堆。 $a2 保存传入整数的值。

.data numberOfInts:.asciiz“要存储的整数数量:” promptElement: .asciiz "\n输入要查找的整数:" promptInt: .asciiz "输入整数:" printSort: .asciiz "你的排序整数:" invalidSize: .asciiz "\n你必须大于零。\n\n" elementExists: .asciiz " 存在于堆栈中。\n" dosNotExist: .asciiz " 堆栈中不存在。\n" 添加空间:.asciiz“” 新行:.asciiz "\n" posInfinity:.word 0x7FFFFFFF
` 。文本 .globl 主

main: # 程序入口

li  $t0, 0          # $a1 is the counter i = 0

initializeNumInts: li $v0, 4 la $a0, numberOfInts syscall # "要存储的整数数量:" li $v0, 5 系统调用

ble $v0, $0, reinitialize

move    $s0, $v0
addi    $sp, $sp, -4        # Allocate space for the array size
sw  $s0, 0($sp)     # Store arraysize at the bottom of the stack
la  $a1, 0($sp)     # Remember the address of the bottom of the stack

插入到堆栈: bge $t0, $s0, findElement

li  $v0, 4          
la  $a0, promptInt
syscall             # "Enter Integer: "
li  $v0, 5
syscall

jal preSortStack

addi    $t0, $t0, 1     # counter++

j   insertToStack

查找元素: li $v0, 4
la $a0, promptElement syscall # "输入要查找的整数:" li $v0, 5 系统调用

move    $v1, $v0        # Element to be found
addi    $a1, $a1, -4        # High of the Stack, Largest Integer, Highest Address
la  $a2, 0($sp)     # Low of the Stack, Smallest Integer, Lowest Address
jal search

beq $v0, $zero, elementDNE  # if ($v0 == 0)

li  $v0, 1
move    $a0, $v1
syscall
li  $v0, 4
la  $a0, elementExists
syscall 
j   terminate

elementDNE:

li  $v0, 1
move    $a0, $v1
syscall
li  $v0, 4
la  $a0, doesNotExist
syscall 

终止: li $v0, 10 # 终止程序 系统调用

重新初始化: li $v0, 4 la $a0, invalidSize 系统调用 j initializeNumInts

<块引用>

Sort Stack Procedure 将元素从堆栈中添加到堆栈中 堆栈指针,然后将它们从最小到最大排序 栈顶的最小元素。 $a1 -- 地址 堆栈的底部。 $a2 -- 要推送到的元素的值 堆栈。

预排序堆栈: move $a2, $v0 # 将整数放入参数中 addi $sp, $sp, -4 # 为传入的整数分配空间 la $s5, 0($sp) # 跟踪堆栈中的地址 sw $a2, 0($sp) # 将传入的整数压入堆栈以占第一个输入

排序堆栈: move $s7, $s5 # $s7 跟踪之前的 $s5 的地址 addi $s5, $s5, 4 # 转到$s5上面的地址

beq $a1, $s5, exitSort  # If the address above the tracker is the bottom of the stack, exit the sort

lw  $s6, 0($s5)     # Get the value at the tracker
bgt $a2, $s6, swap      # if (incoming integer > value at below it in the stack), then swap values

sw  $a2, 0($sp)     # If the value above >= the incoming integer, push incoming integer onto stack

退出排序: jr $ra

交换:

move    $t1, $s6        # $t1 holds the value at tracker
sw  $a2, 0($s5)     # Store the incoming integer at the tracker
sw  $t1, 0($s7)     # Store $t1 at top of stack
move    $a2, $t1

j   sortStack       # Go back to sorting the stack in case there are smaller values above

堆栈是否包含过程 遍历堆栈以查找堆栈中的元素。 $a1 -- 要搜索的堆栈的 HIGH 索引的地址。 $a2 -- 要搜索的堆栈的 LOW 索引的地址。 $v1 -- 要在堆栈中找到的元素的值。

搜索: ble $a2, $a1, checkCases # test if (low <= high) li $v0, 0 # 如果不存在堆栈的任何部分。 jr $ra # 返回 0。

检查案例:

addu    $t0, $a2, $a1   
srl $t0, $t0, 1     # mid = (low + high) / 2

subu    $t1, $a1, $a2   
sra $t1, $t1, 2     # Number of Elements = (High - Low) / 4
addi    $t1, $t1, 1     # Align the number of elements to account for index 0.

andi    $t2, $t1, 1     # Check if number of elements is even or odd
beq $t2, $zero, even    # $t2 == 0, even number of elements have to be offset by 2 bits
j   saveValues

甚至: addiu $t0, $t0, -2 # 对齐字边界,中间地址 -2

保存值: lw $t1, 0($t0) # s[mid]

addi    $sp, $sp, -12
sw  $ra, 8($sp)     
sw  $a1, 4($sp)     # Save High Index
sw  $a2, 0($sp)     # Save Low Index

beq $t1, $v1, found     # if (s[mid] == val)
blt $t1, $v1, lowerStack
j   upperStack

下层堆栈: addi $a2, $t0, 4 # 低 = 中 + 1 日航搜索 j checkIfFound

上层堆栈: addi $a1, $t0, -4 # 高 = 中 - 1 jal搜索

checkIfFound: lw $a2, 0($sp) # 低指数 lw $a1, 4($sp) # 高指数 lw $ra, 8($sp)
addi $sp, $sp, 12

jr  $ra

发现: li $v0, 1 # 如果堆栈的一部分存在 jr $ra # 返回 1。 `

相关问题