Download presentation
Presentation is loading. Please wait.
Published byGriselda Atkinson Modified over 9 years ago
1
1 Data Structures - Part II CS215 Lecture #8
2
Stacks Last-In-First-Out (LIFO) Stacks are often used in programming when data will need to be used in the reverse order A stack has two operations: push (places a new item at the top of the stack) pop (retrieves the top item from the stack)
3
Stack Implementation A stack can be implemented in several ways, e.g., by an array or by a linked list. A stack pointer is a variable that identifies the beginning of the part of the array that is currently unused A stack pointer variable, therefore, holds an address.
4
Declaring a Stack stack:.word 0:maxstacksize sp:.word stack or stack:.word 0:maxstacksize sp:.word... la sp, stack sp uses the address bound to the label stack as the initial value (static initialization) dynamic initialization
5
Some variations to the implementation In some implementations, a stack pointer points to the top of the stack In our sample implementation, the stack pointer points to the next available space we can push an element into A stack can be grown upward or downward, i.e., we can either add a value to the stack pointer or subtract a value from it when pushing an element
6
Pushing an element unto the stack This operation is called push. moveM[sp],x addsp,sp,4
7
Example 16.1 sp initially sp move M[sp],20 add sp,sp,4 20
8
Example 16.2 205move M[sp],5 add sp,sp,4 sp move M[sp],10 add sp,sp,4 20510
9
Taking an item off the stack This operation is called pop. addsp,sp,-4 move x,M[sp]
10
Example 16.3 sp initially 20510 sp add sp,sp,-4 move x,M[sp] 20510 Note: popping the stack means moving back the pointer to the next available space. There is no need to explicitly delete the data. It will get overwritten in the next push.
11
Full and Empty Stack SAL does not provide any form of boundary check, i.e., there is no automatic feature that detects whether an element is “pushed” beyond the stack’s capacity A robust program must check before a push whether the stack is full. It should also check whether the stack is empty before a pop.
12
Example 16.4 P.187 textbook.data stack:.byte 0:50 sp:.word stack #static initialization bottom:.word stack bias:.word 48 top:.word number:.word digit:.word push_error:.asciiz “Full stack failure “ pop_error:.asciiz “Empty stack failure “
13
Example 16.4 P.187 textbook addtop,bottom,50 loop_top: remdigit,number,10 adddigit,digit,bias bgesp,top,bad_push #check if full movem[sp],digit addsp,sp,1 divnumber,number,10 bgtznumber,loop_top bad_push:puts push_error done
14
Example 16.5 P.187 textbook print_it:bltsp,bottom,bad_pop #empty check addsp,sp,-1 putcm[sp] bgtsp,bottom,print_it done bad_pop:puts pop_error done
15
Queues A queue is a data structure that maintains a “first-in first-out” (FIFO) ordering. In contrast, a stack maintains a “last-in first-out” (LIFO) ordering. A queue adds new elements at the end. An element can only be removed at the front. This is an abstraction of the “first- come first-served” practice.
16
Queue operations A queue has two operations: enqueue dequeue An enqueue operation adds new elements at the end of the queue or its tail. This is similar to the stack operation push; only that push now is done at the end of the array instead of at the front (or top). A dequeue operation removes an element from the front of the array or its head.
17
Implementation A queue can be implemented using an array. A naïve implementation will allow the enqueued data to “walk” through the array. tailhead
18
A circular queue An array can be reused by allowing the enqueued data to “walk around” the array. This type of implementation is called a circular queue. tail head
19
The particular implementation that will be illustrated here uses an empty element. This will simplify the check for a full or empty queue. If the queue is empty, the dequeue operation must not return an invalid element. If the queue is full, the enqueue operation must not destroy an element already in the queue.
20
Adding elements (Enqueue) To add one element, we simply add 1 to the the current value of the tail, then execute: add address,base,tail move m[address],new_element #copy element into array 01 012 tail head B B = blank cell
21
Removing Elements (Dequeue) To delete one element, add 1 to the current value of head then we execute add address,base,head move element,m[address] #copy it to element tail head 012 B 012 B
22
Detecting an Empty Queue During a dequeue, the first thing that is done is to check whether ( head == tail ). If this is true, then the queue is empty. tail head 012 B 012 B not empty empty
23
Detecting a Full Queue Before an enqueue is done, the tail is incremented by 1. If after the increment (head == tail) then the queue is full. 012 B 012 B tail head before increment after increment full queue detected
24
Making the address circular Suppose we have the array To make the address 4 equal to the address 0 we simply use modulo arithmetic, i.e., 4 modulo 4 = 0. 0123 4
25
Using modulo arithmetic maps any address to an address within the allocated space, thus preventing access to out-of-the-range addresses Also, the modulo conveniently gives us the offset from the base address. We need the offset from the base address to access specific elements in the queue.
26
Example 17.1.data queue:.byte 0:4 queueaddr:.word head:.word tail:.word linenumber:.byte nextline:.byte addr:.word newline:.byte string1:.asciiz "Which line is ringing ?" string2:.asciiz "The next line to be answered is " string3:.asciiz "Enqueueing line " empty:.asciiz "No calls waiting " full:.asciiz "ERROR: Queue is full. Exiting program. "
27
Example 17.2.text __start: la queueaddr,queue loop: puts string1 get linenumber beq linenumber,'\n',dequeue get newline #reads the second character enqueue: add tail,tail,1 rem tail,tail,4 #uses modulo beq tail,head,full_queue puts string3 put linenumber put '\n' add addr,queueaddr,tail move m[addr],linenumber b loop
28
Example 17.3 dequeue: beq head,tail,empty_queue add head,head,1 rem head,head,4 #uses modulo add addr,queueaddr,head move nextline,m[addr] puts string2 put nextline put '\n' b loop empty_queue: puts empty put '\n' b loop full_queue: puts full done
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.