1 / 30

Turgay Korkmaz Office : NPB 3.330 Phone: (210) 458-7346 Fax: (210) 458-4437

CS 2123 Data Structures Ch 10 – Linear Structures. Turgay Korkmaz Office : NPB 3.330 Phone: (210) 458-7346 Fax: (210) 458-4437 e-mail: korkmaz@cs.utsa.edu web: www.cs.utsa.edu/~korkmaz.

jgloria
Télécharger la présentation

Turgay Korkmaz Office : NPB 3.330 Phone: (210) 458-7346 Fax: (210) 458-4437

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. CS 2123 Data Structures Ch 10 – Linear Structures Turgay Korkmaz Office: NPB 3.330 Phone: (210) 458-7346 Fax: (210) 458-4437 e-mail: korkmaz@cs.utsa.edu web: www.cs.utsa.edu/~korkmaz Thanks to Eric S. Roberts, the author of our textbook, for providing some slides/figures/programs.

  2. Objectives • To recognize that stacks can be implemented using linked lists as well as arrays. • To learn how to implement queues using both arrays and linked lists as the underlying representation. • To understand and learn about simulations (self-study)

  3. Stack Using Linked List • Revisit stack • A storage for a collection of data values (elements) • Defining behavior of stack is “Last in, First out” (LIFO) • Adding a new element to a stack is called push • Removing the most recent item from a stack is called pop • Re-implement stack.c using linked list while keeping the same stack.h interface

  4. Recall stack.h Interface • #ifndef _stack_h /* for comments see stack.h */ • #define _stack_h • //#include "genlib.h“ • // #define New(ptr_t) ((ptr_t) malloc(sizeof *((ptr_t) NULL))) • typedefintbool; • typedefdoublestackElementT; /* “double” can be replaced by other types */ • typedefstructstackCDT *stackADT; • stackADTNewStack(void); • void FreeStack(stackADT stack); • void Push(stackADT stack, stackElementT element); • stackElementT Pop(stackADT stack); • boolStackIsEmpty(stackADT stack); • boolStackIsFull(stackADT stack); • intStackDepth(stackADT stack); • stackElementT GetStackElement(stackADT stack, int index); • #endif

  5. typedef struct cell { stackElementT data; struct cell *link; } cellT; The simple strategy to re-implement stack using Linked List NewStack(){ return NULL; } Push(stack, e1); Push(stack, e2); Pop(stack); cp = malloc(sizeof(cellT)); cp->data=e2; cp->next = stack; stack=cp; cp = stack; stack=cp->next; data=cp->data; free(cp) return data;

  6. typedef struct cell { stackElementT data; struct cell *link; } cellT; Implementation of stack.cFirst provide a concrete representation stackADT • The simple strategy fails. WHY? typedefstructstackCDT *stackADT; // stack.h stackADTmyStack; myStack=NewStack(); Push(myStack, e1); • Actually we can make this work if … (recall Q12) • We pass the address of myStack (pointer to pointer **) • But this requires changes in stack.h • WHAT CAN WE DO TO KEEP stack.h AS IS? stack element myStack NULL e1 NULL

  7. typedef struct cell { stackElementT data; struct cell *link; } cellT; Implementation of stack.cFirst provide a concrete representation stackADT • stack.h will keep the standard abstract def typedefstructstackCDT *stackADT; • stack.c then defines stackCDTas structstackCDT { cellT *start; }; stackADTNewStack() { stackADT stack; stack=malloc(sizeof *stack); // if (stack==NULL) … stack->start = NULL; return(stack); } • Then when the client calls myStack=NewStack(); • Push(myStack, e1); stack stack element myStack e1 start start NULL NULL

  8. stack Reimplementingstack.c #include <stdio.h> // #include "genlib.h" #include "stack.h" typedef struct cell { stackElementT data; struct cell *link; } cellT; structstackCDT { cellT *start; // other fields can be added, e.g., int depth; }; stackADTNewStack(void) { stackADT stack; stack = malloc(sizeof *stack); // if NULL stack->start = NULL; return (stack); } start NULL

  9. stack stack stack start NULL void Push(stackADT stack, stackElementT element) { cellT *cp; cp = malloc(sizeof *cp); // if (cp==NULL)… cp->data = element; cp->link = stack->start; stack->start = cp; } stackElementT Pop(stackADT stack) { stackElementT result; cellT *cp; if (StackIsEmpty(stack)) Error("Pop of an empty stack"); cp = stack->start; stack->start = cp->link; result = cp->data; free(cp); return (result); } start start

  10. stack void FreeStack(stackADT stack) { cellT *cp, *next; cp = stack->start; while (cp != NULL) { next = cp->link; free(cp); cp = next; } free(stack); } boolStackIsEmpty(stackADT stack) { return (stack->start == NULL); } bool StackIsFull(stackADT stack) { return (FALSE); }

  11. intStackDepth(stackADT stack) { int n; cellT *cp; n = 0; for (cp = stack->start; cp != NULL; cp = cp->link) n++; return (n); } stackElementT GetStackElement(stackADT stack, int depth) { inti; cellT *cp; if (depth < 0 || depth >= StackDepth(stack)) { Error("Non-existent stack element"); } cp = stack->start; for (i = 0; i < depth; i++) cp = cp->link; return (cp->data); } structstackCDT { cellT *start; int depth; }; Set it to 0 in NewStack() Increment it in Push Decrement it in Pop Here simply return it return stack->depth;

  12. s Exercise #include <stdio.h> //#include "genlib.h" #include "stack.h" typedef struct cell { stackElementT data; struct cell *link; } cellT; structstackCDT { cellT *start; int depth; }; stackADTNewStack(void) { stackADT stack; stack = malloc(sizeof (stack); // if (stack==NULL) … stack->start = NULL; return (stack); } • Implement the following functions: stackADTReverseCopyStack(stackADT s); stackADTCopyStack(stackADT s); void RemoveAtDepth(stackADT s, int depth);

  13. s s_rev s_rev = ReverseCopyStack(s); stackADTReverseCopyStack(stackADT s) {

  14. QUEUES Very similar to stacks The only difference between them is in the order in which elements are processed. A stack uses a last-in/first-out (LIFO) discipline A queue adopts a first-in/first-out (FIFO) model that more closely resembles a waiting line.

  15. stackADT s1; s1 = malloc(sizeof *s1); vs. s1 = New(StackADT); queue.h interface • #ifndef _queue_h • #define _queue_h • //#include "genlib.h“ • #define New(ptr_t) ((ptr_t) malloc(sizeof *((ptr_t) NULL))) • typedefintbool; • typedefvoid *queueElementT; /* “void *” can be replaced by other types */ • typedefstructqueueCDT *queueADT; • queueADTNewQueue(void); • void FreeQueue(queueADT queue); • void Enqueue(queueADT queue, queueElementT element); • queueElementTDequeue(queueADT queue); • boolQueueIsEmpty(queueADT queue); • boolQueueIsFull(queueADT queue); • intQueueLength(queueADT queue); • queueElementTGetQueueElement(queueADT queue, int index); • #endif

  16. Self-study Array Implementation of Queue ADT What fields do we need in structqueueCDT?

  17. Self-study qarray.c #include <stdio.h> // #include "genlib.h" #include "queue.h" #define MaxQueueSize 9 #define QueueArraySize (MaxQueueSize + 1) /* so it is 10 */ structqueueCDT { queueElementT elements[QueueArraySize]; int head; int tail; }; queueADTNewQueue(void) { queueADT queue; queue = New(queueADT); // if NULL queue->head = queue->tail = 0; return (queue); } queue

  18. Self-study void Enqueue(queueADT queue, queueElementT element) { if (QueueIsFull(queue)) Error("Enqueue: queue is full"); queue->elements[queue->tail] = element; queue->tail = (queue->tail + 1) % QueueArraySize; } queueElementTDequeue(queueADT queue) { queueElementT result; if (QueueIsEmpty(queue)) Error("Dequeue: queue is empty"); result = queue->elements[queue->head]; queue->head = (queue->head+1)% QueueArraySize; return (result); }

  19. Self-study End of qarray.c bool QueueIsEmpty(queueADT queue) { return (queue->head == queue->tail); } bool QueueIsFull(queueADT queue) { return ((queue->tail + 1) % QueueArraySize == queue->head); } void FreeQueue(queueADT queue) { free(queue); } int QueueLength(queueADT queue) { return ((QueueArraySize + queue->tail - queue->head) % QueueArraySize); } queueElementT GetQueueElement(queueADT queue, int index) { if (index < 0 || index >= QueueLength(queue)) { Error("Queue element is out of range"); } return (queue->elements[(queue->head + index) % QueueArraySize]); }

  20. Linked List Implementation of Queue ADT What fields do we need in structqueueCDT?

  21. #ifndef _queue_h • #define _queue_h • //#include "genlib.h“ • #define New(ptr_t) ((ptr_t) malloc(sizeof *((ptr_t) NULL))) • typedefintbool; • typedefvoid *queueElementT; /* “void *” can be replaced by other types */ • typedefstructqueueCDT *queueADT; • queueADTNewQueue(void); • void FreeQueue(queueADT queue); • void Enqueue(queueADT queue, queueElementT element); • queueElementTDequeue(queueADT queue); • boolQueueIsEmpty(queueADT queue); • boolQueueIsFull(queueADT queue); • intQueueLength(queueADT queue); • queueElementTGetQueueElement(queueADT queue, int index); • #endif qlist.c #include <stdio.h> // #include "genlib.h" #include "queue.h" typedef struct cell { queueElementT value; struct cell *link; } cellT; structqueueCDT { cellT *head; cellT *tail; }; queueADTNewQueue(void) { queueADT queue; queue = New(queueADT); // if NULL queue->head = queue->tail = NULL; return (queue); }

  22. void Enqueue(queueADT queue, queueElementT element) { cellT *cp; cp = New(cellT *); // if NULL cp->value = element; cp->link = NULL; if (queue->head == NULL) { queue->head = cp; queue->tail = cp; } else { queue->tail->link = cp; queue->tail = cp; } } { cellT *cp; cp = New(cellT *); // if NULL cp->value = element; cp->link = NULL; if (queue->head == NULL) { queue->head = cp; } else { queue->tail->link = cp; } queue->tail = cp; }

  23. queueElementTDequeue(queueADT queue) { queueElementT result; cellT *cp; cp = queue->head; if (cp == NULL) { Error("Dequeue: queueisempty"); } result = cp->value; queue->head = cp->link; free(cp); return (result); } What if we have only one element? After removing it queue->head will be NULL. How about queue->tail?

  24. bool QueueIsEmpty(queueADT queue) { return (queue->head == NULL); } boolQueueIsFull(queueADT queue) { return (FALSE); } void FreeQueue(queueADT queue) { cellT *cp, *next; cp = queue->head; while (cp != NULL) { next = cp->link; free(cp); cp = next; } free(queue); } cp = queue->head; while (cp != NULL) { free(cp); cp = cp->link; }

  25. End of qlist.c structqueueCDT { cellT *head; cellT *tail; int length; }; Set it to 0 in NewQueue() Increment it in Enqueue Decrement it in Dequeue Here simply return it return queue->length; intQueueLength(queueADT queue) { int n; cellT *cp; n = 0; for (cp = queue->head; cp != NULL; cp = cp->link) n++; return (n); } queueElementTGetQueueElement(queueADT queue, int index) { inti; cellT *cp; if (index < 0 || index >= QueueLength(queue)) { Error("Queue element is out of range"); } cp = queue->head; for (i = 0; i < index; i++) cp = cp->link; return (cp->value); }

  26. Exercise: Copy a queue • Suppose we included the following function prototype into queue.h queuADTCopyQueue(queueADT queue); // which creates another copy of the queue // old queue will be intact • Implement it under linked list representation (array rep is optional)

  27. Exercise: Reverse a queue • Suppose we included the following function prototype into queue.h queuADTReverseQueue(queueADT queue); // which reverses the order of the elements // old queue will be changed… • For example if queue has A B C D, your function should make the queue D C B A • Implement it under linked list representation (array rep is optional) • What will be the complexity?

  28. Exercise: Priority queue • Suppose we included the following function prototype into queue.h void EnqueueSorted(queueADT queue, queueElementT element) // which inserts the elements in a queue in a sorted manner • For example, if queue has 4 8 10 41 and you want to insert 9 your function should insert it after 8 before 10 such that the queue will have 4 8 9 10 41 • Implement it under linked list representation (array rep is optional) • What will be the complexity?

  29. Exercise: merge two sorted queue/list • Write a function that will merge the elements in two sorted queue in a sorted manner under linked list representation • For example, if queue1 has 4 8 10 41 and queue2 has 5 9 45, your function should merge them as queue3 which will have 4 5 8 9 10 41 45 • What will be the complexity?

  30. OPT Application of Queues: Discrete Time Simulations Skip -- Self-Study Section 10.3 form the textbook

More Related