Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
* list.h
* Copyright (c) 2010, Irfan Iqbal
* -------
* This file defines an enhanced version of the list ADT discussed in class.
*/
#ifndef LIST_H
#define LIST_H
#define LIST_SIZE 8
/*
* flags to specify list behavior
*/
#define O_LIMITED 0x00000000 /* list cannot grow beyond a maximum size */
#define O_UNLIMITED 0x00000001 /* list can grow to any size */
/*
* type definitions.
*/
typedef int list_elem_t;
typedef unsigned int list_option_t;
typedef struct listCDT *listADT;
typedef enum {
LIST_NOERROR,
LIST_FULL,
LIST_EMPTY,
LIST_INVALID,
LIST_NOMEM,
LIST_BAD_LOC,
} list_err_t;
/*
* function prototypes.
*/
/*
* list_init
* ---------
* Initializes a list ADT by allocating the necessary resources and
* returns a handle to caller. The handle is used in all subsequent
* calls to various functions/methods of this ADT.
*
* Parameters:
* 'size': specifies the maximum number of elements the list will have.
* 'option': specifies whether the list can grow if it becomes full.
*/
listADT list_init (unsigned int size, list_option_t option);
/*
* list_free
* ---------
* Do away with the list ADT, freeing up all resources allocated.
*
* Parameters:
* 'l': list ADT returned by 'list_init' function.
*/
void list_free (listADT l);
/*
* list_insert
* -----------
* Inserts a specified element at the specified location in the list.
*
* Parameters:
* 'l': the list ADT in which to insert the element.
* 'e': the element to be inserted.
* 'loc': the location at which to insert the element.
*/
list_err_t list_insert (listADT l, list_elem_t e, int loc);
/*
* list_delete
* -----------
* Deletes the element at the specified location in the list.
*
* Parameters:
* 'l': the list ADT from which to delete the element.
* 'loc': the location of the element to be deleted.
*/
list_err_t list_delete (listADT l, int loc);
/*
* list_read
* ---------
* Obtain the element stored at the specified location in the list
* without deleting it. It is similar to the 'peek' function of
* stack ADT.
*
* Parameters:
* 'l': list ADT from which to read.
* 'pe': location at which to write the element read.
* 'loc': location in the list from which to read.
*
* The size of the list does not change after this operation. Only
* the element at the specified location in the list is copied to
* the memory location pointed to by the pointer 'pe'.
*/
list_err_t list_read (listADT l, list_elem_t *pe, int loc);
/*
* list_write
* ----------
* Overwrites the element at the specified location.
*
* Parameters:
* 'l': list ADT in which to overwrite the element.
* 'e': the new element.
* 'loc': the location at which to write the new element.
*
* The size of the list does not change after this operation. Just
* one element is replaced by another element.
*/
list_err_t list_write (listADT l, list_elem_t e, int loc);
/*
* list_print
* ----------
* Print the contents of the list.
*
* This function does not belong to the ADT. It is going to be replaced
* with a mapping function, and will disappear from the future versions
* of this ADT.
*/
list_err_t list_print (listADT l);
/*
* list_map
* --------
* Apply the specified function on every element stored in the list ADT.
*
* Parameters:
* 'l': list ADT on whose elements to apply the mapping function.
* 'map_fn': mapping function to be applied to the list ADT.
*
* We will enhance this mapping function when we talk about lists which
* store elements of arbitrary types.
*/
list_err_t list_map (listADT l, list_map_fn_t map_fn);
#endif /* LIST_H */
/*
* list.c
* Copyright (c) 2010, Irfan Iqbal
* -------
* This file implements list ADT.
*/
#include <stdlib.h>
#include "list.h"
struct listCDT {
int magic_num;
list_elem_t lst[LIST_SIZE];
int count;
};
return (nl);
}
if (!l) {
return (LIST_INVALID);
}
if (l->count == LIST_SIZE) {
return (LIST_FULL);
}
if ((loc < 1) || (loc > (l->count + 1))) {
return (LIST_BAD_LOC);
}
for (i = (l->count - 1) ; i >= (loc - 1) ; --i) {
l->lst[i + 1] = l->lst[i];
}
l->lst[i + 1] = e;
(l->count)++;
return (LIST_NOERROR);
}
/*
* l_driver.c
* Copyright (c) 2010, Irfan Iqbal
* -------
* This file tests list ADT defined in list.h header file.
*/
#include <stdio.h>
#include "list.h"
scanf("%d", &c);
return (c);
}
while (1) {
print_menu();
z = get_option();
switch (z) {
case 1:
myL = list_init();
break;
case 2:
list_free(myL);
myL = NULL;
break;
case 3:
printf("Enter element to insert: ");
scanf("%d", &elem);
printf("Enter location: ");
scanf("%d", &z);
error = list_insert(myL, elem, z);
if (error == LIST_INVALID) {
printf("Invalid list given.\n");
} else if (error == LIST_FULL) {
printf("List is full.\n");
} else if (error == LIST_BAD_LOC) {
printf("Bad insertion location given.\n");
} else {
printf("Insert successful.\n");
}
break;
case 5:
error = list_print(myL);
if (error == LIST_INVALID) {
printf("Invalid list given.\n");
} else if (error == LIST_EMPTY) {
printf("List is empty.\n");
}
break;
case 6:
printf("Enter 1 to multiply every element by 5\n");
printf("Enter 2 to divide every element by 5\n");
scanf("%d", &z);
if (z == 1) {
error = list_map(myL, map_fn_1);
} else if (z == 2) {
error = list_map(myL, map_fn_2);
}
break;
default:
break;
}
if (z < 1 || z > 6) {
break;
}
}
return (0);
}
/*
/*
* list.c
* Copyright (c) 2010, Irfan Iqbal
* -------
* This file implements list ADT using linked-lists.
*/
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
struct cell {
list_elem_t d;
struct cell *next;
};
struct listCDT {
int magic_num;
struct cell *head;
struct cell *tail; /* optional */
int count;
};
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
struct cell {
list_elem_t d;
struct cell *next; /* also called 'flink' (forward link) */
struct cell *prev; /* also called 'blink' (backward link) */
};
struct listCDT {
int magic_num;
struct cell *head;
struct cell *tail; /* optional */
int count;
};
if (!l) {
return (LIST_INVALID);
}
if (!l->count) {
return (LIST_EMPTY);
}
t = l->head;
while (t) {
map_fn(&(t->d));
t = t->next;
}
return (LIST_NOERROR);
}
/*
* list-gen.h
* Copyright (c) 2010, Irfan Iqbal
* -------
* This file defines list ADT which can store any type of data.
*/
#ifndef LIST_GEN_H
#define LIST_GEN_H
#define LIST_SIZE 8
/*
* type definitions.
*/
typedef struct listCDT *listADT;
/*
* Return value of all of the following functions should be
* LIST_NOERROR in case of successful execution.
*/
typedef int (*list_map_fn_t) (void *p, void *q);
typedef int (*copy_fn_t) (void *dst, void *src);
typedef int (*delete_fn_t) (void *p);
typedef enum {
LIST_NOERROR,
LIST_FULL,
LIST_EMPTY,
LIST_INVALID,
LIST_NOMEM,
LIST_BAD_LOC,
LIST_CP_FAIL,
} list_err_t;
/*
* function prototypes.
*/
listADT list_init (int ds, copy_fn_t cp_fn, delete_fn_t del_fn);
void list_free (listADT l);
list_err_t list_insert (listADT l, void *pe, int loc);
list_err_t list_delete (listADT l, int loc);
list_err_t list_read (listADT l, void *pe, int loc);
list_err_t list_write (listADT l, void *pe, int loc);
list_err_t list_map (listADT l, list_map_fn_t map_fn, void *q);
#endif /* LIST_GEN_H */
/*
* list-gen.c
* Copyright (c) 2010, Irfan Iqbal
* -------
* This file implements the list ADT defined in list-gen.h header file.
* The implementation does not define explicit cell structure to store
* items inserted by client.
*/
/*
* To obtain debug output compile with "-DDEBUG" flag as shown below.
*
* $ gcc -g -Wall -DDEBUG -c list-gen.c
*/
#ifdef DEBUG
#include <stdio.h>
#endif /* DEBUG */
#include <stdlib.h>
#include "list-gen.h"
struct listCDT {
int magic_num;
void *head;
void *tail;
int count;
int ds;
copy_fn_t cp_fn;
delete_fn_t del_fn;
};
typedef enum {
LIST_OP_READ = 1,
LIST_OP_WRITE,
} list_op_t;
static
list_err_t list_read_write (listADT l, void *pe, int loc, list_op_t op)
{
list_err_t rc;
void *t;
typedef enum {
BST_NOERROR,
BST_INVALID,
BST_NOMEM,
BST_DUP_KEY,
BST_BAD_WALK,
} bst_err_t;
typedef enum {
WALK_PRE_ORDER = 1,
WALK_IN_ORDER,
WALK_POST_ORDER,
} walk_t;
#endif /* BST_H */
/*
* bst.c
* Copyright (c) 2010, Irfan Iqbal
* -------
* This file implements the binary search tree ADT defined in `bst.h'
* header file. Keys are restricted to integer type.
*/
#include <stdlib.h>
#include "bst.h"
struct node {
bst_key_t k;
struct node *lst; /* left sub-tree */
struct node *rst; /* right sub-tree */
};
struct bstCDT {
struct node *root;
int count; /* total number of nodes in the tree */
};
if (!t) {
return (BST_INVALID);
}
rc = bst_insert_key(&(t->root), k);
if (rc == BST_NOERROR) {
++t->count;
}
return (rc);
}
if (t == NULL )
return NULL;
else
if(t->left == NULL);
return t;
else
return find_min(t-lst);
bst_err_t bst_delete (bstADT t, bst_key_t k)
{
struct node *temp;
if (t == NULL)
{return (BST_INVALID)
else
if (k<t->k)
t->lst = delete (k, t->lst);
else
if (k>t->k)
t->rst = delete (k, t->lst);
else
if (t->lst && t->rst)
{
temp = findmin (t->right); //find_min implemented before
delete function
t->k = temp->k;
t->rst = delete (t->k, t->rst);
}
else
temp = t;
if t->lst == NULL)
t = t->rst;
else if (t->right == NULL)
t = t->lst;
free (temp);
}
return (BST_NOERROR);
}
static void bst_map_tree (struct node *n, map_fn_t mf, walk_t wt,
void *cd)
{
if (!n) {
return;
}
if (wt == WALK_PRE_ORDER) {
mf(n->k, cd);
bst_map_tree(n->lst, mf, wt, cd);
bst_map_tree(n->rst, mf, wt, cd);
} else if (wt == WALK_IN_ORDER) {
bst_map_tree(n->lst, mf, wt, cd);
mf(n->k, cd);
bst_map_tree(n->rst, mf, wt, cd);
} else if (wt == WALK_POST_ORDER) {
bst_map_tree(n->lst, mf, wt, cd);
bst_map_tree(n->rst, mf, wt, cd);
mf(n->k, cd);
}
}
while (1) {
print_menu();
scanf("%d", &opt);
switch (opt) {
case 1:
if (my_bst) {
printf("BST already initialized.\n");
} else {
my_bst = bst_init();
if (my_bst) {
printf("BST successfully initialized.\n");
} else {
printf("Failed to initialize BST.\n");
}
}
break;
case 2:
printf("Function not implemented yet.\n");
break;
case 3:
printf("Enter key: ");
scanf("%d", &k);
rc = bst_insert(my_bst, k);
if (rc == BST_NOERROR){
printf("Key inserted successfully inserted.\n");
} else if (rc == BST_DUP_KEY) {
printf("Duplicate key. Key not inserted.\n");
} else {
printf("Unknown error inserting key.\n");
}
break;
case 4:
printf("Function not implemented yet.\n");
break;
case 5:
printf("Enter 1 for pre-order printing.\n"
"Enter 2 for in-order printing.\n"
"Enter 3 for post-order printing. ");
scanf("%d", &sub_opt);
rc = bst_map(my_bst, print_keys, sub_opt, NULL);
printf("\n");
break;
default:
break;
}
if ((opt < 1) || (opt > 5)) {
break;
}
}
return (0);
}
/*
* symtab.h
* Copyright (c) 2010, Irfan Iqbal
* --------
* This file defines a symbol table abstract data type.
*/
#ifndef SYMTAB_H
#define SYMTAB_H
/*
* Type definitions
*/
typedef struct symtabCDT *symtabADT;
typedef int (*cmp_fn_t)(void *k1, void *k2);
typedef int (*hash_fn_t)(void *k, int num_bins);
typedef int (*map_fn_t)(void *k, void *cd);
typedef int (*del_fn_t)(void *k, void *d);
typedef enum {
SYMTAB_NOERROR,
SYMTAB_NOMEM,
SYMTAB_INVALID,
SYMTAB_EMPTY,
SYMTAB_KEY_NOT_FOUND,
SYMTAB_NO_HASH_FN,
SYMTAB_NO_CMP_FN,
SYMTAB_NO_DEL_FN,
SYMTAB_OP_FAILURE,
} symtab_err_t;
/*
* Exported API
*/
symtabADT symtab_init (void);
void symtab_free (symtabADT st);
symtab_err_t enter (symtabADT st, void *key, void *data);
symtab_err_t lookup (symtabADT st, void *key, void *data);
symtab_err_t delete (symtabADT st, void *key);
symtab_err_t set_cmp_fn (symtabADT st, cmp_fn_t cmp_fn);
symtab_err_t set_hash_fn (symtabADT st, hash_fn_t hash_fn);
symtab_err_t set_del_fn (symtabADT st, del_fn_t del_fn);
symtab_err_t map (symtabADT st, map_fn_t map_fn);
#endif /* SYMTAB_H */
/*
* symtab.c
* Copyright (c) 2010, Irfan Iqbal
* --------
*
* This file implements the symbol table abstract data type defined in
* symtab.h header file. Keys as well as their values are known only to
* client.
*/
#ifdef DEBUG
#include <stdio.h>
#endif /* DEBUG */
#include <stdlib.h>
#include <string.h>
#include "symtab.h"
#include "list-gen.h"
#define NUM_BINS 5
#define MAGIC_NUM 0xdeadcafe
struct symtabCDT {
int magic_num;
int num_bins;
int num_keys;
listADT *bin_list;
cmp_fn_t cmp_fn;
hash_fn_t hash_fn;
del_fn_t del_fn;
};
/*
* We do not know the type of `key' and the type of the corresponding
* `value'. Therefore, both are `void *'. We will store this structure
* in the linked list attached to the bin to which the given key hashes.
*/
struct key_val_pair {
void *key;
void *val;
};
/*
* This function will be passed to `list_init'. Please see `list-gen.h'
* header file for details.
*/
static int st_lst_cp_fn (void *dst, void *src)
{
memcpy(dst, src, sizeof(struct key_val_pair));
return (0);
}
/*
* This function will be passed to `list_init'. Please see `list-gen.h'
* header file for details.
*/
static int st_lst_del_fn (void *t)
{
return (0);
}
/*
* Function to hash string type keys. It advisable to pass a prime
* number as second argument (bins).
*/
int hash_string (char key[], int bins)
{
int i;
unsigned long bin_number;
bin_number = 0;
for (i = 0 ; key[i] != '\0' ; ++i) {
bin_number = bin_number * MULTIPLIER + key[i];
}
return (bin_number % bins);
}
while (1) {
print_menu();
scanf("%d", &opt);
switch (opt) {
case 1:
if (!(st = symtab_init())) {
printf("%%%%Unable to initialize symbol table.\n");
break;
}
set_cmp_fn(st, key_compare);
set_hash_fn(st, (int(*)(void *, int))hash_string);
break;
case 2:
/* function not implemented yet. */
printf("%%%%Function not implemented.\n");
break;
case 3:
enter_key_in_symtab(st);
break;
case 4:
lookup_key_in_symtab(st);
break;
case 5:
/* function not implemented yet. */
printf("%%%%Function not implemented.\n");
break;
}
if ((opt < 1) || (opt > 5)) {
break;
}
}
return (0);
}