链式哈希表没有给出正确的输出

时间:2015-04-26 21:07:10

标签: c arrays hash linked-list hashtable

我目前的问题是找到代码中断的地方时遇到了麻烦。我得到输出,没有编译错误,但输出是错误的和不完整的,因为它看起来没有输出它应该的一切。

以下是代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define TABLE_SIZE 8

typedef struct stItem item;
struct stItem {
    int key;
    item *next;
};

void init(item * H[]) {

    int i = 0;
    for (i; i < TABLE_SIZE; i++)
        H[i] = NULL;
}

int h(int k) {

    // this does not work at all (but from exercise description), replaced with temp code

    /*
    int m = TABLE_SIZE;
    int A = ( sqrt(5.0) - 1) / 2;

    return m * (k * A % 1);
    */

    return k % TABLE_SIZE;
}

void insert(int key, item * H[]) {

    int keyHashed = h(key);

    if (H[keyHashed] == NULL) {

        printf("hashkey: %d (%d)\n", keyHashed,key);

        item * temp = malloc(sizeof(item));
        temp->key = key;
        temp->next = NULL;

        H[keyHashed] = temp;

        free(temp);
    }

    else {

        printf("hashkey: %d (%d) (duplicate)\n", keyHashed,key);

        item * temp = malloc(sizeof(item));
        temp->key = NULL;
        temp->next = H[keyHashed]->next;

        while (temp->key != NULL) {
            temp = temp->next;
        }

        temp->key = key;
        temp->next = NULL;
    }
}

int search(int key, item * H[]) {

        int keyHashed = h(key);

        if (H[keyHashed] == NULL)
            return -1;

        else if (H[keyHashed]->key != key) {

            item * temp = malloc(sizeof(item));
            temp->key = NULL;
            temp->next = H[keyHashed]->next;

            while (temp->key != key && temp != NULL)
                temp = temp->next;

            if (temp->key == key) {
                free(temp);
                return keyHashed;
            }

            else {
                free(temp);
                return -1;
            }
        }

        else
            return keyHashed;
}

void printHash(item * H[]) {

    printf("\nTable size: %d\n", TABLE_SIZE);

    int i = 0;

    for (i; i < TABLE_SIZE; i++) {

        if (H[i] != NULL) {
            printf("i: %d          key: %d",i,H[i]->key);

            if (H[i]->next != NULL) {

                printf("chaining print\n");

                item * temp = malloc(sizeof(item));
                temp->key = NULL;
                temp->next = H[i]->next;

                while (temp->key != NULL) {
                    printf(" -> %d", temp->key);
                }

                printf("\n");
            }

            else
                printf("\n");
        }

        else
            printf("i: %d          key: none\n",i);
    }
}

void test() {

    // a)
    int array[7] = {111,10112,1113,5568,63,1342,21231};

    item *h[TABLE_SIZE];
    init(h);

    int i = 0;
    for (i; i < 7; i++)
        insert(array[i], h);

    // b)
    printHash(h);

    // c)
    printf("Search result for 1: %d", search(1, h));
    printf("Search result for 10112: %d", search(10112, h));
    printf("Search result for 1113: %d", search(1113, h));
    printf("Search result for 5568: %d", search(5568, h));
    printf("Search result for 337: %d", search(337, h));
}

int main() {
    test();
}

这是当前的输出:

hashkey: 7 (111)
hashkey: 0 (10112)
hashkey: 1 (1113)
hashkey: 0 (5568) (duplicate)
hashkey: 7 (63) (duplicate)
hashkey: 6 (1342)
hashkey: 7 (21231) (duplicate)

Table size: 8
i: 0          key: 5568
i: 1          key: 5568
i: 2          key: none
i: 3          key: none
i: 4          key: none
i: 5          key: none
i: 6          key: 21231
i: 7          key: 5568

Process returned -1073741819 (0xC0000005)   execution time : 0.572 s
Press any key to continue.

如您所见,搜索结果根本没有显示,并且哈希表完全没有问题。似乎有些数字不应该根据输出而且它根本不输出相同索引中的任何重复项。

编辑:insert()函数的当前状态:

void insert(int key, item * H[]) {

    int keyHashed = h(key);

    if (H[keyHashed] == NULL) {

        printf("hashkey: %d (%d)\n", keyHashed,key);

        item * temp = malloc(sizeof(item));
        temp->key = key;
        temp->next = NULL;

        H[keyHashed] = temp;
    }

    else {

        printf("hashkey: %d (%d) (duplicate)\n", keyHashed,key);

        item * temp = malloc(sizeof(item));
        temp->key = NULL;
        temp->next = H[keyHashed]->next;

        while (temp->next != NULL) {
            temp = temp->next;
        }

        item * temp2 = malloc(sizeof(item));
        temp->next = temp2;
        temp2->key = key;
        temp2->next = NULL;
    }
}

1 个答案:

答案 0 :(得分:2)

您的问题可能是free(temp);将其插入H后的问题。插入它时,您没有插入临时条目的副本,而是插入指向它的指针。当你然后free指针指向的内存时,它可以被任何后来的内存分配覆盖。

是的,C中的手动内存管理很痛苦。

然后你可能想再次看看你对重复的处理。您正在创建一个新条目并对其进行设置,但您实际上从未将该条目输入H,因此会忽略重复项。