第11章第15题完整代码(cpp) (Powered by biggates)

/// 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("散列值/t/t数据内容/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("/n/n函数createHashTable中的switch语句处理有误,需要修正!/n/n");

                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("/n/n函数insertIntoChain中的oriNode值为空,需要修正!/n/n");

        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;

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值