1 / 31

Today’s Agenda

Today’s Agenda. Access Restricted Lists Stacks, Queues and their applications. ADT Stack – Type Definition. /* file: stack.h */ #include “element.h” struct _stacknode; typedef struct _stacknode *StackNode; struct _stacknode { Element e; StackNode next; }; typedef struct {

malana
Download Presentation

Today’s Agenda

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Today’s Agenda Access Restricted Lists Stacks, Queues and their applications. Sundar B. BITS, Pilani.

  2. ADT Stack – Type Definition /* file: stack.h */ #include “element.h” struct _stacknode; typedef struct _stacknode *StackNode; struct _stacknode { Element e; StackNode next; }; typedef struct { StackNode top; unsigned int size; Boolean error; } Stack;

  3. ADT Stack - Implementation /* file: stackOps.c */ #include “stack.h” #include “element.h” #include “stdlib.h” Stack createStack() { Stack s; s.top = NULL; s.size = 0; s.error = FALSE; return s; } Boolean isEmpty(Stack s) { return (top==NULL) ? TRUE : FALSE; } Element top(Stack s) { return s.top->e; }

  4. s1.top = (StackNode)malloc(sizeof(struct __stacknode)); if (s1.top == NULL) { s1.error = TRUE; // “out of memory” error return s1; } s1.top->e = e ; // copy element s1.top->next = s.top; s1.size = s.size+1; ADT Stack - Implementation /* file: stackOps.c */ Stack push(Element e, Stack s) { Stack s1; return s1; // Can we change s and return it? } // Why not pass address of s instead of returning?

  5. s1.top = s.top->next ; // skip element s1.size = s.size-1; temp = s.top ; ADT Stack – Implementation /* file: stackOps.c */ Stack pop(Stack s) { Stack s1; StackNode temp; return s1; } free(temp); // if the original Stack can be destroyed

  6. Use of ADT Stack - Example • Problem: • Consider a string of parentheses: • ()()(((()))) • Is this a valid string? • Define a string of parentheses to be valid if: • Each Open ‘(‘ has a matching Close ‘)’ and the Open always appears before the Close • Valid instances: • ()()() • ((()))(()) • Invalid instances: • (() • )()( Sundar B. BITS, Pilani.

  7. Use of ADT Stack - Example • Design an algorithm to verify whether a string of parentheses is valid. • Idea • Push each Open onto a stack; Pop an Open for each Close. • The string is valid • If the stack is empty at the end • The string is invalid: • If stack is non-empty at the end (i.e when the string is empty) OR • If stack is empty before the end (i.e when the string is non-empty)

  8. Use of ADT Stack - Example • The parentheses problem does have an alternative solution. • Observation: • In a valid string count of Opens equals the count of Closes. • But )( is an invalid string with equal count of Opens and Closes. • In a valid string the count of Opens of any prefix is greater than or equal to the count of Closes. • This is is not so for invalid strings. Sundar B. BITS, Pilani.

  9. Use of ADT Stack - Example • Alternative solution: • Count the ‘Open’s and the ‘Close’s separately. • If at any time, you have more Closes than Opens, then the string is invalid. • If at the end the counts match, then the string is valid. • So, let us complicate the problem  • The string may have parentheses, square brackets, as well as braces, for instance: • {[]()((()))} Sundar B. BITS, Pilani.

  10. Use of ADT Stack - Example • New definition of validity: • Each Open(t) must have a matching Close(t) where t is one of PAREN, SQUA or BRACE. • An Open(t) must appear before the corresponding Close(t) • But these two conditions may be not be enough: • Is ([)] valid? • All ‘Opens’, inside an Open(t) and its corresponding Close(t), must be closed. Sundar B. BITS, Pilani.

  11. Use of ADT Stack - Example • Counting solution will not work for verifying (new) validity of string. • But the stack solution works - with a minor change: • Push each Open(t) onto stack • For each Close(t) pop an Open(t) – i.e. an Open of the same kind. Sundar B. BITS, Pilani.

  12. Use of ADT Stack - Example Algorithm Match(charSeq) // charSeq is a sequence of bracketing characters // Let stk be a Stack (initially empty). while (!isEmpty(charSeq)) { b = nextChar(charSeq); if (isOpen(b)) { stk = push(b, stk); } else if (isClose(b)) { if (isEmpty(stk) || (b.kind == top(stk).kind)) { return FALSE; } else {stk = pop(stk);} } } return isEmpty(stk);

  13. Use of ADT Stack - Example • Well that was fun  , but of what use is solving the problem? • This is a common problem in editors – text editors (such as vi), or program editors (such as Turbo-C or others). • Exercise: • Complete the implementation. • A type for bracket chars is needed – with two pieces of info.: kind (PAREN, SQUA, or BRACE) and end (OPEN, or CLOSE) Sundar B. BITS, Pilani.

  14. Variant of the Example • In a real editor – say vi – matching bracket characters have to be done while the user is typing. • i.e two different things can happen at the time: • The user inputs characters and • The program matches them • Usually there is a speed mismatch: • A buffer is needed in such situations. Sundar B. BITS, Pilani.

  15. Variant of the Example • The program gets the next character from the buffer – • one at a time instead of assuming the whole string is available. • The user inserts characters one at a time. • Insertion and deletion happen at different ends of the same list (that we call buffer) • This is a different kind of access-restricted list: • It is sequential. • It is First-In-First-Out (FIFO) • Addition is done at one end and deletion at the other end. Sundar B. BITS, Pilani.

  16. Access-restricted lists: Queues • These kind of lists are called queues: • They are useful in many situations where there is a speed mismatch: • A service and more than one client – arrival rate (of clients) does not match with the service rate. • E.g. Ticket Counters • A producer and consumer operating at different speeds • E.g. Input devices and programs; • Programs and output devices Sundar B. BITS, Pilani.

  17. Use of Stack & Queue - Example Algorithm Match(charSeq) // charSeq is a QUEUE of bracketing characters // Let stk be a Stack (initially empty). while (!isEmptyQ(charSeq)) { b = next(charSeq); charSeq = delete(charSeq); if (isOpen(b)) { stk = push(b, stk); } else if (isClose(b)) { if (isEmpty(stk) || (b.kind == top(stk).kind)) { return FALSE; } else {stk = pop(stk);} } } return isEmpty(stk);

  18. Use of Stack & Queue - Example • In the previous slide, the algo. Assumes the whole seq. is available in the queue (Or the input speed is higher than processing speed). • If this is not the case modify the algo: • Check for end of string (some special char.) • If queue is empty then wait; when queue becomes non-empty then restart. • This cannot be directly implemented in C – because two processes (user and editor) have to running at the same time. Sundar B. BITS, Pilani.

  19. ADT Queue • Operations: • createQ returns a new (empty) Queue • addQ adds an Element to (the rear of a) Queue • isEmptyQ checks whether a Queue is empty • frontQ returns the Element at the front of a Queue • deleteQ deletes the Element at the front of a Queue Sundar B. BITS, Pilani.

  20. ADT Queue – Interfaces /* file: queueOps.h */ #include “boolean.h” #include “element.h” #include “queue.h” /* Create an empty Queue */ /* Post-condition: return q such that isEmptyQ(q) = TRUE */ Queue createQ(); /* Post-condition: return TRUE if q is empty FALSE otherwise */ Boolean isEmptyQ(Queue q); Sundar B. BITS, Pilani.

  21. ADT Queue - Interfaces /* file: queueOps.h */ /* Add an Element to a Queue */ /* Post-condition: return q1 such that isEmptyQ(q1) is FALSE AND sizeQ(q1) = sizeQ(q) + 1 AND addQ and deleteQ satisfy FIFO property */ Queue addQ(Element e, Queue q); /* Get the front Element of a Queue */ /* Pre-condition: isEmptyQ(q) is FALSE */ Element frontQ(Queue q); Sundar B. BITS, Pilani.

  22. ADT Queue - Interfaces /* file: queueOps.h */ /* Delete an Element from the front of Queue */ /* Pre-condition: isEmptyQ(q) is FALSE Post-condition: return q1 such that sizeQ(q1) = sizeQ(q) - 1 AND addQ and deleteQ satisfy FIFO property */ Queue deleteQ(Queue q); /* Post-condition: return the size of the queue */ int sizeQ(Queue q); Sundar B. BITS, Pilani.

  23. ADT Queue - Types /* file: queue.h */ #include “qnode.h” typedef struct { QNode front; QNode rear; unsigned int size; Boolean error; } Queue; Sundar B. BITS, Pilani.

  24. ADT Queue - Implementation • Represent a Queue as a linked list. • Addition creates a new node in the rear • Deletion deletes the first node • Front returns the contents of the first node Sundar B. BITS, Pilani.

  25. ADT Queue – Node Type Definition /* file: qnode.h */ #include “element.h” struct __qnode; typedef struct __qnode *QNode; struct __qnode { Element e; QNode next; }; Sundar B. BITS, Pilani.

  26. ADT Queue - Implementation /* file: queueOps.c */ #include “boolean.h” #include “element.h” #include “queue.h” #include <stdlib.h> Queue createQ() { Queue q; q.front = q.rear = NULL; q.size = 0; q.error = FALSE; } Boolean isEmptyQ(Queue q) { return q.front == NULL; } Sundar B. BITS, Pilani.

  27. q1.rear = (QNode)malloc(sizeof(struct __qnode)); if (q1.rear == NULL) { q1.error = TRUE; return q1; } q1.rear->e = e; // copy element q1.rear->next = NULL; // Will the following work if q is empty? q.rear->next = q1.rear; q1.size = q.size+1; q1.front = q.front; ADT Queue - Implementation /* file: queueOps.c */ Queue addQ(Element e, Queue q) { Queue q1; return q1; } Sundar B. BITS, Pilani.

  28. // Will the following work if q is a singleton? q1.front = q.front->next; q1.rear = q.rear; q1.size = q.size-1; free(q.front); ADT Queue - Implementation /* file: queueOps.c */ Queue deleteQ(Queue q) { Queue q1; return q1; } Element frontQ(Queue q) { return q.front->e; } Sundar B. BITS, Pilani.

  29. ADT Queue – Alternate Implementation • Exercise: • Implement ADT (Bounded) Queue using circular array implementation. • In particular, • How is isEmpty operation implemented? Sundar B. BITS, Pilani.

  30. ADT Queue • Change in requirement (one or more of these): • Large (FIFO) list needed – not enough memory! • List must be persistent – must survive multiple runs of program • List to be exchanged between two programs • Files (in persistent storage) fit the bill • Indeed, files are sequential access lists – in particular, FIFO lists! • read is done at the front and write at the rear Sundar B. BITS, Pilani.

  31. Files • All input and output use files (in Unix) • Keyboard input is stdin • Monitor output is stdout • stdin and stdout are files declared in stdio.h • stdio.h contains a type FILE and operations for opening, closing, reading and writing. Sundar B. BITS, Pilani.

More Related