1 / 34

Chapter 12 Simple Data Structures

Chapter 12 Simple Data Structures. 1 2 .1 Introduction. A computer is a machine that manipulates data. The study of computer science includes the study of how data is organized in a computer, how it can be manipulated, and how it can be utilized.

barny
Download Presentation

Chapter 12 Simple Data Structures

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. Chapter 12Simple Data Structures

  2. 12.1 Introduction • A computer is a machine that manipulates data. • The study of computer science includes the study of how data is organized in a computer, how it can be manipulated, and how it can be utilized. • In computer science, the real world abstractions are represented in terms of data types. • The basic data types of C include char, int, float, double, etc. • In addition, C helps us by providing two mechanisms for grouping data together • Array – collections of elements of the same data type • Structure – collections of elements whose data types need not be the same

  3. Whether your program is dealing with predefined data types or user-defined data types, these two aspects must be considered: Objects and Operations • For example, • The data type int is related to • Objects : {0, +1, -1, +2, -2, … , INT_MAX, INT_MIN} • Operations: +, -, *, /, %, <, >, ==, = (assignment), etc. • The data type structstudent may be related to • Objects: all instances of struct student { char name[20]; int ID; int grade; } • Operations:getName(), getID(), getGrad(), printStdInfo(), etc.

  4. 12.2 Abstract Data Type (ADT) • Abstract Data Type • An ADT is a collection of • data objects that share a defined set of properties and • operations for processing the objects. • An ADT is a data type that is organized in such a way that the specification of the objects and the operations on the objects is separated from the implementation of the operations. • Some programming language provide explicit mechanism to support the distinction between specification and implementation. • Ada : a package • C++ : a class • C does not have an explicit mechanism for implementing ADTs, but it is still possible and desirable to design your data types using the same notion.

  5. Why Abstract Data Types? • User of the ADT “sees” only the interface to the objects; the implementation details are “hidden” in the definition of the ADT • It has been observed by many software designers that hiding the representation of objects of a data type from its users is a good design strategy. • In that case, the user is constrained to manipulate the object solely through the functions (operations) that are provided. • The designer may still alter the representation as long as the new implementations of the operations do not change the user interface. This means that users will not have to recode their algorithms.

  6. 12.3 Examples of ADTs • String ADT • definition of string object (alphabet, sequence) • definition of string operations • Boolean StringCopy(srcString, dstString) • Boolean StringConcat(srcString, dstString) • Boolean StringCompare(SrcString, dstString) • Void StringPrint(String); • possible implementations • array implementation • linked list implementation • circular doubly-linked list implementation

  7. 12.4 The Stack ADT • Objects • a finite sequence of elements of the same type with additions restricted to one end of the sequence called the top of the stack and deletions also restricted to the same end • Operations • initialize • push • pop • empty • full

  8. Characteristics of Stack • a finite sequence of values (of a particular data type) with the recency of addition to the stack being directly related to the distance from the top of the stack; so, items more recently added to a stack are deleted earlier • Last In First Out (LIFO) • analogy to a stack of plates in a cafeteria

  9. Stack Operations • Initialize (Stack) : put Stack into its initial state • Precondition: • Stack is in an unknown state • Postcondition: • Stack is empty

  10. Push Operation • Push (Item, Stack): Item is placed on the top of Stack • Preconditions: • Stack is in a reliable state • Item has a value • Postcondition • If Stack is full, Stack is unchanged; • Otherwise, Stack is the previous Stack with the value of Item added to the top

  11. Pop Operation • Pop (Item, Stack): the value of Item is changed to the value of the element appearing at the top of Stack and the topmost element of Stack is removed • Preconditions • Stack is in a reliable state • Postcondition • If Stack is empty, Stack is unchanged, Item's value is unreliable; • Otherwise, Item's new value is the value at the top of Stack, and Stack is the previous Stack with the top element removed

  12. Stack Test Operations • Empty (Stack): tests whether Stack has any element • Preconditions • Stack is in a reliable state • Postconditions • TRUE is returned if Stack is empty; • Otherwise, FALSE is returned • Full (Stack): tests whether an item can be added to Stack • Preconditions • Stack is in a reliable state • Postconditions • TRUE is returned if Stack is full; • Otherwise, FALSE is returned

  13. Implementation of Stacks in C • Recall from the definition of the ADT that stack is a sequence of elements • All the operations performed on the stack are done at one end of the structure (nothing can be added to or deleted from the middle) • We need to be able to test whether the structure is empty or full. • Stack can be implemented easily using C array • The top of the stack needs to be encapsulated.

  14. Stack Declarations #define MAX_STACK_SIZE 100 typedef struct{ int key; /* other fields can go here */ }element; element stack[ MAX_STACK_SIZE ]; int top; • top: index of top element in the stack • stack[]: the array implementing a sequence • bottom of stack: first element of the array • stack[0]; • top of stack : last element currently being held in the array • stack[top]; • empty stack : top = -1; • full stack : top = MAX_STACK_SIZE - 1;

  15. Source for Stack Operations void initialize( int* top ) { top = -1; } void push( int* top, element stack[], element item ) { if ( !stackfull(*top ) ) stack[ ++(*top) ] = item; }

  16. element pop( int* top, element stack[] ) { if ( !stackempty( *top ) ) return stack[ (*top)-- ]; return 0; } int stackfull( int top ) { return ( top == MAX_STACK_SIZE-1 ) ; } int stackempty( int top ) { return ( top == -1 ); }

  17. d c b a Stack Application Example 1 • Print a line in reverse order • Use the stack architecture to do the reversal. • By placing the characters on the stack in the order read, the first character read will be the last written. User types: a b c d Stack :

  18. This example assumes that the stack never gets full. element stack[MAX_STACK_SIZE]; int top; element item; initialize( &top ); printf ("push numbers ( 0 to end )\n"); scanf ( "%d" , &item.key ) ; while ( item.key != 0 ) { push( &top, stack, item ); scanf( "%d", &item.key ); } while ( !stackempty( top ) ){ item = pop( &top, stack ); printf( "%d", item.key ); }

  19. Stack Application Example 2 • Stacks in Compilers • Example : convert an expression written in infix notation into the equivalent expression written in postfix notation: A * B + (C - D) / E is converted to A B * C D - E / +

  20. Precedence rules play an important role in transforming infix to postfix. • Let us assume the existence of a function prcd(op1,op2), where op1 and op2 are characters representing operators. • This function TRUE if op1 has precedence over op2 when op1 appears to the left of op2 in an infix expression without parentheses. • prcd(‘*’, ‘+’) : TRUE • prcd(‘+’, ’+’) : TRUE • prcd(‘+’, ‘*’) : FALSE • prcd(‘(‘, op) : FALSE for any operator op • prcd(op, ‘(‘) : FALSE for any operator op other than ‘)’ • prcd(op, ‘)‘) : TRUE for any operator op other than ‘(’

  21. InfixToPostfix ( char infix[ ], char postr[ ]) { int position, und; int outpos = 0; char topsymb = ‘+’; char opStack[MAX STACK SIZE]; int top; initialize(&top); for (position=0; (symb = infix[position]) != ‘\0’; position++) if (isoperand(symb)) postr[outpos++] = symb; else { while (topsymb = pop(&top, opStack) && prcd(topsymb, symb)) { postr[outpos++] = topsymb; } if (topsymb) push(&top, opStack, topsymb); if (stackempty(top) || symb != ‘)’ ) push(&top, opStack, symb); else topsymb = pop(&top, opStack); } while (! stackempty(top) ) postr[outpos++] = pop(&top,opStack); postr[outpos] = ‘\0’; }

  22. 12.5 The Queue ADT • Objects • a finite sequence of elements of the same type with additions restricted to one end of the sequence called the back of the queue and deletions restricted to the other end called the front of the queue. • Operations • initialize • enqueue • dequeue • empty • full

  23. Characteristics of Queue • a finite sequence of values (of a certain data type) with the recency of addition to the queue being inversely related to the distance from the front of the queue; so, the earlier an item is added to a queue, the earlier it is removed • First In First Out (FIFO) • First Come First Served (FCFS) • analogy to a bank lineup or a store checkout

  24. Queue Operations • Initialize (Queue) : puts Queue into its initial state. • Preconditions • Queue is in an unknown state. • Postconditions • Queue is empty • Enqueue (Item, Queue) : Item is placed at the back of Queue. • Preconditions • Queue is in a reliable state. • Item has a value. • Postconditions • If Queue is full, Queue is unchanged; • Otherwise, Queue is the previous Queue with the value of Item added to the back.

  25. Dequeue (Item, Queue) : The element at the front of Queue is removed and becomes Item. • Preconditions • Queue is in a reliable state. • Postconditions • If Queue is empty, Queue is unchanged, Item's value is unreliable; • Otherwise, Item's new value is the value at the front of Queue, and Queue is the previous Queue with the front element removed.

  26. Empty (Queue) : tests whether Queue has any elements. • Preconditions • Queue is in a reliable state. • Postconditions • TRUE is returned if Queue is empty; • Otherwise, FALSE is returned • Full (Queue) : tests whether an element can be added to Queue. • Preconditions • Queue is in a reliable state. • Postconditions • TRUE is returned if Queue is full; • Otherwise, FALSEis returned.

  27. Implementation of Queues in C Using Circular Arrays • Declaration #define MAX_QUEUE_SIZE 100 typedef struct{ int key; /* other fields can go here */ } element; element queue[MAX_QUEUE_SIZE]; int front; int length;

  28. Declaration (cont’d) • queue[]: the element in the queue • back of queue : last queue element: • queue[front + length - 1] • front of queue : 1st queue element: • queue[front] • empty queue? • length = 0; • full queue? • length = MAX_QUEUE_SIZE;

  29. Source for Queue Operations void initialize( int* front, int* length ) { *front = *length = 0; } int queueempty( int length ) { return length == 0; } int queuefull( int length ) { return length == MAX_QUEUE_SIZE; }

  30. void enqueue( int front, int* length, element queue[], element item ) { int where; if ( !queuefull( *length ) ) { where = front + *length; queue[ where % MAX_QUEUE_SIZE ] = item; (*length)++; } } element dequeue( int* front, int* length, element queue[] ) { int where; if ( !queueempty( *length ) ){ where = *front; *front = (where+1) % MAX_QUEUE_SIZE; (*length)--; return queue[where]; } return 0; }

  31. Queue Application Example #include <stdio.h> #define MAX_QUEUE_SIZE 5 typedef struct { int key; } element; void initialize( int* front, int* length ) /* Initialize the queue */ { *front = *length = 0; } int queueempty( int length ) /* Check queue empty */ { return length == 0; } int queuefull( int length )/* Check queue full */ { return length == MAX_QUEUE_SIZE; }

  32. /* Enqueue an item into the queue */ void enqueue( int front, int* length, element queue[], element item ) { int where; if ( !queuefull( *length ) ) { where = front + *length; queue[ where % MAX_QUEUE_SIZE ] = item; (*length)++; } } /* Dequeue an item from the queue */ element dequeue( int* front, int* length, element queue[] ) { int where; if ( !queueempty( *length ) ){ where = *front; *front = (where+1) % MAX_QUEUE_SIZE; (*length)--; return queue[where]; } } /* print the content of the queue */ void printqueue ( element queue[], int front, int length ) { int i; for (i=0; i<length; i++) printf("%d ",queue[(front+i) % MAX_QUEUE_SIZE].key); printf(”\n"); }

  33. void main(void) { element queue[MAX_QUEUE_SIZE]; int front, length; element item; int i; initialize(&front, &length); item.key = 0; for (i=0; i<MAX_QUEUE_SIZE; i++) { enqueue(front, &length, queue, item); item.key++; printqueue(queue, front, length); } for (i=0; i<MAX_QUEUE_SIZE; i++) { printqueue(queue, front, length); item = dequeue(&front, &length, queue); } }

More Related