第11章第15题完整代码

/// 11_15.cpp: 编写对一组关键字,利用链地址法解决冲突,

/// 散列函数为H(k),写出在此散列表中插入、删除元素的算法

 

#include "stdafx.h"

#include <stdlib.h>

#include <stdlib.h>

#include <conio.h>

#include <time.h>

#include "Chapter11.h"

 

void printDataType(const dataType data)

{

    printf("%c", data);

}

 

void printKeyType(const keyType key)

{

    printf("%2d", key);

}

 

keyType getHash(const dataType data)

//从data算出hash值的函数

//使用简单的除留余数法

{

    keyType hash = EMPTY_KEY;

 

    hash = data % MODDER;

 

    return hash;

}

 

hashChain* newHashChain()

//分配新的hashChain节点的函数

{

    hashChain* head = NULL;

 

    head = (hashChain*)malloc(sizeof(hashChain));

 

    if(head == NULL)

    {

        printf("分配空间出错!n");

        exit(1);

    }

 

    initializeHashChain(head);

 

    return head;

}

 

void initializeHashChain(hashChain* chain)

//初始化一个hashChain节点的函数

{

    chain->data = EMPTY_CHAR;

    chain->pNext = NULL;

}

 

void initializeHashNodes(hashNode* head, const int size)

//初始化一个hashNode表的函数

{

    for (int i = 0; i < size; i++)

    {

        (head + i)->key = i;

        (head + i)->pChain = NULL;

    }

}

 

hashNode* chainSearch(hashNode* head, const int size, const dataType data)

//在以head为首,长度为size的hashNode表中查找key,并返回其hashNode地址的函数

//不成功则返回NULL

{

    hashChain* chain = NULL;

 

    hashNode* temp = head;

 

    if (head == NULL)

    {

        return NULL;

    }

 

    keyType tempKey = getHash(data);

 

    if (tempKey >= size)

    {

        return NULL;

    }

 

    for (int i = 0; i < size; i++)

    {

        if ( (head + i)->key == tempKey )

        {

            return (head + i);

        }

    }

 

    return NULL;

    //在整个散列表中都找不到所需要的散列数据,返回NULL

}

 

void printHashTable(hashNode* head, const int size)

//显示以head为首,长度为size的hashNode表的内容的函数

{

    hashNode* tempHead = head;

 

    if (tempHead == NULL)

    {

        printf("该散列表没有内容!n");

        return;

    }

 

    printf("散列表的内容是:n");

    printf("散列值tt数据内容n");

    //表头

 

    hashChain* tempChain = NULL;

 

    for (int i = 0; i < size; i++)

    {

        tempHead = head + i;

        tempChain = tempHead->pChain;

 

        printf("  ");

 

        printKeyType(tempHead->key);

 

        printf("t");

 

        while (tempChain != NULL)

        {

            printf("->");

 

            printDataType(tempChain->data);

 

            printf("t");

 

            tempChain = tempChain->pNext;

        }

 

        printf("n");

    }

}

 

void freeHashTable(hashNode* head, const int size)

//释放以head为首,长度为size的hashNode表所占用的空间的函数

{

    hashNode* tempHead = head;

    hashChain* r = NULL;

    hashChain* s = NULL;

 

    for (int i = 0; i < size; i++)

    {

        r = (tempHead + i)->pChain;

 

        if ( r == NULL)

        {

            continue;

        }

 

        s = r->pNext;

 

        if (s == NULL)

        {

            free(r);

            r = NULL;

            continue;

        }

 

        while (s != NULL)

        {

            free(r);

            r = NULL;

 

            r = s;

            s = s->pNext;

        }

    }

}

 

 

hashNode* createHashTable(hashNode* head, const int size, const int totalNumber)

//建立初始长度为size的散列表,并返回其首地址的函数

//不成功则返回NULL

{

    if (head == NULL)

    {

        head = (hashNode*)malloc( sizeof(hashNode) * size);

    }

 

    srand( (unsigned)time(NULL) );

 

    char tempData = ‘a’;

    char tempBase = ‘a’;

    int random = 0;

 

    for (int i = 0; i < totalNumber; i++)

    {

        do

        {

            random = rand();

 

            switch(random % 3)

            {

            case 0:

                tempBase = ‘!’;

                //’!’是能显示的ASCII码的最小值

                break;

 

            case 1:

                tempBase = ‘a’;

                break;

 

            case 2:

                tempBase = ‘A’;

                break;

 

            default:

                printf("nn函数createHashTable中的switch语句处理有误,需要修正!nn");

                break;

            }

 

            tempData = ( random % 31 ) + tempBase;

            //在tempBase基础上加一个0到30的数作为数据

            //之所以用30是因为’A’的ASCII码是97,而

            //char类型的上限是127

 

        }

        while(insertIntoChain(head, size, tempData) == NULL);

    }

 

 

    return head;

}

 

hashChain* insertIntoChain(hashNode* head, const int size, const dataType source)

//在以head为首,长度为size的hashNode表中插入值为source的节点的函数

//成功则返回其地址,否则返回NULL

//如果未进行插入,则返回NULL

{

    hashNode* oriNode = chainSearch(head, size, source);

    hashChain* newChain = newHashChain();

    newChain->data = source;

 

    hashChain* temp = NULL;

 

    if (oriNode == NULL)

    //不做任何处理

    {

        printf("nn函数insertIntoChain中的oriNode值为空,需要修正!nn");

        return NULL;

    }

 

    if (oriNode->pChain == NULL)

    //chainNodes中不含有key和source相匹配的数据

    //只需直接将chain连接到相应的key处即可返回

    {

        oriNode->pChain = newChain;

    }

    else

    //chainNodes中已经含有和key和source相匹配的数据

    //需要将newChain插入oriNode->pChain

    {

        temp = oriNode->pChain;

        while (temp != NULL)

        {

            if (temp->data == source)

            {

                free(newChain);

                return NULL;

                //已存在source,不进行操作,返回NULL

            }

            temp = temp->pNext;

        }

 

        temp = oriNode->pChain;

        oriNode->pChain = newChain;

        newChain->pNext = temp;

    }

 

    return newChain;

}

 

int main(int argc, char* argv[])

{

    hashNode hashNodes[HASH_TABLE_LENGTH];

 

    hashNode* head = hashNodes;

 

    initializeHashNodes( head, HASH_TABLE_LENGTH );

    //对散列表进行初始化

 

    int totalNumber = 0;

    char ch = ‘y’;

 

    while(ch == ‘y’ || ch == ‘Y’)

    {

        do

        {

            printf("请输入散列表中的元素数(现在散列表的总长度是%d)n为了尽可能地减少出错机会,请输入一个不大于90的正整数:"

                    , HASH_TABLE_LENGTH);

 

            scanf("%2d", &totalNumber);

        }

        while(totalNumber < 0 || totalNumber > 90);

 

        head = createHashTable(head, HASH_TABLE_LENGTH, totalNumber);

 

        printHashTable(head, HASH_TABLE_LENGTH);

 

        printf("n还继续吗(请输入y以继续)?");

 

        ch = getche();

 

        printf("n");

 

        freeHashTable(head, HASH_TABLE_LENGTH);

 

    }

    return 0;

}

Advertisements

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s

%d 博主赞过: