34
1 Chapter 12 Simple Data Structures

Chapter 12 Simple Data Structures

  • Upload
    barny

  • View
    42

  • Download
    0

Embed Size (px)

DESCRIPTION

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. - PowerPoint PPT Presentation

Citation preview

Page 1: Chapter 12 Simple Data Structures

1

Chapter 12Simple Data Structures

Page 2: Chapter 12 Simple 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

Page 3: Chapter 12 Simple Data Structures

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 struct student may be related to• Objects: all instances of struct student {

char name[20];

int ID;int grade;

}

• Operations: getName(), getID(), getGrad(), printStdInfo(), etc.

Page 4: Chapter 12 Simple Data Structures

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.

Page 5: Chapter 12 Simple Data Structures

5

• 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.

Why Abstract Data Types?

Page 6: Chapter 12 Simple Data Structures

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

Page 7: Chapter 12 Simple Data Structures

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 toptop of the stack and deletions also restricted to the same end

• Operations– initialize – push– pop– empty– full

Page 8: Chapter 12 Simple Data Structures

8

• 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

Characteristics of Stack

Page 9: Chapter 12 Simple Data Structures

9

Stack Operations• Initialize (Stack) : put Stack into its initial

state

– Precondition:• Stack is in an unknown state

– Postcondition:• Stack is empty

Page 10: Chapter 12 Simple Data Structures

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

Page 11: Chapter 12 Simple Data Structures

11

• 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

Pop Operation

Page 12: Chapter 12 Simple Data Structures

12

• 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

Stack Test Operations

Page 13: Chapter 12 Simple Data Structures

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.

Page 14: Chapter 12 Simple Data Structures

14

Stack Declarations

#define MAX_STACK_SIZE 100typedef 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;

Page 15: Chapter 12 Simple Data Structures

15

void initialize( int* top )

{

top = -1;

}

void push( int* top, element stack[], element item )

{

if ( !stackfull(*top ) )

stack[ ++(*top) ] = item;

}

Source for Stack Operations

Page 16: Chapter 12 Simple Data Structures

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 );}

Page 17: Chapter 12 Simple Data Structures

17

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 : dcba

Page 18: Chapter 12 Simple Data Structures

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 ); }

Page 19: Chapter 12 Simple Data Structures

19

• 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 / +

Stack Application Example 2

Page 20: Chapter 12 Simple Data Structures

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 ‘(’

Page 21: Chapter 12 Simple Data Structures

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’;}

Page 22: Chapter 12 Simple Data Structures

22

symb Postfix String opStackA A

* A *

B AB *

+ AB* +

( AB* +(

C AB*C +(

- AB*C +(-

D AB*CD +(-

) AB*CD- +

/ AB*CD- +/

E AB*CD-E */

AB*CD-E/+

Page 23: Chapter 12 Simple Data Structures

23

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

Page 24: Chapter 12 Simple Data Structures

24

• 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

Characteristics of Queue

Page 25: Chapter 12 Simple Data Structures

25

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.

Page 26: Chapter 12 Simple Data Structures

26

• 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.

Page 27: Chapter 12 Simple Data Structures

27

• 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, FALSE is returned.

Page 28: Chapter 12 Simple Data Structures

28

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;

Page 29: Chapter 12 Simple Data Structures

29

• 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;

Page 30: Chapter 12 Simple Data Structures

30

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;}

Source for Queue Operations

Page 31: Chapter 12 Simple Data Structures

31

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;}

Page 32: Chapter 12 Simple Data Structures

32

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;}

Page 33: Chapter 12 Simple Data Structures

33

/* 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");}

Page 34: Chapter 12 Simple Data Structures

34

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);

}}