散列表反向插入值[C]

时间:2014-07-03 17:34:05

标签: c list hash

我正在关注哈希表的教程,我在下面创建了这段代码。问题是,当我尝试插入值时,我成功了,但如果我打印表,似乎列表是相反的。

起初,我认为我将错误的值传递给函数 printhashtable(),但它似乎不是这样,因为它打印所有正确的元素,但相反。 如果,对于一个实例,我通过条件 i!= NULL 传递了列表的最后一个元素,我会得到一个空白的打印。

我现在的想法是,我以某种方式给出了尾指针,而'next'字段实际上是倒退。

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

int a;
int b;
int count_collisions;

// Linked list
typedef struct _list{
    int value;
    struct _list *next;
} list;


// Hash Table Structure
typedef struct _hash_t {
    int size; // Table Size
    list** table; // Table elements
} hash_t;


// Creating the HASH function
int hash(int x, int a, int b, int len) {
int h;
h=((((a*x)+b)%999149)%len);
return h;
}


// Creating the table
hash_t* CreateTable(int size) {

hash_t* newtab;

if (size < 1) return NULL; // This size is not valid

newtab = malloc(sizeof(hash_t));  // ALlocate memory for the table structure
if (newtab == NULL) return NULL; // Checking if the malloc went good

newtab->table = malloc(sizeof(list*)*size); // Allocating memory for the table
if (newtab->table == NULL) return NULL; // Checking if the malloc went good

int i;
for (i=0; i<size; i++) {
    newtab->table[i] = NULL; // Initialize the elements of the table
}

newtab->size = size; // Setting the size of the table

return newtab;
}


// Searching for a value
list* Search(int x, hash_t* hashtable) {

list* list;
int hashval = hash(x, a, b, hashtable->size);

if (hashtable == NULL) {
    return NULL;
}

for (list = hashtable->table[hashval]; // We start from the correct list, using the hash function
     list != NULL; list = list->next) {
    if (list->value == x) {
        return list;
    }
}

return NULL;
}


 // Insert a value
void Insert(int x, hash_t* hashtable) {

list* list;
int hashval = hash(x, a, b, hashtable->size);

list = malloc(sizeof(list)); // Allocate memory for the list
list->value = x;
list->next = hashtable->table[hashval];
hashtable->table[hashval] = list;

}


// Function that prints a list
void printList (list* list) {
struct _list* i;
for (i=list; i!= NULL; i = i->next) {
    printf("%d ", i->value);
}
}



// Function that prints hashtable
void printHashTable(hash_t* hashtable, int size) {
int i;
for (i=0; i<size; i++) {
    printf("\nPosition: %d | list: ", i);
    printList(hashtable->table[i]);
}

}



int main () {

int size;
scanf("%d", &size);
scanf("%d", &a);
scanf("%d", &b);

hash_t* table = CreateTable(size);
int i, x;
for (i=0; i<size; i++) {
    scanf("%d", &x);
    Insert(x, table);
}

printf("Hash Table created is: ");
printHashTable(table, size);

printf("\n");


return 0;
}

示例测试集:

输入:

5    // 5 elements
2    // a = 2
4    // b = 4
3    // h(3) = 0
12   // h(12) = 8
97   // h(97) = 8
18   // h(18) = 0
98   // h(98) = 0

输出

// hash table:
//  0 -> 3 18 98
// 1 -> NULL
// 2 -> NULL
// 3 -> NULL
// 4 -> NULL
// 5 -> NULL
// 6 -> NULL
// 7 -> NULL
// 8 -> 12 97
// 9 -> NULL

我在0和8得到的是:

0 -> 98 18 3
8 -> 97 12

可能有什么不对? 提前致谢 附:抱歉我的英文不好

编辑: 我想可能在插入函数中我没有将列表为空的情况分开。我是对的吗?

1 个答案:

答案 0 :(得分:1)

来自您的插入功能:

list->value = x;
list->next = hashtable->table[hashval];
hashtable->table[hashval] = list;

将list-&gt; next分配为当前列表,然后将哈希表条目指定为新制作的列表。这是头部的插入物。

您的列表就像(仅显示表[0])一样构建:

0 -> 3
0 -> 18 3
0 -> 98 18 3