Pythonで循環リンクリストの中央に新しいノードを挿入する方法
循環リンクリスト(Circular Linked List)の中央に新しいノードを挿入するには、まず「Node」クラスを作成する必要があります。このクラスには2つの属性が定義されます。1つ目はノードが保持するデータ、2つ目はリンクされた次のノードへの参照です。
循環リンクリストの特徴
循環リンクリストでは、先頭(head)と末尾(tail)が互いに隣接しており、リスト全体が環状につながっています。そのため、末尾のノードには「NULL」が存在せず、最後のノードのnextが再び先頭を指し示す構造になっています。
続いて、初期化関数を持つ別のクラスを作成します。このクラスでは、リストの先頭が「None」で初期化されます。さらに、リストの中間へノードを追加するメソッドや、ノードの値を出力するメソッドなど、複数の操作用メソッドを定義していきます。
以下に具体的な実装例を示します。
サンプルコード
class Node:
def __init__(self, data):
self.data = data
self.next = None
class list_creation:
def __init__(self):
self.head = Node(None)
self.tail = Node(None)
self.head.next = self.tail
self.tail.next = self.head
self.size = 0
def add_data(self, my_data):
new_node = Node(my_data)
if self.head.data is None:
self.head = new_node
self.tail = new_node
new_node.next = self.head
else:
self.tail.next = new_node
self.tail = new_node
self.tail.next = self.head
self.size = self.size + 1
def add_in_between(self, my_data):
new_node = Node(my_data)
if self.head == None:
self.head = new_node
self.tail = new_node
new_node.next = self.head
else:
count = (self.size // 2) if (self.size % 2 == 0) else ((self.size + 1) // 2)
temp = self.head
for i in range(0, count):
curr = temp
temp = temp.next
curr.next = new_node
new_node.next = temp
self.size = self.size + 1
def print_it(self):
curr = self.head
if self.head is None:
print("リストは空です")
return
else:
print(curr.data)
while curr.next != self.head:
curr = curr.next
print(curr.data)
print()
class circular_linked_list:
my_cl = list_creation()
print("ノードをリストに追加していきます")
my_cl.add_data(21)
my_cl.add_data(54)
my_cl.add_data(78)
my_cl.add_data(99)
print("現在のリスト:")
my_cl.print_it()
my_cl.add_in_between(33)
print("更新後のリスト:")
my_cl.print_it()
my_cl.add_in_between(56)
print("更新後のリスト:")
my_cl.print_it()
my_cl.add_in_between(0)
print("更新後のリスト:")
my_cl.print_it()
実行結果
ノードをリストに追加していきます 現在のリスト: 21 54 78 99 更新後のリスト: 21 54 33 78 99 更新後のリスト: 21 54 33 56 78 99 更新後のリスト: 21 54 33 0 56 78 99
コードの解説
- まず、ノードのデータと次ノードへの参照という2つの属性を持つ「Node」クラスを作成します。
- 必要な属性を備えた別のクラス「list_creation」を定義します。
- 循環リンクリストの中央(最も中間に近い位置)にデータを挿入するための「add_in_between」メソッドを定義します。
- 循環リンクリストの各ノードを表示するための「print_it」メソッドを定義します。
- 「__init__」メソッドでは、循環リンクリストの先頭と末尾のノードをNoneで初期化します。
- 「list_creation」クラスのオブジェクトを生成し、そのメソッドを呼び出してデータを順番に追加します。
- 「add_in_between」メソッドが呼び出されると、リストを走査して中央のインデックスを算出し、その位置に新しい要素を挿入します。
- 挿入後のリストの状態は「print_it」メソッドによってコンソールに出力されます。
計算量について
中央への挿入では、挿入位置までリストを走査する必要があるため、時間計算量はO(n)となります。一方、実際のノード挿入処理(ポインタの付け替え)自体はO(1)で完了します。この点を理解しておくと、データ構造の選択時に適切な判断ができるようになります。
-
循環リンクリスト内の要素を検索するPythonプログラム
循環リンクリストとは循環リンクリスト(Circular Linked List)は、通常のリンクリストと異なり、最後のノードが先頭ノードに接続されているデータ構造です。そのため、リスト内に「NULL」で終わるノードが存在せず、head(先頭)とtail(末尾)が互いに隣接し、円を形成するように連結されています。循環リンクリスト内の特定の要素を検索するには、まず「Node」クラスを作成する必要があります。このクラスには、ノードに格納されるデータと、次のノードへの参照という2つの属性を持たせます。さらに、初期化関数を持つ別のクラスを作成し、headノードを「None」で初期化します。そして、リスト
-
Pythonで片方向リンクリストの中央ノードを1回の走査で見つける方法
片方向リンクリスト(単方向連結リスト)の先頭ノードが与えられたとき、その中央ノードの値を求めることを考えます。ノード数が偶数で中央にあたるノードが2つ存在する場合は、後ろ側(2番目)の中央ノードを返すものとします。さらに、リスト全体をたどるのは1回だけ(シングルパス)で解くのが条件です。例えば、入力が [5,9,6,4,8,2,1,4,5,2] の場合、要素数は10なので中央は「8」と「2」の2つになります。したがって、出力は後ろ側の 2 となります。解法のアプローチこの問題は、基準点となるポインタ p をゆっくり進めながら、カウンタを組み合わせて処理することで解けます。手順は以下の通りです。