abstract data types - university of washingtonfaculty.washington.edu/jstraub/isilon/isilon1/unit...
TRANSCRIPT
Abstract Data TypesAn Abstract Data Type, or ADT, consists of: 1. A description of a data type, e.g. list, complex
number.2. A description of the operations that can be
performed on the data type, e.g. add to a list, multiply two complex numbers.
Abstract Data Type, ExampleComplex NumberA complex number is represented in the form:A + Bi
Where A and B are real numbers and i is the square root of ‐1. A is referred to as the real part and Bi is referred to as the imaginary part.
Allowed operations: AdditionThe sum of two complex numbers is defined as the sum of their respective real and imaginary parts:
(A + Bi) + (C + Di) = (A + C) + (B + D)i
MultiplicationThe product of two complex numbers is defined as the algebraic product of the two pairs:
A + Bix C + Di ---------------
ADi + BDi2AC + Bci---------------= AC + (AD + BC)i – BD= (AC - BD) + (AD + BC)i
Etc.
Application Programming Interface• An Application Programming Interface, or API, consists of a set
of related declarations, functions and tools.
• An API is often encapsulated in a library.
• The header file and source files of a module may comprise an API.
• An API may be used to implement an ADT.
Application Programming Interface, Example// cpx.htypedef struct cpx_num_s{
double real;double imag;
} CPX_NUM_t;
// cpx.cCPX_NUM_t CPX_add( CPX_NUM_t num1, CPX_NUM_t num2 ){
CPX_NUM_t sum = { num1.real + num2.real, num1.imag + num2.imag };return sum;
}
CPX_NUM_t CPX_mul( CPX_NUM_t num1, CPX_NUM_t num2 ){
CPX_NUM_t prod ={ num1.real * num2.real - num1.imag * num2.imag,num1.real * num2.imag + num1.imag * num2.real
};return prod;
}. . .
List ADTThe List ADT consists of any uniform data type and six operations.
ListA list is a sequence of members of type T.
Operations:Determine if the list is empty
The result of this operation is TRUE if the list contains no members. Determine if the list is full
The result of this operation is TRUE if no more members may be added to the sequence.
Obtain the list size The result of this operation is the number of members in the sequence.
Add a member to the list This operation will add a new member to the end of the sequence.
Traverse the list This operation will "visit" every member of the sequence in the order that the sequence was created.
Clear the list This operation will return the list to the empty state.
Singly Linked Lists• A linked list is a set of records linked together by pointers. • A singly linked list is a linked list in which each record is linked
to the next by a forward reference.
flink
flink
Data flink
Data flink
Data flink
Data
head
Singly Linked List API: SLIST_addvoid *SLIST_add( void **head, void *item )
Adds an item to the tail of the list.head
Address of list headitem
Item to addReturns: item added
SLIST_addtypedef struct{
void *next;} ITEM_t, *ITEM_p_t;
void *SLIST_add( void **head, void *item ){
ITEM_p_t ditem = item;
ditem->next = NULL;if ( *head == NULL )
*head = item;else{
ITEM_p_t temp = SLIST_get_tail( *head );temp->next = item;
}
return item;}
Singly Linked List API: SLIST_add_aftervoid *SLIST_add_after( void *item, void *after )
Adds a new item after an existing item in the list.item
The item to add.after
The item after which to add.Returns: the item added.
Singly Linked List API: SLIST_traversetypedef void SLIST_TRAV_PROC_t( void *item );typedef SLIST_TRAV_PROC_t *SLIST_TRAV_PROC_p_t;void SLIST_traverse( void *head, SLIST_TRAV_PROC_p_t trav_proc )
Visits every item in a list.head
The list head.trav_proc
Callback procedure; called for each item in the list.
SLIST_traversetypedef struct{
void *next;} ITEM_t, *ITEM_p_t;
void SLIST_traverse( void *head, SLIST_TRAV_PROC_p_t trav_proc ){
ITEM_p_t item = head;
for ( item = head ; item != NULL ; item = item->next )trav_proc( item );
}
Singly Linked List API: SLIST_find_itemtypedef void *SLIST_FIND_PROC_t( void *item, void *key );typedef SLIST_FIND_PROC_t *SLIST_FIND_PROC_p_t;void *SLIST_find_item( void *head, void *key, SLIST_FIND_PROC_p_t find_proc )
Locates an item in a list. head
The list head.key
The key to the desired item.find_proc
Callback procedure; called items in the list. Returns true if target item is identified.
Returns: target item, or NULL if not found.
SLIST_find_itemtypedef struct{
void *next;} ITEM_t, *ITEM_p_t;
void *SLIST_find_item( void *head, void *key, SLIST_FIND_PROC_p_tfind_proc ){
ITEM_p_t item = head;void *result = NULL;
while ( item != NULL && result == NULL ){
result = find_proc( item, key );item = item->next;
}
return result;}
Singly Linked List API: SLIST_get_tailvoid *SLIST_get_tail( void *head )
Returns the last item in a list. head
list headReturns: last item, or NULL if list is empty.
Singly Linked List API: SLIST_remove_headvoid *SLIST_remove_head( void **head )
Removes and returns the first item in a list. head
The list headReturns: first item in the list, or NULL if list is empty.
SLIST_remove_headtypedef struct{
void *next;} ITEM_t, *ITEM_p_t;
void *SLIST_remove_head( void **head ){
ITEM_p_t result = NULL;if ( *head != NULL ){
result = *head;if ( result != NULL ){
*head = result->next;result->next = NULL;
}}
}
Exercises1. Download and complete the slist.h and slist.c from the
class web page; you will have to write the code for SLIST_add_after and SLIST_get_tail.
2. Given the following declaration:typedef struct name_item_s{
struct_name_item_s *next;int num;char name[21];
} NAME_ITEM_t, *NAME_ITEM_p_t;Create five sequentially numbered NAME_ITEM_t objects with unique names and add them to a singly‐linked list. Using the name as a key, search for each item using SLIST_find_item.
Stacks: BasicsA stack is known as a first‐in, last‐out queue; items are removed from the queue in reverse order.
dick
jane
sally
push( “dick” );
push( “jane” );
push( “sally” );
stack head
stack tail
puts( pop() );
push( pop() );
push( pop() );
output:sallyjanedick
Stacks: Implementation StrategiesTraditional stacks are implemented as arrays, and may be bottom‐up or top‐down.
0
1
2
3
4
5
6
7
8
0
1
2
3
4
5
6
7
8
Bottom‐up Stack
Top‐down Stack
top of stack
top of stack
Stacks: pushAdding an item to the stack is a push operation; the next available address is indicated via a stack pointer.
occupied
occupied
occupied
occupied
0
1
2
3
4
5
6
7
8
occupied
occupied
occupied
occupied
0
1
2
3
4
5
6
7
8
Bottom‐up Stack
Top‐down Stack
stack pointer
stack pointer
Stacks: StatesThe stack pointer indicates whether the stack is empty or full.
0
1
2
3
4
5
6
7
8
occupied
occupied
occupied
occupied
occupied
occupied
occupied
occupied
occupied
0
1
2
3
4
5
6
7
8
Bottom‐up Stack, full
stack pointer
stack pointer
Bottom‐up Stack, empty
Stacks: popAdding an item to the stack is a pop operation.
occupied
occupied
occupied
occupied
0
1
2
3
4
5
6
7
8
Bottom‐up Stack
stack pointer
occupied
occupied
occupied
Stack: Reversing a Stringstatic char *reverse_chars( char *string ){
char *temp = string;char stack[50];char *sptr = stack;
while ( *temp != '\000' )*sptr++ = *temp++; /* push */
temp = string;while ( sptr != stack )
*temp++ = *--sptr; /* pop */
return string;}
The STK Module
The STK module is an API that implements a stack as a fixed‐size array of type void*. It consists of a private header file (stkp.h), a public header file (stk.h) and a source file (stk.c). It illustrates how encapsulation is accomplished in C.
The STK Module: Encapsulation, stkp.h// STK module private header file.#ifndef STKP_H#define STKP_H
#include <stk.h>#include <stddef.h>
typedef struct stk__control_s{
void **stack;void **sptr;size_t size;
} STK__CONTROL_t, *STK__CONTROL_p_t;
#endif
occupied
occupied
occupied
occupied
sptr
occupied
occupied
occupied
stack
size
The STK Module: Encapsulation, stk.h#ifndef STK_H#define STK_H
#include <stdio.h>#include <stddef.h>#include <stdbool.h>
#define STK_NULL_ID (NULL)
typedef struct stk__control_s *STK_ID_t;
void STK_clear_stack( STK_ID_t stack );STK_ID_t STK_create_stack(size_t size );STK_ID_t STK_destroy_stack(STK_ID_t stack );bool STK_is_stack_empty( STK_ID_t stack );bool STK_is_stack_full( STK_ID_t stack );void *STK_peek_item( STK_ID_t stack );void *STK_pop_item( STK_ID_t stack );void STK_push_item( STK_ID_t stack, void *item );
#endif
The STK Module: STK_createSTK_ID_t STK_create( size_t size )
Creates a stack of a given size; returns a value that identifies the stack.
The STK Module: STK_push_itemvoid STK_push_item( STK_ID_t stack, void *item )
Pushes an item onto a stack.stack
The ID of the target stack.item
The item to push.
The STK Module: STK_pop_itemvoid *STK_pop_item( STK_ID_t stack )
Removes the item at the top of the stack and returns it.stack
The ID of the target stack.Returns: The item at the top of the stack.
The STK Module: STK_peek_itemvoid *STK_peek_item( STK_ID_t stack )
Returns the item at the top of the stack withoutremoving it.
stackThe ID of the target stack.
Returns: The item at the top of the stack.
The STK Module: STK_is_stack_emptybool STK_is_stack_empty( STK_ID_t stack )
Indicates whether or not a stack is empty.stack
The ID of the target stack.Returns: true if the stack is empty, false otherwise.
The STK Module: STK_is_stack_fullbool STK_is_stack_full( STK_ID_t stack )
Indicates whether or not a stack is full.stack
The ID of the target stack.Returns: true if the stack is full, false otherwise.
The STK Module: STK_clear_stackvoid STK_clear_stack( STK_ID_t stack )
Returns a stack to the empty state.stack
The ID of the target stack.
The STK Module: STK_destroy_stackSTK_ID_t STK_destroy_stack( STK_ID_t stack )
Returns a stack to the empty state.stack
The ID of the target stack.
ExerciseImplement the stack module in stk.c. You can download stk.h and stkp.h from the class website.
Doubly‐Linked ListsA doubly‐linked list is a linked list in which every item is linked to the next item in the list by a forward reference and the previous item by a forward reference.
Additional Data
flinkblink
Additional Data
flinkblink
Additional Data
flinkblink
Circular ListsIn a circular list a pair of pointers (the list anchor) point to the first and last items in the list; the forward reference of the last item, and the backward reference of the first item point to the anchor.
flinkblink
Additional Data
flinkblink
Additional Data
flinkblink
Doubly Linked Lists – The ENQ ModuleMethods
• Create a new doubly‐linked list • Create a new enqueuable item • Destroy an item • Destroy a list • Test whether an item is enqueued• Test whether a list is empty • Add an item to the head of a list • Add an item to the tail of a list • Add an item after another item• Add an item before another item
• Dequeue an item from a list • Dequeue the item at the head of a list • Dequeue the item at the tail of a list • Get the item at the head of a list • Get the item at the tail of a list • Get the previous item • Get the next item • Get the name of a list • Get the name of an item • Empty a list
CDA Facilities: cda.h#define CDA_NEW( type ) ...#define CDA_NEW_STR( str ) ...#define CDA_NEW_STR_IF( str ) ...#define CDA_CARD( arr ) ...
void *CDA_calloc(size_t num,size_t size
);
void CDA_free(void *mem
);
void *CDA_malloc(size_t size
);
void *CDA_realloc(void *old, size_t size
);
The ENQ Module: enq.h#define ENQ_GET_HEAD( list ) ((list)->flink)#define ENQ_GET_TAIL( list ) ((list)->blink)#define ENQ_GET_NEXT( item ) ((item)->flink)#define ENQ_GET_PREV( item ) ((item)->blink)#define ENQ_GET_LIST_NAME( list ) ((list)->name)#define ENQ_GET_ITEM_NAME( item ) ((item)->name)
typedef struct enq_item_s {struct enq_item_s *flink;struct enq_item_s *blink;char *name;
} ENQ_ITEM_t, *ENQ_ITEM_p_t;
typedef ENQ_ITEM_t ENQ_ANCHOR_t, *ENQ_ANCHOR_p_t;
The ENQ Module: ENQ_create_listENQ_ANCHOR_p_t ENQ_create_list( const char *name ){
ENQ_ANCHOR_p_t list = CDA_NEW( ENQ_ANCHOR_t );
list->flink = list;list->blink = list;list->name = CDA_NEW_STR_IF( name );
return list;}
The ENQ Module: ENQ_destroy_listENQ_ITEM_p_t ENQ_destroy_list( ENQ_ANCHOR_p_t list ){
ENQ_empty_list( list );CDA_free( list->name );CDA_free( list );
return NULL;}
The ENQ Module: ENQ_empty_listENQ_ITEM_p_t ENQ_empty_list( ENQ_ANCHOR_p_t list ){
while( !ENQ_is_list_empty( list ) )ENQ_destroy_item( list->flink );
return list;}
The ENQ Module: ENQ_create_itemENQ_ITEM_p_t ENQ_create_item( const char *name, size_t size ) {
ENQ_ITEM_p_t item = (ENQ_ITEM_p_t)CDA_malloc( size );
CDA_ASSERT( size >= sizeof( ENQ_ITEM_t) );item->flink = item;item->blink = item;item->name = CDA_NEW_STR_IF( name );
return item;}
The ENQ Module: ENQ_destroy_itemENQ_ITEM_p_t ENQ_destroy_item( ENQ_ITEM_p_t item ){
ENQ_deq_item( item );CDA_free( item->name );CDA_free( item );
return NULL;}
Exercises1. Download enq.h, enqp.h and enq.c from the class web site.
Write the following methods:ENQ_deq_item, ENQ_add_after, ENQ_add_before, ENQ_add_head, ENQ_add_tail, ENQ_deq_head, ENQ_deq_tail
2. Add the method:ENQ_item_p_tENQ_find_item( const char *name )
which returns an item with the given name, or NULL if no such item exists. Don’t forget to add a prototype to enq.h.