MIPS에서 연결된 목록을 사용하여 병합 정렬 알고리즘을 구현하려고합니다. 기본적으로이 코드를 번역하려고합니다 : http://www.geeksforgeeks.org/merge-sort-for-linked-list/ 그러나 몇 가지 문제가 있습니다. 정렬 된 목록은 마치 전체 재귀 분기를 잃어 버린 것처럼 불완전합니다 (예 : 정렬 할 링크 목록). 4 -> 3 -> 1 -> 2 출력은 다음과 같습니다. 1 -> 2 -> 4 . 그리고 파일 (런타임 예외 0x004003fc : 범위 밖으로 0x00000000)에 목록을 쓰려고하면 오류가 발생합니다. 4 개의 숫자를 인쇄 할 것으로 예상하기 때문에 그럴 것 같지만 목록에는 3 개의 숫자 만 있습니다.병합 정렬을 C에서 MIPS까지 연결된 목록으로 변환
내가 포인터가 실제로 무엇을하는지 완벽하게 이해하지 못해서 도움이 필요한 부분이 MergeSort 함수에 있다고 생각합니다. 이것은 내가 생각하는 것입니다 :
그것은 매개 변수로 목록의 머리 부분에 대한 포인터를받습니다. 함수 내에서 "head"포인터를 만들고 headRef의 VALUE를 가리 킵니다 (이 경우 & 머리가 main에 전달되었으므로 이제 함수의 "head"는 머리에 머리의 주소를가집니다). 그런 다음 두 포인터를 선언합니다. a와 b (MIPS에서 이것은 = 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
해결책을 직접 찾은 것을 축하드립니다. 유사한 문제가있을 수있는 다른 사용자를위한 교육 목적으로 여기에서 답변을 편집하여 원래 질문에서 수정 한 내용을 자세히 설명하는 것이 좋습니다. 또한, 당신이 겪었던 [그리고 고정 된] 다른 문제들뿐만 아니라 당신이 배웠거나 개선 한 것. –
나는 더 많은 시간을 갖자 마자 그것을 할 것이다. D. 아마 다음주. – Sebasuraa