Professional Documents
Culture Documents
If you confirm that the file is coming from a trusted source, you can send
the following SHA-256 hash value to your admin for the original file.
e30d63709d403c1d52aff937082177bce39be888caa945951b82ada455d7c
12f
Abstract Data Types
Abstract Data Types
• A useful tool for specifying the logical properties of a data type
is the abstract data type, or ADT.
• User of the ADT “sees” only the interface to the objects; the
implementation details are “hidden” in the definition of the
ADT
Constructor function:
RATIONAL makerational (int, int);
Selector functions :
int numerator (RATIONAL);
Int denominator (RATIONAL) ;
Operations:
RATIONAL add (RATIONAL,RATIONAL);
RATIONAL mult (RATIONAL, RATIONAL);
RATIONAL reduce (RATIONAL) ;
Equality testing :
int equal (RATIONAL, RATIONAL);
Print :
void printrat (RATIONAL) ;
Several Ways to Represent Rational
typedef struct {
int numerator;
int denominator;
} Rational;
typedef struct {
int ar[2];
} Rational;
ADT: Rational Number
Concrete implementation I
typedef struct {
ETYPE elem[MAX];
int size;
} SET;
• Operations
– initialize
– push
– pop
– empty
– full
Stack Properties and Attributes
Properties
1. LIFO data structures.
2. All accesses are done to the element referenced by top.
3. The top always refers to the topmost element in the stack.
4. Insertions are done “above” the top element.
Attributes
size : The number of elements in the stack: size >= 0 at all times.
top : The topmost element of the stack, refers to null, a special
value indicating top doesn’t reference anything in the stack.
6-24
Example 3 :: Last-In-First-Out STACK
Assume:: stack contains integer elements
top
top
top
top
data
Compiling the datatype
$ gcc -c stack.c
PUSH OPERATION
top
POP OPERATION
top
7 4 1 5
front rear
11 37 22 15 3 -7 1
Queue on Circular Array: Representation
void init(queue *) ;
int add(queue *, int) ;
int delete(queue *);
int front(queue *, int *) ;
int isEmpty(queue *) ;
int isFull(queue *) ;
Interface File: queue.h
#include <stdio.h>
#define MAX 200
#define ERROR 1
#define OK 0
typedef struct {
int data[MAX];
int front, rear;
} queue;
/* Queue may contain MAX-1 data.*/
void init(queue *);
int add(queue *, int);
int delete(queue *);
int front(queue *, int *);
int isEmpty(queue *);
int isFull(queue *);
Implementation File: queue.c
#include "queue.h"
void init(queue *q) { q->front=q->rear=0; }
int isEmpty(queue *q)
{ return q->rear == q->front; }
int isFull(queue *q)
{ return (q->rear+1)%MAX == q->front; }
int add(queue *q, int n) {
if(isFull(q)) return ERROR;
q->rear=(q->rear+1)%MAX;
q->data[q->rear]=n;
return OK ;
}
int delete(queue *q) {
if(isEmpty(q)) return ERROR ;
q->front=(q->front+1)%MAX ;
return OK ;
}
int front(queue *q , int *v) {
if(isEmpty(q)) return ERROR ;
*v=q->data[(q->front+1)%MAX] ;
return OK ;
}
User Program: testQueue.c
#include "queue.h"
int main() {
queue q ;
int x , err , val ;
char c;
init(&q);
printf(" ’A’ for add (A 15)\n") ;
printf(" ’D’ for delete\n ’F’ for front\n ’E’ for exit
while((c = getchar()) != ’e’ && c != ’E’)
switch(c) {
case ’A’ : scanf("%d",&x);
err = add(&q,x);
if(err)
printf("Queue is full\n") ;
break;
case ’D’ : err = delete(&q);
if(err)
printf("Q empty\n") ;
break;
case ’F’ : err = front(&q , &val)
if(err) printf("Q empty\n") ;
else printf("%d\n",val);
break;
case ’\n’ :case ’\t’ :case ’ ’ :
break;
default : printf("Token Unknown\n");
}
return 0 ;
}
Basic Idea
– Create a linked list to which items would be added
to one end and deleted from the other end.
– Two pointers will be maintained:
• One pointing to the beginning of the list (point from
where elements will be deleted).
• Another pointing to the end of the list (point where
Rear
new elements will be inserted).
ENQUEUE
front rear
DEQUEUE
front rear
struct node{
char name[30];
struct node *next;
};
typedef struct {
_QNODE *queue_front, *queue_rear;
} _QUEUE;
init_queue(&q);
command[0]='\0';
printf("For entering a name use 'enter <name>'\n");
printf("For deleting use 'delete' \n");
printf("To end the session use 'bye' \n");
while(strcmp(command,"bye")){
scanf("%s",command);
if (!strcmp(command,"delete")) {
if (!isEmpty(&q))
printf("%s \n",dequeue(&q,val));
else printf("Name deleted %s \n",val);
}
} /* while */
printf("End session \n");
}
ENQUEUE DEQUEUE
0 N
front
front rearrear
typedef struct {
_ELEMENT q_elem[MAX_SIZE];
int rear;
int front;
int full,empty;
} _QUEUE;
q->rear=(q->rear+1)%(MAX_SIZE);
q->q_elem[q->rear]=ob;
return;
}
if(IsEmpty(q)) {printf("Queue is
EMPTY\n");return(temp);}
q->front=(q->front+1)%(MAX_SIZE);
temp=q->q_elem[q->front];
return(temp);
}
Spring 2012 Programming and Data Structure 76
Queue Example: Contd.
main() #include <stdio.h>
{ #include <stdlib.h>
int i,j; #include <string.h>
char command[5];
_ELEMENT ob;
_QUEUE A;
init_queue(&A);
command[0]='\0';
printf("For adding a name use 'add [name]'\n");
printf("For deleting use 'delete' \n");
printf("To end the session use 'bye' \n");
if(strcmp(command,"add")==0) {
scanf("%s",ob.name);
if (IsFull(&A))
printf("No more insertion please \n");
else {
AddQ(&A,ob);
printf("Name inserted %s \n",ob.name);
}
}
6-80
Postfix Expressions
• The calculation: ((1 + 2) * 4) + 3 can
be written down in postfix notation
with the advantage of no
precedence rules and no
parentheses needed.
1 2 + 4 * 3 +
6-81
• The expression is evaluated from
the left to right using a stack:
– when encountering an operand, push
the operand
– when encountering an operator, pop
two operands and evaluate the value
then push the result.
6-82
Solution
– when encountering an 1 2 + 4 * 3 +
operand, push the operand
– when encountering an
operation, pop two
operands and evaluate the
value then push the result.
6-83
Stack Usage
Examples
– Browser “back” button: takes you to the page visited before the current page
– Editor “undo” button: takes you to the state of the document before the current
state
– Process stacks: stores call frames to support method calls. The call frame on top of
the stack is the currently executing method, the call frame below it represents the
method invoked before the current method, and so on
– Many virtual machines are also stack-oriented, including the
p-code machine and the Java virtual machine.
6-84
Properties
• Stack: a Last-In-First-Out (LIFO) data structure –
the last item into the stack is the first out of it
– Attributes: top – references the element on top of the
stack
– Operations: push(element), pop(), peek(), isEmpty(),
size()
6-85
Stack Operations
Stack()
pre-condition: none
responsibilities: constructor – initialize the stack attributes
post-condition: size is 0
top refers to null (a special value not part of
the stack)
returns: nothing
push( Type )
pre-condition: none
responsibilities: push element onto the top of the stack
post-condition: element is placed on top of the stack
size is incremented by 1
top refers to the element pushed
returns: nothing
6-86
Stack Operations
pop()
pre-condition: isEmpty() is false
responsibilities: remove and return the element at top
post-condition: the top element is no longer in the stack
size is decremented by 1
top refers to the element below the previous
topmost element or null if the stack is empty
returns: the element removed
throws: empty stack exception if pre-condition is not
met
6-87
Stack Operations
peek()
pre-condition: isEmpty() is false
responsibilities: return the element at top
post-condition: the stack is unchanged
returns: the element referenced by top
throws: empty stack exception if pre-condition is not
met
6-88
Goals for the Stack
• Hide implementation details from the client
– Put only the interface in stack.h, and implementation in stack.c
– Only allow the client to have a pointer to a Stack
• Allow multiple instances of stacks in the same program
– Define a type of Stack, rather than a global variable in stack.c
• Allow different stacks to have different kinds of elements
– Allow another abstract data type to define the type of Item
– Only allow the Stack to refer to a pointer to an Item
• Allow different stacks with different element types in the
same program
– Using void pointers
Stack Interface (stack.h)
Stack_T Stack_new(void);
int Stack_empty(Stack_T stk);
void Stack_push(Stack_T stk, Item_T item);
Item_T Stack_pop(Stack_T stk);
#endif
Notes on stack.h
• Type Stack_T is an opaque pointer
– Clients can pass Stack_T around but can’t look inside
– Definition of Stack can change without recompiling the client
code
• Type Item_T is also an opaque pointer
– … but defined in some other ADT
– So, Stack implementation doesn’t need to know about it
– And, Stack implementation can be used for many kinds of items
• Stack_ is a disambiguating prefix
– A convention that helps avoid name collisions
Stack Implementation: Array
stack.c
#include <assert.h>
#include <stdlib.h>
#include “stack.h”
struct Stack {
int count;
Item_T data[CAPACITY];
};
Stack_T Stack_new(void) {
Stack_T stk = malloc(sizeof(*stk));
assert(stk != NULL);
stk->count = 0;
return stk;
}
Careful Checking With Assert
stack.c
#include <assert.h>
#include <stdlib.h>
#include “stack.h”
struct Stack {
int count;
Item_T data[CAPACITY];
};
Stack_T Stack_new(void) {
Stack_T stk = malloc(sizeof(*stk));
assert(stk != NULL);
stk->count = 0;
return stk; Make sure stk!
} =NULL, or halt the
program!
Stack Implementation: Array (Cont.)
int Stack_empty(Stack_T stk) {
assert(stk != NULL);
return (stk->count == 0);
}
void Stack_push(Stack_T stk, Item_T item) {
assert(stk != NULL);
assert(stk->count < CAPACITY); 0
stack->data[stack->count] = item; 1
stack->count++; 2
} 3
Item_T Stack_pop(Stack_T stk) { 4
assert(stk != NULL); 5
assert(stk->count > 0); count is 3
stk->count--;
CAPACITY is 6
return stk->data[stk->count];
}
Problems With Array Implementation
data
struct List {
val int val;
next struct List *next;
} *head;
3 2 1
head
Popping and Pushing
3 2 1
head
pop( );
3 2 1
head
4 push(4);
2 1
head
Stack Implementation: Linked List
stack.c
#include <assert.h>
#include <stdlib.h>
#include “stack.h”
Stack_T Stack_new(void) {
Stack_T stk = malloc(sizeof(*stk));
assert(stk != NULL);
stk->head = NULL;
return stk;
}
Stack Implementation: Linked List
int Stack_empty(Stack_T stk) {
assert(stk != NULL);
return (stk->head == NULL);
}
#ifndef STACK_INCLUDED
#define STACK_INCLUDED
Stack_T Stack_new(void);
int Stack_empty(Stack_T stk);
void Stack_push(Stack_T stk, void *item);
void *Stack_pop(Stack_T stk);
#endif
Stack Implementation (with void*)
stack.c
#include <assert.h>
#include <stdlib.h>
#include “stack.h”
Stack_T Stack_new(void) {
Stack_T stk = malloc(sizeof(*stk));
assert(stk);
stk->head = NULL;
return stk;
}
stack.c (with void*) continued
int Stack_empty(Stack_T stk) {
assert(stk != NULL);
return stk->head == NULL;
}