2017-11-12 6 views
1

CでHashTableを作成しようとしていますが、各 'bucket'はLinkedListへのポインタです。つまり、LinkedListポインタの配列を作成する必要があります。C - LinkedListポインタの配列を作成しよう

今のところ、SomeHashTable->Buckets[i]は、非ポインタLinkedListを返しています。私はどこでも答えを探していて、何も見つけられません。おそらく私は何かを見過ごしているのだろうか?私は下に私の現在のコードを与えました。

HashTable.h

#include "LinkedList.h" 

typedef struct HashTable 
{ 
    LinkedList* Buckets[1009]; 
} HashTable; 

//Creates new hashtable 
HashTable* HashTable_new(); 

//Hashes and adds a new entry 
void HashTable_add(HashTable* Table, int data); 

HashTable.c

#include "HashTable.h" 
HashTable* HashTable_new() 
{ 
    HashTable* newTable = (HashTable*)malloc(sizeof(HashTable)); 
    newTable->Buckets = malloc(1009 * sizeof(LinkedList*)); 

    //Create linked lists 
    for (int i = 0; i < 1009; i++) 
    { 
    newTable->Buckets[i] = LinkedList_new(); 
    } 

    return newTable; 
} 

void HashTable_add(HashTable* Table, int data) 
{ 
    int index = data % 1009; 

    //Get bucket to hash to 
    LinkedList* BucketHead = (Table->Buckets[index]); 
    //Hash it iiinnnn real good 
    LinkedList_add_at_end(BucketHead, data); 
} 

参照のためのリンクリストの構造体:

typedef struct LinkedListNode { 
    int data; 
    struct LinkedListNode *next; 
    struct LinkedListNode *prev; 
} LinkedListNode; 

typedef struct LinkedList { 
    struct LinkedListNode *first; 
    struct LinkedListNode *last; 
} LinkedList; 
+0

なぜあなたは 'Buckets' - >' newTable-> Buckets = malloc(1009 * sizeof(LinkedList *));にメモリを割り当てていますか? 'Buckets'は既に' LinkedList * '型の' 1009'要素の配列です。 –

+0

よく読んだ[永遠にConfuzzled - ハッシュテーブル](http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_hashtable.aspx)。読書の価値がある。もう1つはYale [C/HashTables](http://www.cs.yale.edu/homes/aspnes/pinewiki/C(2f)HashTables.html?highlight =%28CategoryAlgorithmNotes%29)です。どちらも参考になります。お気に入りの[ハッシュテーブルのコーディング](http://www.sparknotes.com/cs/searching/hashtables/section3.rhtml) –

+0

バケットの*二重リンクリスト*を使用するための説明できない目的がない限り、それは一般的に一方通行(例:単独リンク*実装)初期充填または再ハッシュ化では、ターゲットの下に*負荷係数*を維持するために二重リンクを利用することはありません(通常は '.7' OKです) –

答えて

0

HSさんのコメントがあり、言及したよう必要ないバケット配列を静的に動的に割り当てます。

このライン:

newTable->Buckets = malloc(1009 * sizeof(LinkedList*)); 

はあなたが望むものはおそらくないが、静的に割り当てられた配列へのポインタを上書きしています。スケーラビリティのために、私は静的配列を捨てて、malloc()を使用します。あなたがそうのように、バケット配列のサイズを指定するために)(HashTable_newに引数を使用することができますその方法:newTable->バケツがLinkedListの(LinkedListのへのポインタへのポインタとして割り当てられていることを

HashTable* HashTable_new(int nBuckets) 
{ 
    HashTable* newTable = (HashTable*)malloc(sizeof(HashTable)); 
    newTable->Buckets = malloc(nBuckets * sizeof(LinkedList*)); 
    newTable->nBuckets = nBuckets; 

    //Create linked lists 
    for (int i = 0; i < nBuckets; i++) 
    { 
    newTable->Buckets[i] = LinkedList_new(); 
    } 

    return newTable; 
} 

お知らせ* *)。あなたは[]バケットのサイズに追跡する必要があり、その次のように構造体に変数を追加します:

typedef struct HashTable 
{ 
    int nBuckets; 
    LinkedList **Buckets; 
} HashTable; 

あなたがいる限りLinkedList_new()の戻り値の型は、LinkedListの*であると良いことがあり、あなたが終わったらそれをすべて解放することを忘れないでください。

+0

ありがとう!今働こうとしているようだ。私はなぜあなたがLL *にapposedとしてmalloc'd nBuckets * LL **を疑問に思っています。バケットはリンクされたリストへのポインタであるべきではありませんか?ダブルポインターではない? –

+0

あなたは完全に正しいです。私はそれを反映する答えを編集しました。 malloc()はvoid *を返すので、ポインターは通常ダブルポインターと同じサイズであるため、機能的な違いはないため、いずれの方法でも動作します。 –