#c #list #hash
#c #Список #хэш
Вопрос:
Я следовал руководству по хэш-таблицам, и я создал этот код ниже. Проблема в том, что когда я пытаюсь вставить значения, у меня получается, но если я печатаю таблицу, кажется, что списки расположены в обратном порядке.
Сначала я подумал, что передаю неправильное значение функции 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", amp;size);
scanf("%d", amp;a);
scanf("%d", amp;b);
hash_t* table = CreateTable(size);
int i, x;
for (i=0; i<size; i ) {
scanf("%d", amp;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
Что может быть не так?
Заранее спасибо
P.S. Извините за мой плохой английский
Редактировать: Я думаю, что, возможно, в функции Insert я не разделяю случаи, в которых список пуст или нет. Я прав?
Комментарии:
1. это то, как вы вставляете: вы делаете текущий список
next
элементом списка, который вы вставляете2. @Ben, спасибо, я пытаюсь выполнить вставку в конце прямо сейчас
Ответ №1:
Из вашей функции insert:
list->value = x;
list->next = hashtable->table[hashval];
hashtable->table[hashval] = list;
вы назначаете list-> next в качестве текущего списка, а затем назначаете запись хэш-таблицы в качестве вашего вновь созданного списка. Это вставка в начале.
Ваш список построен следующим образом (отображается только таблица [0]):
0 -> 3
0 -> 18 3
0 -> 98 18 3
Комментарии:
1. Спасибо! Я пытаюсь исправить это сейчас!
2. Я пытаюсь что-то подобное, но, похоже, не работает: pastebin.com/fWZNhj61
3. Возможно, вам также придется явно установить для вашего нового tail значение null. Что заставляет вас думать, что это не работает? происходит ли ошибка segfault?
4. Я добавил list-> next = NULL; но я думаю, что проблема в моем первом условии (list == null), потому что мой вывод представляет собой пустой список, поэтому он не добавляет ни одного элемента
5. Кажется, я нашел это: ваш цикл for, вы запускаете его в своем новом списке? Вы хотите запустить его в списке в хэш-таблице. Это,
index = hashtable->table[hashval]