Pythonで連結リスト(リンクリスト)をクラスで実装する方法

スポンサーリンク

Pythonのリンクリストは、C/C++時代から人気を保ち続けている興味深い抽象データ型の1つです。

今回は、Pythonでリンクリストをゼロから実装する方法を学びます。

スポンサーリンク

リンクリストとは

リンクリストは、各要素が独立したオブジェクトである線形データ構造です。

リンクリストの要素は、配列とは異なり、メモリ内に一緒に格納されません。

リンクリストの各要素は、その次の要素を指しています。

ここでいうポイントとは、各要素に次の要素のアドレスが格納されていることを意味します。

リンクリストを巡回する際には、このポインターを利用して、あるノードから次のノードへジャンプします。

各リンクリストには、考慮しなければならない要素が2つあります。

  • ノード – ノードクラスを作成することにより、ノードを処理します。
  • ノード間の接続 – Pythonの変数とリストでこれを処理します。

Pythonでリンクリストを作るには?

Pythonでリンクリストを作成する手順を説明します。

Node クラスの作成

独自のリンクリストを作成するには、ノードクラスを定義する必要があります。

ノード・クラスを定義する前に、そのクラスがどのようなフィールドを持つべきかを考える必要があります。

リンクリストのノードは2つのものを格納することになっています。

  1. データ
  2. 次のノードのアドレス

この2つのフィールドを持つノード・クラスを定義してみましょう。

class Node(object):
 
    def __init__(self, data=None, next_node=None):
        self.data = data
        self.next_node = next_node

Linked-List クラスの作成

リンクリストを作成するために、空のノードを初期化するクラスをもうひとつ作ってみましょう。

class LinkedList(object):
    def __init__(self, head=None):
        self.head = head

このクラスには、いくつかの重要な関数が用意されています。

それぞれのクラスの目的と定義を確認しましょう。

1. リストを表示する関数

リンクリストを印刷する関数を書いてみましょう。

リンクリストを印刷するには、リスト全体を走査して、各ノードのデータを印刷し続ける必要があります。

def printList(self):
        temp = self.head
        while (temp):
            print (temp.data, " -> ", end = '')
            temp = temp.next_node
        print("")

2. リストの大きさを取得する

リンクリストのサイズを返す関数を書いてみましょう。

サイズを計算するためには、リスト全体を走査し、カウンターを保持する必要があります。

def size(self):
     current = self.head
     count = 0
     while current:
        count += 1
        current = current.next_node
     return count

この関数はリンクリストのサイズを返します。

3. 新しいノードを先頭に挿入する

新しいノードを先頭に挿入する関数を書いてみましょう。

def insert_at_head(self, data):
      new_node = Node(data)
      new_node.next_node = self.head
      self.head = new_node

これはデータを持つ新しいノードを作り、それをheadの前に追加します。

そして、リンクリストの先頭をこの新しいノードに向ける。

4. 次のノードの取得

次のノードを取得するための関数を以下に示す。

def get_next_node (self,node):
     return node.next_node.data

新しいリンクドリストを作成する

上記で作成したクラスを使って、main関数を書き、リンクリストを作成しましょう。

llist = LinkedList()

このコードでは、llist オブジェクトを空のノードで初期化しています。

1. ノードの追加

このノードにデータを追加してみましょう。

llist.head = Node(1)

リンクリストのための他のノードをいくつか作成します。

s = Node(2)
t = Node(3)

2. ノード間のリンクの作成

個々のノード間のリンクを作成することは、リンクリストを作成する上で最も重要な部分です。

リンクの作成には、.NET Frameworkを使用します。

llist.head.next_node = s
s.next_node = t

3. リストのノードを印刷する

リストが正常に作成されたかどうかを確認するために、print機能を使用することができます

llist.printList()

結果を出力すると、以下の様になります。

1  -> 2  -> 3

4. リストの大きさを出力する

リストの大きさを出力するには、上で書いた size 関数を呼び出します。

print(llist.size())

結果は以下の通りです。

3

5. 新しいノードを挿入する

上の関数を使って、リンクリストの先頭にデータを挿入してみましょう。

llist.insert_at_head(5)

リストを印刷して検証してみましょう。

llist.printList()

結果は以下の通りです。

5  -> 1  -> 2  -> 3

6. 次のノードを取得する

次のノードを取得します。

print(llist.get_next_node(s))

結果を出力すると、以下の様になります。

3

Pythonによるリンクリストの完全な実装

完全な実装は以下の通りです。

class Node(object):
 
    def __init__(self, data=None, next_node=None):
        self.data = data
        self.next_node = next_node
 
 
class LinkedList(object):
    def __init__(self, head=None):
        self.head = head
 
    def size(self):
     current = self.head
     count = 0
     while current:
        count += 1
        current = current.next_node
     return count
       
    def printList(self):
        temp = self.head
        while (temp):
            print (temp.data, " -> ", end = '')
            temp = temp.next_node
        print("")
 
    def insert_at_head(self, data):
      new_node = Node(data)
      new_node.next_node = self.head
      self.head = new_node
 
    def get_next_node (self,node):
      return node.next_node.data
 
 
if __name__=='__main__':
   
     
    llist = LinkedList()
   
    llist.head = Node(1)
    s = Node(2)
    t = Node(3)
    llist.head.next_node = s;
    s.next_node = t
    llist.printList()
    print(s.data)
    print(llist.size())
    print(llist.get_next_node(s))
    llist.insert_at_head(5)
    llist.printList()

まとめ

この記事では、Pythonでのリンクリストの実装を取り上げました。

私たちはゼロから独自のリンクリストを作成し、リストを表示し、リストのサイズを取得し、先頭に挿入を行うためのいくつかの追加関数を書きました。

タイトルとURLをコピーしました