Tom Kelliher, CS23
Mar. 31, 1997
ADT stack: a fundamental data structure.
Consider evaluating postfix expressions:
23 17 + 18 + 2 5 + 4 2 + * 1 7 4 * + 5 +
An algorithm:
CreateStack() while not end of line token = next token from input stream if token is a number Push(token, success); else if token is an operator GetStackTop(operand1, success) Pop(operand1, success) GetStackTop(operand2, success) Pop(operand2, success) result = the value of the operator in token applied to operand1 and operand2 Push(result, success) else // invalid token terminate end_if end_while GetStackTop(answer, success) print answer DestroyStack()
Where should errors be checked?
stack.h:
#ifndef __STACK_H #define __STACK_H #include <stdlib.h> struct stackItem { stackItem* next; int value; }; typedef stackItem* stackPtr; class Stack { private: stackPtr s; public: Stack() : s(NULL) {} ~Stack(); Stack(const Stack& oldStack); // copy constructor int StackIsEmpty(void); void Push(int newItem, int& success); void Pop(int& success); void GetStackTop(int& stackTop, int& success); }; #endif
stack.cc:
#include "stack.h" #include <stdlib.h> #include <assert.h> Stack::~Stack() { stackPtr tmp; while (s != NULL) { tmp = s; s = s->next; delete tmp; tmp = NULL; } } Stack::Stack(const Stack& oldStack) { stackPtr oldPtr = oldStack.s; stackPtr ptr; if (oldStack.s == NULL) { s = NULL; return; } else { s = new stackItem; assert (s != NULL); ptr = s; ptr->next = NULL; ptr->value = oldPtr->value; oldPtr = oldPtr->next; } while (oldPtr != NULL) { ptr->next = new stackItem; assert (ptr->next != NULL); ptr = ptr->next; ptr->next = NULL; ptr->value = oldPtr->value; oldPtr = oldPtr->next; } } int Stack::StackIsEmpty(void) { return s == NULL; } void Stack::Push(int newItem, int& success) { stackPtr tmp; tmp = new stackItem; if (!(success = tmp != NULL)) return; tmp->value = newItem; tmp->next = s; s = tmp; } void Stack::Pop(int& success) { stackPtr tmp; if (s == NULL) success = 0; else { success = 1; tmp = s; s = s->next; delete tmp; } } void Stack::GetStackTop(int& stackTop, int& success) { if (s == NULL) success = 0; else { success = 1; stackTop = s->value; } }
Example usage:
#include "stack.h" #include <iostream.h> int main() { Stack s; int tmp, success; s.Push(2, success); // build s s.Push(5, success); Stack t = s; // call copy constructor to make a copy // different from regular assignment cout << "s:\n"; s.GetStackTop(tmp, success); cout << tmp << endl; s.Pop(success); s.GetStackTop(tmp, success); cout << tmp << endl; s.Pop(success); cout << s.StackIsEmpty() << endl; cout << "t:\n"; t.GetStackTop(tmp, success); cout << tmp << endl; t.Pop(success); t.GetStackTop(tmp, success); cout << tmp << endl; t.Pop(success); cout << t.StackIsEmpty() << endl; return 0; }
Problem: Finding a set of airline flights to travel from one city to another, if one exists.
Consider a flight map:
How is it represented?
City file (graph vertices):
Phil Hb SC Pitt Balt DC
Flight file (graph edges):
Phil SC Phil Hb Phil Balt SC Pitt Hb SC Pitt Hb Balt DC DC Pitt
Request file:
Phil DC DC Phil
Implemented as various classes.
read city file, construct names array, visited array, empty adjacency lists; read flight file, filling adjacency lists to construct flight map; open request file; while there is a request { check its validity; mark departure point visited and push onto stack; while the stack is not empty and the destination is not on top of stack { if there are no unvisited cities on the adjacency list for the top of stack city pop it from the stack; else mark that city as visited and push onto stack; } if the stack is empty no flight path exists else print the flight path
What does recursion use?
What data structure is used for activation records?