/* Linked lists and queues * 15-122 Principles of Imperative Computation, Fall 2010 * Frank Pfenning */ /* Linked lists */ /* Building blocks for several elementary data structures */ struct list { string data; struct list* next; }; typedef struct list* list; bool is_segment(list start, list end) { list p = start; while (p != end) { if (p == NULL) return false; p = p->next; } return true; } /* Interface to queues */ typedef struct queue* queue; bool is_empty(queue Q); /* O(1) */ queue q_new(); /* O(1) */ void enq(queue Q, string s); /* O(1) */ string deq(queue Q); /* O(1) */ // string ith(queue Q, int i); /* O(n) */ /* Implementation of queues */ struct queue { list front; list back; }; bool is_queue(queue Q) { return Q->front != NULL && Q->back != NULL && is_segment(Q->front, Q->back); } bool is_empty(queue Q) //@requires is_queue(Q); { return Q->front == Q->back; } queue q_new() //@ensures is_queue(\result); //@ensures is_empty(\result); { queue Q = alloc(struct queue); list l = alloc(struct list); Q->front = l; Q->back = l; return Q; } void enq(queue Q, string s) //@requires is_queue(Q); //@ensures is_queue(Q); //@ensures string_equal(\old(Q->back)->data, s); /* internal */ { list l = alloc(struct list); Q->back->data = s; Q->back->next = l; Q->back = l; } string deq(queue Q) //@requires is_queue(Q); //@requires !is_empty(Q); //@ensures is_queue(Q); //@ensures string_equal(\old(Q->front->data), \result); /* internal */ { assert(!is_empty(Q), "cannot deq from empty queue"); { string s = Q->front->data; Q->front = Q->front->next; return s; } } // Thorough test suite // int main() {return 0;}