質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
ハッシュ

ハッシュは、高速にデータ検索を行うアルゴリズムのことです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

1031閲覧

ハッシュテーブル構築

Giovannaaa

総合スコア10

ハッシュ

ハッシュは、高速にデータ検索を行うアルゴリズムのことです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2021/07/04 12:04

出力結果がこのように、初期に定義した-1の値が出る時と出ない時があります。なぜなのでしょうか?線形リストができていないのでしょうか?よろしくお願いします。
0 120 0x7ff974c059f0 0x7ff974c05a00
910 0x7ff974c05a00 0x0

1 -1 0x7ff974c05940 0x7ff974c05a10
411 0x7ff974c05a10 0x0

2 -1 0x7ff974c05950 0x0

3 -1 0x7ff974c05960 0x0

4 344 0x7ff974c059d0 0x7ff974c05a20
824 0x7ff974c05a20 0x0

5 -1 0x7ff974c05980 0x7ff974c05a40
435 0x7ff974c05a40 0x0

6 676 0x7ff974c059e0 0x7ff974c05a50
426 0x7ff974c05a50 0x0

7 -1 0x7ff974c059a0 0x0

8 -1 0x7ff974c059b0 0x7ff974c05a30
658 0x7ff974c05a30 0x0

9 -1 0x7ff974c059c0 0x7ff974c05a60
529 0x7ff974c05a60 0x0

C++

1#include <iostream> 2#include <cstdlib> 3using namespace std; 4#define HASH_NUM 10 //ハッシュデーブルの要素数m 5#define N 10 //入力データ数n 6 7struct CELL{ 8 int data; 9 CELL *next; 10}; 11 12int Hash(int); 13void add_hash_struct(CELL**,int); 14void show_hash_struct(CELL**); 15 16 17int main() 18{ 19 CELL *HashTable[HASH_NUM]; 20 21 for(int i = 0; i < HASH_NUM; i++){ 22 HashTable[i] = new CELL; 23 HashTable[i]->data = -1; 24 HashTable[i]->next = NULL; 25 } 26 27 srand((unsigned int)time(NULL)); 28 int x; 29 for(int i = 0; i < N; i++){ 30 x = rand() % 900 + 100; 31 add_hash_struct(HashTable,x); 32 x = 0; 33 } 34 35 show_hash_struct(HashTable); 36 37} 38 39int Hash(int x) 40{ 41 return x % HASH_NUM; 42} 43 44void add_hash_struct(CELL **HT,int x) 45{ 46 CELL *newcell = new CELL; 47 48 int key; 49 key = Hash(x); 50 51 while(HT[key]->next != NULL){ 52 HT[key] = HT[key]->next; 53 } 54 55 newcell->next = NULL; 56 HT[key]->next = newcell; 57 newcell->data = x; 58} 59 60void show_hash_struct(CELL **HT) 61{ 62 CELL *p = new CELL; 63 for(int i = 0; i < HASH_NUM; i++){ 64 cout << i << " " ; 65 while(HT[i] != NULL){ 66 cout << HT[i]->data << " " << HT[i] << " " << HT[i]->next << endl; 67 HT[i] = HT[i]->next; 68 } 69 cout << endl; 70 } 71}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

値-1のCELLは何のために入れてあるんですか?

投稿2021/07/04 12:54

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Giovannaaa

2021/07/04 13:01

リストの先頭と表したいので-1(適当な値)を入れています。
episteme

2021/07/04 13:05

末尾ならともかく、なんでそんなの必要なんですか?
Giovannaaa

2021/07/04 13:16

一応なにか値を入れとこうと思いました。消しときます。
episteme

2021/07/04 13:41

while(HT[key]->next != NULL){ HT[key] = HT[key]->next; } で、ここでリストの先頭を書き換えちゃっていいんですかね?
Giovannaaa

2021/07/04 14:25

リストの先頭を書き換えているとはどういうことなのでしょうか?
guest

0

ベストアンサー

add_hash_struct()HT[key]つまりHashTable[key]を書き換えてしまっているので、
HashTable[0]~HashTable[9]それぞれに対して2回以上追加した場合、最後の2つしか表示されません。

void add_hash_struct(CELL** HT, int x) { CELL* newcell = new CELL; int key; key = Hash(x); while (HT[key]->next != NULL) { HT[key] = HT[key]->next; // ここ }

書き換えたいのはHashTable[0]~HashTable[9]の末尾のNULLになっているnextでしょう?

diff

1void add_hash_struct(CELL **HT,int x) 2{ 3 CELL *newcell = new CELL; 4 5 int key; 6 key = Hash(x); 7 8+ CELL* lastCell = HT[key]; 9- while(HT[key]->next != NULL){ 10+ while(lastCell->next != NULL){ 11- HT[key] = HT[key]->next; 12+ lastCell = lastCell->next; 13 } 14 15 newcell->next = NULL; 16- HT[key]->next = newcell; 17+ lastCell->next = newcell; 18 newcell->data = x; 19}

show_hash_structでもHashTable[0]~HashTable[9]を書き換えてしまっていますが…

投稿2021/07/04 13:05

編集2021/07/04 13:35
SHOMI

総合スコア4079

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Giovannaaa

2021/07/04 13:15

解決するためのアドバイスを教えて欲しいです。
Giovannaaa

2021/07/04 13:15

よろしくお願いします。
Giovannaaa

2021/07/04 13:52

構築することができました。ありがとうございます。最後になのですが、前のwhile文ではなぜ書き換えてしまうのかあまり分からないです。また、新たにCELLを追加することでなぜ解決できるのでしょうか?良ければ教えてほしいです。すみません。
SHOMI

2021/07/04 14:23 編集

HTは配列HashTableの先頭ポインタなので、 HT[key] = HT[key]->next; で書き換わるのはHashTable[key]の内容そのものです。 一方、 CELL* lastCell = HT[key]; lastCell = lastCell->next; で書き換わるのは、 HT[key]の内容をコピーしたlastCellです。 main内で for (int i = 0; i < HASH_NUM; i++) { cout << "&HashTable[" << i << "]:" << &HashTable[i] << endl; } add_hash_struct内で CELL* lastCell = HT[key]; cout << "&last:" << &last << ",&HT[" << key << "]:" << &HT[key] << endl; とすれば &HashTable[0]~[9]と&HT[0]~[9]が同じアドレスであること、 &lastCellと&HT[key]が異なるアドレスであることが確認できます。
Giovannaaa

2021/07/04 14:37

丁寧なご回答ありがとうございます。理解することができました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問