2011-11-25 1 views
2

나는 MIPS에 숙제를하고 있는데, 배정은 배정 밀도 부동 소수점 수를 받아들이고 공간을 동적으로 할당하는 MIPS의 이진 트리를 만드는 것이다. 누구든지 사용할 수있는 MIPS의 이진 트리 예제가 있습니까?어떻게 이진 트리를 만들 수 있습니까?

+0

MIPS를에 ... 어셈블리 언어로 다음과 같이

내 솔루션입니까? –

+0

네, 이와 같이 http://vhouten.home.xs4all.nl/mipsel/r3000-isa.html –

+1

동적 할당자를 작성하지 않을 것으로 가정하면 작업 환경을 완전히 지정하지 않은 것입니다. – dmckee

답변

3

MIPS에서 배열을 만드는 방법을 알고 있다면 배열에 이진 트리를 투사 할 수 있습니다. 그것은 거대한 공간 낭비가 될 것이지만 반쯤 간단하게 작동 할 것입니다.

먼저 스택의 메모리에 노드를 구성하는 방법을 결정하십시오. 그것을 구성 것이다 :

[data to store] #presumably floating point numbers 
[address of left node] 
[address of right node] 

아마 0x7ff ... F

널 주소 지정 노드에 대한 널 (null) 값을 지정 아마 0

크기의 배열 생성 (2^n - 1) * NodeSize
여기서 n은 0이 아닌 1에서부터 세는 트리의 가장 깊은 지점의 깊이입니다. NodeSize는 노드를 설명하는 데 필요한 단어의 수입니다.

배열 색인은 아래에 설명 된 패턴과 일치합니다.

 0 
/ \ 
    1  2 
/\ /\ 
3 4 5 6 

다소 어려울 수 있지만 작동해야합니다. 기술적으로 당신이 트리를 잘 관리한다면 배열에 null 값의 인덱스가 필요하지 않거나 설명 된 형식으로 유지하면 실제로 다른 노드의 주소를 저장할 필요가 없습니다. 색인에 의해 암시됩니다. 그래서 정말로 당신은 단지 하나 또는 다른 것을 필요로합니다. 얼마나 많이 주소를 가지고 일하기를 원하는지 그리고 나무가 얼마나 충만 해지는지를 알아 내면 어느 것이 더 쉬울 지 선택해야합니다. 나무가 가득차면 공간을 절약하여 암시 된 가장자리가 도움이됩니다.

tl; dr 이렇게하면 트리를 두 가지 방법으로 설명하여 공간을 낭비합니다. 배열 아이디어 또는 주소를 제거하십시오.

1

나는 비슷한 프로젝트를 가지고 있었다.

################################################## 
# 
# Binary Search Tree - Project 1 
# 
# First Assembly Program :) 
# 
################################################## 
.data 
nl: .asciiz "\n" 
prompt1: "\nPlease select an option from the list below:\n" 
prompt2: "[A] - Add a record to the tree\n" 
prompt3: "[F] - Find a record in the tree\n" 
prompt4: "[P] - Perform a preorder traversal\n" 
prompt5: "[I] - Perform an inorder traversal\n" 
prompt6: "[Q] - Quit the program\n" 
prompt7: "\nChoose a character: " 
empty: "\nThe Tree is Empty." 
youentered: "\nYou Entered: " 
recordfound: "\nRecord Found: " 
recordnotfound: "\nRecord Not Found! " 
goodbye: "\nGoodbye!" 
addid: "\nEnter the ID to add: " 
addyear: "Enter the year: " 
addtitle: "Enter the title: " 
adddescription: "Enter the description: " 
id: "\nID: " 
year: "\nYear: " 
title: "\nTitle: " 
description: "Description: " 
#idsize: .word 0 
#optiona: 97 addrecord a 
#optionf: 102 findrecord f 
#optionp: 112 preorder p 
#optioni: 105 inorder  i 
#optionq: 113 quit  q 
################################################################### 
# 
# Note: I reuse a lot of print statements 
# This code is far from what I would call optimized 
# 
# This is my first assembly program and I'm really just 
# Happy to see it all working :) 
# 
# I spent about 18 hours writing this so lol :) 
# 
# The only thing that I've gotten to crash it so far is 
# Entering characters when it's waiting for an int :) 
# 
###################################################### 
# 
# Here is my memory setup: 
# 
# $s5 - Stores Root Node 
# $s7 - Stores Size of Tree (Not Really Necessary) 
# 
# Each New Item Contains a chunk of 344 bytes 
# The bytes are setup as such: 
# 
# 8 Bytes - [ID] 
# 8 Bytes - [Year] 
# 64 Bytes - [Title] 
# 256 Bytes - [Description] 
# 8 Bytes - [LeftNodeAddress] 
# 8 Bytes - [RightNodeAddress] 
# 
# 
# Example Tree: 
# 
#      10  -Root 
#     / \ 
#      7  15  -Branch 
#     /\ /\ 
#     6 9 12 17 -Leaf 
# 
# In Memory: 
# 
#  [Offset: 328] - [ID] - [Offset: 336] 
#    |      | 
# [Off: 328][ID][Off:336] [Off: 328][ID][Off: 336] . . . 
# 
# 
######################################################## 
.text 
################### 
##Prompt Function## 
################### 
prompt: 
li $v0, 4 
la $a0, prompt1   #Please select an option from the list below: 
syscall 

li $v0, 4 
la $a0, prompt2   #[A] - Add a record to the tree 
syscall 

li $v0, 4 
la $a0, prompt3   #[F] - Find a record in the tree 
syscall 

li $v0, 4 
la $a0, prompt4   #[P] - Preorder traversal 
syscall 

li $v0, 4 
la $a0, prompt5   #[I] - Inorder traversal 
syscall 

li $v0, 4 
la $a0, prompt6   #[Q] - Quit the program 
syscall 
################### 
##Get User Input ## 
################### 
getinput: 
li $v0, 4   #Choose a character: 
la $a0, prompt7 
syscall 

li $v0, 12   #Read a single character from console 
syscall 

move $s0, $v0 

beq $s0, 97, addrecord  #If you press 'a', addrecord 
beq $s0, 102, findrecord #If you press 'f', findrecord 
beq $s0, 112, preorder  #If you press 'p', preorder 
beq $s0, 105, inorder  #If you press 'i', inorder 
beq $s0, 113, exit  #If you press 'q', exit 

li $v0, 4   #If you press something random 
la $a0, nl   #Display new line 
syscall 

j getinput   #And ask for a new character 
################### 
## Add A Record ## 
################### 
addrecord: 
li $v0, 9   #allocate memory for new record 
li $a0, 344   #enough memory for 2 addresses and all the data 
syscall 


move $s0, $v0   #hang onto the initial address of all our info 

li $v0, 4   #prompt for ID 
la $a0, addid 
syscall 

li $v0, 5   #enter integer 
syscall 

sw $v0, 0($s0)   #store our ID into memory Offset: 0 

li $v0, 4   #prompt for add year 
la $a0, addyear 
syscall 

li $v0, 5   #enter integer 
syscall 

sw $v0, 4($s0)   #store year into our memory Offset: 4 

li $v0, 4   #prompt for add title 
la $a0, addtitle 
syscall 

li $v0, 8   #read our title into the allocated space 
la $a0, 8($s0)   #Offset: 8 
li $a1, 64 
syscall 

li $v0, 4   #prompt for add description 
la $a0, adddescription 
syscall 

li $v0, 8   #read our description into the allocated space 
la $a0, 72($s0)   #Offset: 72 
li $a1, 256 
syscall 

bne $s7, 0, setlocations #if this isn't root node let's set the locations 

add $s7, $s7, 1   #add 1 to the size of the records 

move $s5, $s0   #store this address as root node for now 

j prompt 
######################## 
##Set Memory Locations## 
######################## 
setlocations: 
move $s6, $s5   #Keep $s5 as our root and use $s6 as temporary storage 
move $s4, $s6   #Use $s4 to find the null node slot 
storelocations: 
beqz $s4, store   #If we've reached a leaf, store 
lw $t2, 0($s4)   #get ID from current node 
lw $t1, 0($s0)   #get Current ID from new node node we're adding 
ble $t1,$t2,goleft  #get left location if new node <= current node 
move $s6, $s4 
lw $s4, 336($s4)  #get node to the right if new node > current node 
li $t3, 336   #be ready to store to the right slot 
j storelocations 
goleft: 
move $s6, $s4 
lw $s4, 328($s4)  #load the node to the left 
li $t3, 328   #be ready to store to the left slot 
j storelocations 
store: 
beq $t3, 336, storeright #if $t3 was set to storeRight, then store to the right 
sw $s0, 328($s6)  #else store the new node's location into our node's left slot 
add $s7, $s7, 1   #remind our size register that it's growing 
j prompt   #back to the prompt 
storeright: 
sw $s0, 336($s6)  #store new node to the right slot 
j prompt   #back to the prompt 
######################## 
## Find Record by ID ## 
######################## 
findrecord: 
move $s6, $s5 
bne $s7, 0, search 
li $v0, 4   #if tree is empty 
la $a0, empty   #display message Tree is empty 
syscall 
j prompt   #and go wait for input 
search: 
move $s6, $s5 
li $v0, 4   #print ID: 
la $a0, id 
syscall 

li $v0, 5   #let user enter ID 
syscall 

move $t1, $v0   #store the id we're looking for in $t1 
checkagain: 
lw $t2, ($s6)   #store the id we're currently looking at 
bne $t1, $t2, checkempty #if this isn't the right ID, is it the last one? 
########################### 
##If we find the record: 
########################### 
li $v0, 4 
la $a0, recordfound  #Record Found: 
syscall 

li $v0, 4   #Print ID: 
la $a0, id 
syscall 

li $v0, 1   #Print the ID stored at $s6  [Offset: 0] 
lw $a0, 0($s6) 
syscall 

li $v0, 4   #Print Year: 
la $a0, year 
syscall 

li $v0, 1   #Print the Year stored at $s6 [Offset: 4] 
lw $a0, 4($s6) 
syscall 

li $v0, 4   #Print Title: 
la $a0, title 
syscall 

li $v0, 4   #Print the Title stored at $s6 [Offset: 8] 
la $a0, 8($s6) 
syscall 

li $v0, 4   #Print Description: 
la $a0, description 
syscall 

li $v0, 4   #Print descript stored at $s6 [Offset: 72] 
la $a0, 72($s6) 
syscall 

j getinput 

checkempty: 
ble $t1, $t2, checkleft  #If $t1 <= $t2 check the left node 
lw $s6, 336($s6)  #Otherwise check the right node 
bne $s6, 0, checkagain  #If this record isn't empty, check again 
li $v0, 4   #Otherwise 
la $a0, recordnotfound  #Record not found 
syscall 
j getinput 
checkleft: 
lw $s6, 328($s6)  #Check the left node 
bne $s6, 0, checkagain  #If the record isn't empty, check again 
li $v0, 4   #Otherwise 
la $a0, recordnotfound  #Record not found 
syscall 
j getinput 
treeempty: 
li $v0, 4   #if tree is empty 
la $a0, empty   #display message Tree is empty 
syscall 
j prompt 
##################################### 
# 
# The Inorder Function 
# 
##################################### 
inorder: 
beq $s7, 0, treeempty  #If the tree is empty display empty message 
move $s6, $s5   #$s6 is the record we're currently at 
move $t0, $s6   #t0 will iterate $s6 is our starting node 
move $t1, $t0   #t1 will be thrown on the stack to keep track of everything 
jal printinorder 
j prompt 
printinorder: 
addi $sp, $sp, -12  #allocate 8 bytes for the stack 
sw $ra, 0($sp)   #4 for the $ra variable 
sw $t1, 4($sp)   #4 for $t1 

bne $t0, 0, dontreturn  #if $t0 isn't null don't return 
lw $ra, 0($sp)   #otherwise: 
lw $t1, 4($sp)   #pop stack 
addi $sp, $sp, 12  #and prepare 
jr $ra    #to return 
dontreturn: 
move $t1, $t0   #put $t0 in $t1 
lw $t0, 328($t0)  #load the next pointer to the left 
jal printinorder  #and recurse back to printorder 
move $s6, $t1   #if we're back here, it's time to print 
j goprint   #so go print 
afterprint: 
move $t0, $t1   #after we print, move $t1 back to $t0 
lw $t0, 336($t0)  #get the next pointer to the right 
jal printinorder  #recurse to see if it's the last one 
move $s6, $t1   #if we made it here, it is, let's print 
beq $s6, $t1, done  #if we already printed this one, we're done (Root Node) 
j goprint   #Go print the node to the right 
done: 
lw $ra, 0($sp)   #if we're done, pop our stack 
lw $t1, 4($sp)   #clean it up 
addi $sp, $sp, 12  #8 bytes worth 
jr $ra    #and return 
goprint: 
li $v0, 4   #Print ID: 
la $a0, id 
syscall 

li $v0, 1   #Print the ID stored at $s6  [Offset: 0] 
lw $a0, 0($s6) 
syscall 

li $v0, 4   #Print Year: 
la $a0, year 
syscall 

li $v0, 1   #Print the Year stored at $s6 [Offset: 4] 
lw $a0, 4($s6) 
syscall 

li $v0, 4   #Print Title: 
la $a0, title 
syscall 

li $v0, 4   #Print the Title stored at $s6 [Offset: 8] 
la $a0, 8($s6) 
syscall 

li $v0, 4   #Print Description: 
la $a0, description 
syscall 

li $v0, 4   #Print descript stored at $s6 [Offset: 72] 
la $a0, 72($s6) 
syscall 

j afterprint 

##################################### 
# 
# The Preorder Function 
# 
##################################### 
preorder: 
beq $s7, 0, treeempty  #If the tree is empty display empty message 
move $s6, $s5   #$s6 is the record we're currently at 
move $t0, $s6   #t0 will iterate $s6 is our starting node 
move $t1, $t0   #t1 will be thrown on the stack to keep track of everything 
jal printpreorder 
j prompt 
printpreorder: 
addi $sp, $sp, -12  #allocate 8 bytes for the stack 
sw $ra, 0($sp)   #4 for the $ra variable 
sw $t1, 4($sp)   #4 for $t1 
bne $t0, 0, dontreturnpo #if $t0 isn't null don't return 
lw $ra, 0($sp)   #otherwise: 
lw $t1, 4($sp)   #pop stack 
addi $sp, $sp, 12  #and prepare 
jr $ra    #to return 
dontreturnpo: 
move $s6, $t0   #if we made it here, it is, let's print 
j goprintpo   #so go print 
afterprintpo: 
move $t1, $t0   #put $t0 in $t1 
lw $t0, 328($t0)  #load the next pointer to the left 
jal printpreorder  #and recurse back to printorder 
move $t0, $t1   #after we print, move $t1 back to $t0 
lw $t0, 336($t0)  #get the next pointer to the right 
jal printpreorder  #recurse to see if it's the last one 
donepo: 
lw $ra, 0($sp)   #if we're done, pop our stack 
lw $t1, 4($sp)   #clean it up 
addi $sp, $sp, 12  #8 bytes worth 
jr $ra    #and return 
goprintpo: 
li $v0, 4   #Print ID: 
la $a0, id 
syscall 

li $v0, 1   #Print the ID stored at $s6  [Offset: 0] 
lw $a0, 0($s6) 
syscall 

li $v0, 4   #Print Year: 
la $a0, year 
syscall 

li $v0, 1   #Print the Year stored at $s6 [Offset: 4] 
lw $a0, 4($s6) 
syscall 

li $v0, 4   #Print Title: 
la $a0, title 
syscall 

li $v0, 4   #Print the Title stored at $s6 [Offset: 8] 
la $a0, 8($s6) 
syscall 

li $v0, 4   #Print Description: 
la $a0, description 
syscall 

li $v0, 4   #Print descript stored at $s6 [Offset: 72] 
la $a0, 72($s6) 
syscall 

j afterprintpo 

exit: 
li $v0, 4   #Say 
la $a0, goodbye   #Goodbye! 
syscall 

li $v0, 10   #Terminate Program 
syscall