abstract data types - university of washingtonfaculty.washington.edu/jstraub/isilon/isilon1/unit...

Post on 19-Jul-2020

16 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

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.

top related