Goにおけるリンクリストの実装
Daniel Hayes
Full-Stack Engineer · Leapcell

Key Takeaways
- Goにおけるリンクリストは、より深い理解のためにゼロから実装することも、Goの
container/list
パッケージを使用することもできます。 - 単方向リンクリストの手動実装には、効率的な挿入と削除のためのノード参照の管理が含まれます。
- Goの標準ライブラリは、一般的な操作のための便利なメソッドを持つ双方向リンクリストを提供します。
リンクリストは、コンピュータサイエンスにおける基本的なデータ構造であり、各要素(ノードと呼ばれる)はデータと、シーケンス内の次のノードへの参照(またはリンク)を含みます。配列とは異なり、リンクリストは要素をメモリ内に連続して格納しません。代わりに、各ノードが次を指しており、データ構造全体を再編成することなく、効率的な挿入および削除操作が可能です。
リンクリストの種類
リンクリストにはいくつかの種類があります。
-
単方向リンクリスト: 各ノードはデータと、次のノードへの参照を含みます。
-
双方向リンクリスト: 各ノードはデータ、次のノードへの参照、および前のノードへの参照を含みます。
-
循環リンクリスト: 最後のノードが最初のノードを指し、円を形成します。
Goでの単方向リンクリストの実装
Goの標準ライブラリには、双方向リンクリストを実装するcontainer/list
パッケージが用意されています。ただし、単方向リンクリストをゼロから実装する方法を理解することで、Goにおけるポインタとメモリ管理についてより深い洞察を得ることができます。
ノード構造の定義
単方向リンクリストの各ノードは、整数値と次のノードへの参照を保持します。
type Node struct { data int next *Node }
リンクリスト構造体の定義
リンクリスト自体は、ヘッドノードへの参照を維持し、その長さを追跡します。
type LinkedList struct { head *Node length int }
先頭への挿入
リストの先頭に新しいノードを挿入するには:
func (l *LinkedList) InsertAtHead(data int) { newNode := &Node{data: data, next: l.head} l.head = newNode l.length++ }
末尾への挿入
リストの末尾に新しいノードを挿入するには:
func (l *LinkedList) InsertAtTail(data int) { newNode := &Node{data: data} if l.head == nil { l.head = newNode } else { current := l.head for current.next != nil { current = current.next } current.next = newNode } l.length++ }
ノードの削除
その値でノードを削除するには:
func (l *LinkedList) Delete(data int) { if l.head == nil { return } if l.head.data == data { l.head = l.head.next l.length-- return } current := l.head for current.next != nil && current.next.data != data { current = current.next } if current.next != nil { current.next = current.next.next l.length-- } }
リストのトラバース
リストをトラバースして出力するには:
func (l *LinkedList) PrintList() { current := l.head for current != nil { fmt.Println(current.data) current = current.next } }
Goのcontainer/list
パッケージの使用
実用的なアプリケーションでは、Goのcontainer/list
パッケージは、双方向リンクリストの堅牢な実装を提供します。
package main import ( "container/list" "fmt" ) func main() { l := list.New() l.PushBack(1) l.PushBack(2) l.PushFront(0) for e := l.Front(); e != nil; e = e.Next() { fmt.Println(e.Value) } }
これは以下を出力します。
0
1
2
container/list
パッケージは、すぐに使用できる双方向リンクリストを提供し、双方向トラバーサル機能により特定の操作でより効率的になります。
結論
Goでリンクリストを実装すると、ポインタと動的データ構造に関する貴重な経験が得られます。Goの標準ライブラリはcontainer/list
パッケージを介して双方向リンクリストを提供しますが、基盤となる実装の詳細を理解することで、開発者はそのようなデータ構造をいつ、どのように効果的に使用するかについて、情報に基づいた決定を下すための知識を得ることができます。
FAQs
リンクリストは、メモリを再割り当てせずに効率的な挿入と削除を提供します。
新しいノードを作成し、そのnext
を現在のヘッドを指すようにし、ヘッドを新しいノードに更新します。
簡略化された操作を備えた、堅牢な組み込みの双方向リンクリストが必要な場合。
Goプロジェクトのホスティングには、Leapcellをお選びください。
Leapcellは、Webホスティング、非同期タスク、Redisのための次世代サーバーレスプラットフォームです。
多言語サポート
- Node.js、Python、Go、またはRustで開発します。
無制限のプロジェクトを無料でデプロイ
- 使用量のみを支払い — リクエストも料金もありません。
比類のないコスト効率
- アイドル料金なしの従量課金制。
- 例:25ドルで、平均応答時間60ミリ秒で694万リクエストをサポートします。
合理化された開発者エクスペリエンス
- 簡単なセットアップのための直感的なUI。
- 完全に自動化されたCI/CDパイプラインとGitOps統合。
- 実用的な洞察を得るためのリアルタイムのメトリクスとロギング。
簡単なスケーラビリティと高性能
- 高い同時実行性を簡単に処理するための自動スケーリング。
- 運用上のオーバーヘッドはゼロ — 構築に集中するだけです。
ドキュメントで詳細をご覧ください。
Xでフォローしてください:@LeapcellHQ