Chapter 3: Lists, Stacks and Queues Concept of Abstract Data Type (ADTS) How to efficiently perform operations on list Stack ADT and its applications Queue.

Post on 30-Mar-2015

221 Views

Category:

Documents

3 Downloads

Preview:

Click to see full reader

Transcript

Chapter 3: Lists, Stacks and Queues

• Concept of Abstract Data Type (ADTS)

• How to efficiently perform operations on list

• Stack ADT and its applications

• Queue ADT and its applications

3.1 Abstract Data Type

• Modular program

• Advantages:

(1) debugging

(2) team work

(3) easy to modify

3.1 Abstract Data Type

• Abstract data typea set of operations

mathematical abstractions

just as integer, boolean

• Basic idea

write once, use many

Any changes are transparent to the other modules

3.2 List ADT

• Review on linked list

• Common errors

memory allocation

segmentation violation

check for NULL pointer

free memory

3.2 List ADT

• Doubly linked list

struct node

{ int Number;

struct node *left;

struct node *right;

}

3.2.1 List ADT: Example1

• Single-variable Polynomials

N

i

iiXAXF

0

)(typedef struct

{ int CoeffArray[MaxDegree+1];

int HighPower

} *polynomial

3.2.1 List ADT: Example 1

• Initialize a polynomial

void ZeroPolynomial(Polynomial Poly)

{ int j;

for (j = 0; j < MaxDegree; j++)

poly->CoeffArray[j] = 0;

Poly->HighPower = 0;

}

3.2.1 List ADT: Example 1

• Add two polynomials

void AddPolynomial(const Polynomial Poly1, const Polynomial Poly2, Polynomial PolySum)

{ int j;

ZeroPolynomial(PolySum);

PolySum->HighPower = Max(Poly1-> HighPower, Poly2 -> HighPower);

for (j=PolySum->HighPower; j>=0; j--)

PolySum->CoeffArray[j] = Poly1-> CoeffArray [j] + Poly2-> CoeffArray[j];

}

3.2.1 List ADT: Example 1

• Multiply two polynomialsvoid MultPolynomial(const Polynomial Poly1, const Polynomial

Poly2, Polynomial PolyProd)

{ int j,k;

ZeroPolynomial(PolyProd);

PolySum->HighPower = Poly1-> HighPower+ Poly2 -> HighPower;

for (j=0; j=Poly1->HighPower; j++)

for (k=0; k=Poly2->HighPower; k++)

PolyProd->CoeffArray[j+k] += Poly1-> CoeffArray [j]* Poly2-> CoeffArray[k];

}

3.2.1 List ADT: Example 1

• Multiply two polynomials: limitation

• Consider the following situationP1(X) = 10 X1000 + 5X14 + 1

P2(X) = 3X1990 - 2X1492 +11X +5

• Most of the time is spent multiplying zeros

3.2.1 List ADT: Example 1

• Multiply two polynomials: better structure

struct node

{ int Coefficient;

int Exponent;

struct node *Next;

}

3.2.1 List ADT: Example 1

• Linked list representation of the previous structure

3.2.2 List ADT: Example 2

• Multilists• A university with 40,000 students and 2,500

subjects needs to generate 2 reports

1. Lists of registration for each class

2. Classes that each student registered.

Implementation: construct 2D array (40Kx2K5) = 100M entries

if each student takes 3 subjects => only 120K entries (~0.1% of 100M) => waste of resources.

3.2.2 List ADT: Example 2

MultilistsMultilists

3.3 Stack ADT

• Stack model

3.3 Stack ADT

• LIFO structure

• Access from the top

• Basic Operations– empty (s)– pop (s) – push (s, i) – top (s)

3.3.1Implementation of stack using Linked List

struct Node;

typedef struct Node *PtrToNode;

typedef PtrToNode Stack;

struct Node{ ElementType Element;

PtrToNode Next;

}

3.3.1Implementation of stack using Linked List

int IsEmpty(Stack S);

Stack CreatStack(void);

void DisposeStack(Stack S);

void MakeEmpty(Stack S);

void Push(ElementType X, Stack S);

void Pop(Stack S);

ElementType Top(Stack S);

3.3.1Implementation of stack using Linked List

• Test for an empty stack

int Isempty(Stack S)

{

return (SNext == NULL)

}

3.3.1Implementation of stack using Linked List

• Create an empty stackstack CreatStack(void)

{ Stack S;

S=malloc(sizeof(struct Node));

if (S==NULL)

FatalError(“Out of space!!!”);

MakeEmpty(S)

return(S);

}

void MakeEmpty(Stack S){ if (S==NULL)

printf(“Error message!”);

else

while (!IsEmpty(S))

pop(S)

}

3.3.1Implementation of stack using Linked List

• Push onto a stackvoid Push(ElementType X, Stack S)

{ PtrtoNode TmpCell;

TmpCell = malloc(sizeof(struct Node));

if (TmpCell == NULL)

fatalError(“message”);

else

{ TmpCell Element = X;

TmpCell Next = S Next;

S Next = TmpCell;

}

}

3.3.1Implementation of stack using Linked List

• Return top element in a stack

ElementType Top(Stack S)

{ if (!IsEmpty(S))

return (S Next Element);

Error(“Empty stack”);

return 0;

}

3.3.1Implementation of stack using Linked List

• Pop from a stackvoid Pop(Stack S)

{ PtrToNode FirstCell;

if (ISEmpty(S);

Error (“Empty stack”);

else

{ FirstCell = S Next;

S Next =S Next Next;

free(FirstCell);}

}

3.3.2 Implementation of stack using Array

Struct StackRecord

{

int Capacity;

int TopOfStack;

ElementType *Array;

}

#define STACKSIZE 100

Struct StackRecord

{ int top;

ElementType Array[STACKSIZE];

}

3.3.2 Implementation of stack using Array

• Test for empty stack

empty (stack *ps)

{

return (ps top == -1)

}

3.3.2 Implementation using Array

• Pop top element from stackint pop (stack *ps)

{ int x

if (empty (ps))

printf (“%s\n”, “stack underflow!”);

else

{ x = ps array [ps top];

(ps top)--;

return (x); }

}

3.3.2 Implementation using Array

Push an element onto the stackpush (stack *ps, int x)

{ if (ps top == STACKSIZE – 1)

printf (“%s\n”, “stack overflow!”);

else

{ (ps top)++;

ps items [ps top] = x;

}

}

3.3.3 Variable types of stack elements

#define STACKSIZE 100

#define INTGR 1

#define FLT 2

#define STRING 3

struct stackelement

{

int etype; /* element type */

union

{ int ival;

float fval;

char *pval;

} element; /* end union */

}

3.3.3 Variable Types of Stack Elements

• To access the top elementstruct stack s;

struct stackelement se;

se = s.items [s.top];

switch (se.etype)

{

case INTGR: printf (“%d\n”, se.ival); break;

case FLT: printf (“%d\n”, se.fval); break;

case STRING: printf (“%s\n”, se.pval);

}

3.3.4 Applications

• Balancing Symbols• Make an empty stack. Read characters until end of file.

• If the character is an opening symbol, push it onto stack.

• If it is a closing symbol, then if the stack is empty, report an error. Otherwise, pop the stack.

• If the symbol popped is not the corresponding opening symbol, then report an error.

• At the end of file, if the stack is not empty, report an error.

3.3.4 Applications

• Postfix Expressions

• 4.99+5.99+6.99*1.06 = 19.05 or 18.39

• postfix notation of (4.99*1.06 + 5.99 + 6.99*1.06)

is 4.99 1.06 * 5.99 + 6.99 1.06 * +

• Why do we need postfix notation?

3.3.4 Application: Postfix

• How does postfix work?

• e.g. 6 5 2 3 + 8 * + 3 + *

3.3.4 Application : Postfix

3.3.4 Application : Postfix

3.3.4 Applications

• Converting infix expressions into postfix

• Infix A * B + C * D

• Postfix A B * C D * +

3.3.4 Application: infix postfix

Stack -> Input Postfix StringA A

* * A

* B A B

+ + A B *

+ C A B * C

+ * * A B * C

+ * D A B * C D

pop stack A B * C D * +

3.3.4 Application: infix postfix

opstk = the empty stack;

while (not end of input)

{ symb = next input character;

if (symb is an operand)

add symb in the postfix string;

else

{ while (!empty (opstk) && prcd (stack (opstk), symb))

{ topsymb = pop (opstk);

add topsymb to postfix string;

}

push (opstk, symb);

}

}

3.3.4 Application: infix postfix

/* output any remaining operators */

while (!empty (opstk))

{

topsymb = pop (opstk);

add topsymb to the postfix string;

}

3.3.4 Application: infix postfix

With parentheses

Stack -> Input Postfix String

( (

( A A

( + + A

( + B A B

) A B +

* * A B +

* C A B + C

pop stack A B + C *

3.3.4 Application: infix postfix

• Please refer to infix2postfix.doc for implementation.

3.4 Queue ADT

Ordered collections of data items– Delete item at front of the queue– Insert item at rear of the queue– A FIFO structure

A B C D E

front rear

3.4 Queue ADT

• Basic operations

(1) insert (q, x)

(2) remove (q, x)

(3) empty (q)

3.4 Queue ADT

• Array implementation#define MAXQUEUE 100

struct queue

{

int items [MAXQUEUE];

int front, rear, length;

} q;

3.4 Queue ADT

void insert (q, x)

{

q.length++;

q.rear++;

q.items [q.rear] = x;

}

3.4 Queue ADT

void remove (q, x)

{

x = q.items [q.front];

q.front++;

q.length--;

}

3.4 Queue ADT

• Problem: May run out of rooms

(1) Keep front always at 0 by shifting the contents up the queue, but the computer solution is inefficient

(2) Use a circular queue (wrap around & use a length variable to keep track of the queue length)

3.4 Queue ADT

insert (queue *pq, int x)

{ if ((pq length) == MAXQUEUE) /* check for overflow */

printf (“Queue overflow”);

else

{ (pq length)++; /* make room for a new element */

if ((pq rear) == MAXQUEUE - 1)

pq rear = 0;

else (pq rear)++;

pq items [pq rear] = x;

/* check if queue is originally empty */

if ((pq length) == 1)

pq front = pq rear;

}

}

3.4 Queue ADT

void empty (queue *pq)

{

if ((pq length) == 0)

return (TRUE);

else

return (FALSE);

}

3.4 Queue ADT

void remove (queue *pq)

{ if (empty (pq))

printf (“Queue underflow”);

else

if (pq front == MAXQUEUE - 1)

{ pq front = 0;

return (pq items [MAXQUEUE - 1]);

}

else

{ (pq front)++;

return (pq items [(pq front) - 1]);

}

}

3.4 Applications of Queues

• Print jobs

• Computer networks

• OS

• Real-life waiting lines

top related