哈希表的例子

/*--- wordlist.c -------------------------- Listing 3-4 -------
 *  Lists all words in a text file by storing them in a hash
 *  table. Must be linked to the linked-list primitives of
 *  Chapter 2 and to ElfHash() of Listing 3-3.
 *-------------------------------------------------------------*/

   /* uncomment the following line to print all words
    * with their associated hash value.
    */
// #define LIST_HASH  1
/* #define LIST_HASH  1 */

   /* uncomment the following line to print the unique words
    * and a count of their frequency.
    */
#define LIST_WORDS 1
/* #define LIST_WORDS 1 */

   /* comment out the following line if you do not want an
    * an analysis of the hashing function and hash table load.
    */

// #define LIST_TABLE_STATS 1

   /* uncomment the following line if you want a listing
    * of all words > 10 letters. Such words are often typing
    * or scanning errors in the text or odd constructs.
    */

#define LIST_LONG_WORDS 1

#include 
#include 
#include 
#include 

#include "llgen.h"          /* Header for generic linked lists */
#include "llapp.h"          /* Header for appl.'s linked lists */

extern unsigned long ElfHash ( char *);
extern unsigned int HashPJW ( char * );

/*--- the hash table portion ---*/

//#define TABLE_SIZE  1999    /* Number of slots; a prime number */
#define TABLE_SIZE  7    /* Number of slots; a prime number */

Link   *Table;              /* Our table is an array of Links */

#if 0
int CreateTable ( Link **t )
{
    *t = calloc ( TABLE_SIZE, sizeof ( Link ));
    return ( *t == NULL ? 0 : 1 );
}
#endif

/*--------------------------------------------------------------
 * We use calloc() to allocate the table. However, on some
 * compilers the bit pattern used by calloc() for initialization
 * is not the same as NULL (which is what we want). So we check
 * for this condition and, if it occurs, intialize the table by
 * hand to NULLs.
 *-------------------------------------------------------------*/
int CreateTable ( Link **t )
{
    int i;

    *t = (Link *) calloc ( TABLE_SIZE, sizeof ( Link ));
    if ( *t == NULL )
        return ( 0 );

    if ( **t != NULL )      /* is the calloc'd memory == NULL? */
    {
        for ( i = 0; i < TABLE_SIZE; i++, t++ )
            **t = NULL;
    }

    return ( 1 );
}


/* === main line === */

int main ( int argc, char *argv[] )
{
    char     word[64];        /* the raw word from the file */

    char     buffer[128];
    char     *phoneNum;
    char     *name;
    char     *age;

    char     *pw;             /* pointer to the word */
    int      c, i, j;
    int      chains,          /* counts how many chains     */
             chain_table[33]; /* table of chain lengths     */
                              /*    for our report.         */
    int      add_status;      /* return value from table add*/

    unsigned hash_key;

    struct List *L1,          /* list for hash table entries*/
                *long_wd;     /* list of long words         */

    struct NodeData1 nd;      /* the node we add each time  */
    struct Node      n;       /* used for scratch purposes  */

    FILE     *fin;            /* the input file             */

    if ( argc < 2 )
    {
        fprintf ( stderr, "Error! Usage: wordlist filename\n" );
        exit ( EXIT_FAILURE );
    }

    if ( argc > 2 )
        fprintf
            ( stderr, "Warning: Usage: wordlist filename\n" );

    fin = fopen ( argv[1], "rt" );
    if ( fin == NULL )
    {
        fprintf ( stderr, "Could not find/open %s\n", argv[1] );
        exit ( EXIT_FAILURE );
    }

    /*--- create the table ---*/

    if ( ! CreateTable ( &Table ))
    {
        fprintf ( stderr, "Error! Could not create table\n" );
        exit ( EXIT_FAILURE );
    }

    /*--- set up linked-list data structures ---*/

    L1 = CreateLList ( CreateData1,      /* in llapp.c */
                       DeleteData1,      /*     "      */
                       DuplicatedNode1,  /*     "      */
                       NodeDataCmp1 );   /*     "      */

    long_wd = CreateLList ( CreateData2, /* in llapp.c */
                       DeleteData2,      /*     "      */
                       DuplicatedNode2,  /*     "      */
                       NodeDataCmp2 );   /*     "      */

    if ( L1 == NULL || long_wd == NULL )
    {
        fprintf ( stderr, "Error creating linked list\n" );
        exit ( EXIT_FAILURE );
    }

    /*--- begin processing file ---*/

    while (!feof(fin))
    {
        if (fgets(buffer, 127, fin) == NULL)
            break;
        buffer[strlen(buffer) - 1] = '\0';


        phoneNum = strtok(buffer, ",");
        name = strtok(NULL, ",");
        age = strtok(NULL, ",");

         /*--- get the hash value ---*/
        hash_key = (unsigned int) ElfHash ( phoneNum );
        hash_key %= TABLE_SIZE;


#ifdef LIST_HASH
        printf ( "%15s  %3d\n", phoneNum, hash_key );
#endif

        /*--- insert into table ---*/

        L1->LHead = Table[hash_key];

        nd.phoneNum =  phoneNum;             
        nd.name    =  name;            
        nd.age = age;

        add_status =  AddNodeAscend ( L1, &nd );
        if ( add_status == 0 )    
            printf ( "Warning! Error while allocating node.\n" );

        Table[hash_key] = L1->LHead;

    }

    /*--- now dump the table ---*/

    for ( j = 0; j < 33; j++ ){
          chain_table[j] = 0;
	}
    for ( i = 0; i < TABLE_SIZE; i++ )
    {
        Link pcurr;     /* Node we're examining */

        pcurr = Table[i];             /* set to start of list */
        if ( pcurr == NULL )          /* skip empty slots */
            continue;
        else
        {
            int chain_len;

            for ( chain_len = 0; ; pcurr = pcurr->next )
            {
                memcpy ( &n, pcurr, sizeof ( struct Node ));

#ifdef LIST_WORDS
              /* Print each word and the count of occurrences */
                printf ( "%-20s  %-20s  %-5s\n",
                         ( (pND1) n.pdata)->phoneNum,
                         ( (pND1) n.pdata)->name,
                         ( (pND1) n.pdata)->age );
#endif
                chain_len += 1;


				if ( pcurr->next == NULL )
                    break;
            }

            if ( chain_len > 32 )
                 chain_len = 32;

            chain_table[chain_len] += 1;
        }
    }


#ifdef LIST_TABLE_STATS

    chains = 0;
    for ( i = 32; i > 0; i-- )
    {
        if ( chain_table[i] == 0 )
            continue;
        else
        {
            printf ( "%3d chains of length %2d\n",
                      chain_table[i], i );
            chains += chain_table[i];
        }
    }

    if ( chains != 0 )
    {
        printf ( "\n%d Nodes in %u chains\n\n",
                 L1->LCount, chains );

        printf ( "Size of hash table   = %u\n",
                    (unsigned) TABLE_SIZE );

        printf ( "Average chain length = %f\n",
                  L1->LCount / (double)chains );

        printf ( "Slot Occupancy       = %f \n",
                 ( (double)chains ) / TABLE_SIZE );

        printf ( "Load Factor          = %f \n",
                 ( (double)L1->LCount ) / TABLE_SIZE );
    }
    else
        printf ( "Error! No chains found.\n" );
#endif

    while(1)
    {
        Link pcurr; 
        printf("please input you want to search...\n");
        scanf("%s" ,phoneNum);
        hash_key = (unsigned int) ElfHash ( phoneNum );
        hash_key %= TABLE_SIZE;

        pcurr = Table[hash_key];
        if (pcurr == NULL)
        {
            printf("Did not find\n");
            printf("=====================\n");
            continue;
        }
        else
        {
            for ( ; ; pcurr = pcurr->next )
            {
                memcpy ( &n, pcurr, sizeof ( struct Node ));
                // if (*(((pND1)n.pdata)->phoneNum) == *phoneNum)
                if (strcmp(((pND1)n.pdata)->phoneNum, phoneNum) == 0)
                {
                    printf("this is you want...\n");
                    printf ( "%-20s  %-20s  %-5s\n",
                         ( (pND1) n.pdata)->phoneNum,
                         ( (pND1) n.pdata)->name,
                         ( (pND1) n.pdata)->age );
                    printf("=====================\n");
                    break;
                }
                if ( pcurr->next == NULL )
                {
                    printf("Did not find\n");
                    printf("=====================\n");
                    break;
                }
            }
        }
    }
	system("pause");
    return ( EXIT_SUCCESS );
}

你可能感兴趣的:(哈希表的例子)