Files
hello-algo/ja/docs/chapter_data_structure/summary.md
T
Yudong Jin 7257641e0e Retranslate the complete Japanese online edition from Chinese (#2008)
* Retranslate the complete Japanese online edition from Chinese

* Fit Japanese homepage labels and localize heading permalinks

* Point Japanese contribution instructions to the Japanese preview

* Replace locale conditionals with multilingual UI tables
2026-10-30 02:12:26 +08:00

67 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# まとめ
### 要点の振り返り
- データ構造は論理構造と物理構造の二つの観点で分類できます。論理構造は要素間の関係、物理構造はメモリ内での格納方法を表します。
- 主な論理構造には、線形、木、ネットワークがあります。通常は線形(配列、連結リスト、スタック、キュー)と非線形(木、グラフ、ヒープ)に分けます。ハッシュテーブルの実装には、線形と非線形の両方が含まれる場合があります。
- プログラムの実行時、データはメモリに保存されます。各領域にはメモリアドレスがあり、プログラムはそれを使ってデータにアクセスします。
- 物理構造は主に、連続した領域への格納(配列)と分散した領域への格納(連結リスト)に分けられます。すべてのデータ構造は、この二つまたはその組み合わせで実装されます。
- 基本データ型には、整数の `byte`、`short`、`int`、`long`、浮動小数点の `float`、`double`、文字の `char`、ブールの `bool` があります。値の範囲は、使用する空間と表現方法で決まります。
- 符号絶対値表現、1 の補数表現、2 の補数表現は、数値を符号化する三つの方法で、相互に変換できます。整数の符号絶対値表現では、最上位ビットが符号、残りが数の値を表します。
- 整数はコンピュータ内で 2 の補数表現で保存されます。正負の加算を同じ方法で処理でき、減算専用のハードウェア回路が不要になり、正負のゼロという曖昧さもなくなります。
- 浮動小数点数の符号化は、符号 1 ビット、指数 8 ビット、仮数 23 ビットで構成されます。指数部があるため整数よりはるかに広い範囲を表せますが、精度を犠牲にします。
- ASCII は初期の英語用文字集合で、長さは 1 バイト、128 文字を収録しています。GBK はよく使われる中国語の文字集合で、2 万字以上の漢字を収録しています。Unicode は、世界の各言語の文字を収めた完全な文字集合の標準を目指し、符号化方式の違いによる文字化けの解消を図っています。
- UTF-8 は最も普及した Unicode の符号化方式で、汎用性に優れています。可変長で拡張性が高く、記憶領域を効率よく使えます。UTF-16 と UTF-32 は固定長の符号化方式です。中国語では UTF-16 の方が UTF-8 より少ない空間で済みます。Java や C# などは標準で UTF-16 を使います。
### Q & A
**Q**:ハッシュテーブルに、線形と非線形のデータ構造の両方が含まれるのはなぜですか。
ハッシュテーブルの基盤は配列ですが、衝突の解決には「チェイン法」(後の「ハッシュ衝突」の節で説明します)を使うことがあります。各バケットが連結リストを指し、その長さがしきい値を超えると、木(通常は赤黒木)に変換する場合があります。
格納の観点では、基盤となる配列の各バケットには、一つの値、連結リスト、木のいずれかが入る可能性があります。そのため、線形の構造(配列、連結リスト)と非線形の構造(木)が同時に含まれる場合があります。
**Q**:`char` 型の長さは 1 バイトですか。
`char` の長さは、言語が使う符号化方式で決まります。たとえば Java、JavaScript、TypeScript、C# は UTF-16(Unicode コードポイントを保存する方式)を使うため、`char` の長さは 2 バイトです。
**Q**:配列で実装したデータ構造を「静的」と呼ぶのは曖昧ではありませんか。スタックのプッシュやポップは「動的」な操作です。
スタックのデータ操作は確かに動的ですが、構造自体は「静的」(長さが固定)です。配列を使った構造で要素を動的に追加・削除できても、容量は固定されています。確保済みの容量を超えたら、より大きな配列を作り、元の内容をコピーする必要があります。
**Q**:スタックやキューを作るときに大きさを指定していないのに、なぜ「静的データ構造」なのですか。
高水準言語では、初期容量の設定をクラスの内部で自動的に行うため、自分で指定する必要はありません。たとえば Java の `ArrayList` の初期容量は通常 10 です。容量拡張も自動で行われます。詳しくは後の「リスト」の節で説明します。
**Q**:符号絶対値表現から 2 の補数表現への変換は「反転してから 1 を足す」ので、逆変換は「1 を引いてから反転する」はずです。逆変換にも「反転してから 1 を足す」が使えるのはなぜですか。
相互変換は、実際には「補数」を求める操作だからです。まず補数を定義します。$a + b = c$ なら、$a$ は $b$ の $c$ に対する補数であり、逆に $b$ も $a$ の $c$ に対する補数です。
$n = 4$ ビットの二進数 $0010$ を、符号ビットを考慮せず符号絶対値表現とみなすと、対応する 2 の補数は「反転してから 1 を足す」ことで得られます。
$$
0010 \rightarrow 1101 \rightarrow 1110
$$
元の値と補数の和は $0010 + 1110 = 10000$ です。つまり、補数 $1110$ は、元の値 $0010$ の $10000$ に対する「補数」です。**「反転してから 1 を足す」は、実際には $10000$ に対する補数を求める操作なのです**。
では、$1110$ の $10000$ に対する「補数」は何でしょうか。同じく「反転してから 1 を足す」で求められます。
$$
1110 \rightarrow 0001 \rightarrow 0010
$$
つまり、元の表現と 2 の補数表現は、互いに $10000$ に対する「補数」なので、どちらへの変換も同じ操作(反転してから 1 を足す)で行えます。
もちろん、$1110$ から元の表現を求めるには、「1 を引いてから反転する」という逆操作も使えます。
$$
1110 \rightarrow 1101 \rightarrow 0010
$$
「反転してから 1 を足す」と「1 を引いてから反転する」は、どちらも $10000$ に対する補数を求める操作であり、同等なのです。
本質的には、「反転」は $1111$ に対する補数を求める操作です(常に `元の値 + 1 の補数 = 1111` が成り立ちます)。さらに 1 を足して得る 2 の補数は、$10000$ に対する補数になります。
ここでは $n = 4$ を例にしましたが、任意のビット数の二進数に一般化できます。