qselect MIPS汇编程序中的错误



下面是mips中的快速选择算法。这里有个错误,但我找不到。Qselect函数不能正确工作,但其他函数似乎很好。我花了很多时间试图调试它,但它在火星上编译没有错误。它只是不像预期的那样工作

如何测试:

n: .word 4
v: .word 3, 10, 8, 2
k: .word 2
correct: 8 but the program finds 2
n: .word 21
v: .word 10, 3, 7, 21, 20, 15, 14, 24, 9, 5, 1, 22, 16, 13, 12, 18, 4, 6, 19, 17, 2
k: .word 12
correct:15  but the program finds 19
swap: # swap entry point
la $t0, v   #t0 = address of v
sll $t1, $a0, 2     #t1 = 4*a0 = 4*i
add $t1, $t0 , $t1   #t1 = address of v[i]
lw $t2, 0($t1)  # t2=v[i]
sll $t3, $a1, 2     #t3 = 4*a1 = 4*j
add $t3, $t0 , $t3  #t3 = address of v[j]
lw $t4 , 0($t3)     #t4 = v[j]
sw $t4 , 0($t1)     #v[i] = v[j]
sw $t2, 0($t3) # v[j] = v[i]
jr      $ra         # return to caller

partition:
addi $sp, $sp, -16              #adjust stack for 4 items
sw $ra, 0($sp)                  #store ra in stack
sw $s0, 4($sp)                  #store s0
sw $a0, 8($sp)                  #store a0
sw $a1, 12($sp)                 #store a1

la $s0, v                       #load address of v0 in s0

sll $t0, $a1, 2                 #t0 stores 4 * l
add $t0, $t0, $s0               #t0 stores ad. of v[l]
lw $t1, 0($t0)                  #t1 contains v[l] (t1 pivot)
add $t2, $a0, $zero             #t2 is f (t2 i)
add $t3, $a0, $zero             #t3 is f (t3 j)

for1:   slt $t4, $t3, $a1               #sets 1 to t4 if j < l
beq $t4, $zero, exit            
sll $t5, $t3, 2                 #t5 is 4 * j
add $t5, $t5, $s0               #t5 stores ad. of v[j]
lw $t6, 0($t5)                  #t6 has the value of v[j]

slt $t4, $t6, $t1               #sets 1 to t4 if v[j] < pivot
beq $t4, $zero, bfor

add $a0, $t2, $zero             #a0 is i
add $a1, $t3, $zero             #a1 is j

addi $sp, $sp, -12              #adjust stack for 3 items
sw $t1, 0($sp)
sw $t2, 4($sp)
sw $t3, 8($sp)                  #store pivot, i, j in stack
jal swap                        #call swap

lw $t1, 0($sp)
lw $t2, 4($sp)
lw $t3, 8($sp)                  #restores pivot, i, j before the call
addi $sp, $sp, 12               #return items to stack

lw $a1, 12($sp)                 #restore initial a1

addi $t2, $t2, 1                #i++
j bfor                          

bfor:   addi $t3, $t3, 1                #j++
j for1                          #continue loop        


exit:   add $a0, $t2, $zero             #a0 is i
addi $sp, $sp, -4               #adjust stack for 1 item
sw $t2, 0($sp)                  #store i
jal swap                        #calls swap
lw $v0, 0($sp)                  #returns i
addi $sp, $sp, 4                #returns item to stack

lw $ra, 0($sp)                  #restore initial ra in stack
lw $s0, 4($sp)                  #restore initial s0
lw $a0, 8($sp)                  #restore initial a0
lw $a1, 12($sp)                 #restore initial a1
addi $sp, $sp, 16               #return items to stack
jr      $ra

qselect:
# a0 = f
# a1 = l
# a2 = k
addi $sp, $sp, -4 #adjust stack for 1 item
sw $ra, 0($sp)
if1:
#if !(f < 1+l) goto else0
addi $t0, $a1, 1 #t0 = l+1
slt $t0, $a0, $t0 #if f<1+l t0 = 1
beq $t0, $zero, else0 # if t0 = 0 goto else0
#j partition
partition:  #int p = partition(f,l);
jal partition #v0 becomes p
lw $ra, 0($sp) #restore ra
#j if3
if3:
#if (p==k) goto else_if2 
beq $v0, $a2,else_if2

if2:  #if p < k return qselect(f,p-1,k);
slt $t1, $a2, $v0 #if p > k, t1 = 1
beq $t1, $zero, qselectp1lk # if t1 = 0 goto qselectp1lk
#j qselectfp1k
qselectfp1k:
#return qselect(f,p-1,k);
addi $a1, $a1, -1 # a1 = p-1
jal partition
lw $ra, 0($sp) # restore ra
j end_qselect
else0: #return v[f];
la $t0, v # t0 = address of v
sll $t1, $a0, 2 # t1 = 4*f
add $t1, $t1, $t0 #t1 = address of v[f]
lw $v0, 0($t1) #v0 = v[f]
j end_qselect

else_if2:
#return v[k];
la $t0, v # t0 = address of v
sll $t1, $a2, 2 # t1 = 4*k
add $t1, $t1, $t0 #t1 = address of v[k]
lw $v0, 0($t1) #v0 = v[k]
j end_qselect
qselectp1lk: # return qselect(p+1,l,k);
addi $a0, $v0, 1 # a0 = p+1
jal qselect
lw $ra, 0($sp) #restore ra
j end_qselect
end_qselect:
lw $ra, 0($sp)
addi $sp, $sp, 4 #restore stack
jr $ra #return to caller

qselectfp1k:
#return qselect(f,p-1,k);
addi $a1, $a1, -1 # a1 = p-1   *** p is in $v0 so this is not p-1, but l-1
jal partition                  *** this is supposed to be a call to qselect
lw $ra, 0($sp) # restore ra
j end_qselect

你注意到注释说的是return qselect(f,p-1,k),但是代码调用了partition(f,l-1)吗?

通常的快速选择将有一个调用配分函数和两个递归调用-但是你有两个调用配分函数和一个递归调用。

相关内容

  • 没有找到相关文章

最新更新