【发布时间】:2017-04-26 03:52:27
【问题描述】:
我正在尝试使用链表在 MIPS 中实现合并排序算法。我基本上是在尝试翻译这段代码:http://www.geeksforgeeks.org/merge-sort-for-linked-list/ 但是,我遇到了一些问题。排序列表是不完整的,就好像它丢失了整个递归分支,例如,这是要排序的链表: 4 -> 3 -> 1 -> 2 输出为:1 -> 2 -> 4。然后当我尝试将列表写入文件时出现错误(0x004003fc 处的运行时异常:地址超出范围 0x00000000)。我猜那是因为我希望打印 4 个数字,但列表中只有 3 个数字。
我认为我需要帮助的地方是 MergeSort 函数,因为我不完全理解它在指针方面的实际作用。这就是我认为的:
它接收一个指向链表头指针的指针作为参数。在函数内部,它创建了“head”指针,并指向 headRef 的 VALUE(在这种情况下,&head 被传递给 main,所以现在函数内部的“head”具有 main 中的 head 地址)。然后它声明了两个指针,a 和 b(在 MIPS 中这就像做 a = 0 和 b = 0?我不能“声明”寄存器)。然后它检查列表是否有 1 个或 0 个元素,如果有则返回。否则,它会使用 FrontBackSplit(head, &a, &b) 将列表分成两半,但这是一个棘手的部分……这个函数不返回任何内容。相反,它修改了指针“a”和“b”,使它们分别指向列表的前半部分和后半部分。在 MIPS 中,我认为这是两个返回值 $v0 和 $v1。然后它递归地对列表进行排序,从左边开始,但是再一次,它没有返回任何东西......它修改了指针“a”和“b”。最后,它改变指向链表头的指针的值,使其指向新的排序链表。
由于有这么多 **ptr 和 &ptr 值,我对要在堆栈中保存什么感到困惑。到目前为止,关于该功能,这就是我所坚持的:
# void mergesort(node** headRef)
# input $a0: head of the list
mergesort:
move $t0, $s3 # node* head = headRef
li $t1, 0 # node* a
li $t2, 0 # node* b
# if(head == NULL || head->next == NULL)
beqz $t0, mergesort_return
lw $t3, node_next($t0) # $t3 = head->next
beqz $t3, mergesort_return
move $a0, $t0
move $a1, $t1
move $a2, $t2
# save head and $ra
addi $sp, $sp, -8
sw $t0, 0($sp)
sw $ra, 4($sp)
jal frontbacksplit
# restore head and $ra
lw $t0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
# save output results
move $t1, $v0 # a now points to the first half + 1 (if odd) of the list (frontRef)
move $t2, $v1 # b now points to the second half of the list (backRef)
# save head, a, b and $ra
addi $sp, $sp, -16
sw $t0, 0($sp)
sw $t1, 4($sp)
sw $t2, 8($sp)
sw $ra, 12($sp)
# mergesort(a)
move $a0, $t1
jal mergesort
# restore registers and $ra
lw $t0, 0($sp)
lw $t1, 4($sp)
lw $t2, 8($sp)
lw $ra, 12($sp)
addi $sp, $sp, 16
# save head, a, b and $ra
addi $sp, $sp, -16
sw $t0, 0($sp)
sw $t1, 4($sp)
sw $t2, 8($sp)
sw $ra, 12($sp)
# mergesort(b)
move $a0, $t2
jal mergesort
# restore registers and $ra
lw $t0, 0($sp)
lw $t1, 4($sp)
lw $t2, 8($sp)
lw $ra, 12($sp)
addi $sp, $sp, 16
move $a0, $t1
move $a1, $t2
# save head, a, b and $ra
addi $sp, $sp, -16
sw $t0, 0($sp)
sw $t1, 4($sp)
sw $t2, 8($sp)
sw $ra, 12($sp)
jal sortedmerge
# restore registers and $ra
lw $t0, 0($sp)
lw $t1, 4($sp)
lw $t2, 8($sp)
lw $ra, 12($sp)
addi $sp, $sp, 16
move $s3, $v0 # s3 is the saved head of the original list declared in main
mergesort_return:
jr $ra
【问题讨论】:
标签: c pointers mips mergesort translate