Pythonで連結リストのノードを削除する方法
連結リスト(リンクリスト)にいくつかの要素が格納されているとします。ここでの課題は、指定されたノードをリストから削除する関数を作成することです。例えば、リストが 1 → 3 → 5 → 7 → 9 の場合、値 3 を削除すると、結果は 1 → 5 → 7 → 9 になります。
削除の基本的な考え方
削除したいノードを指すポインタ「node」が与えられている場合、以下の2つの操作を実行することでノードを削除できます。
node.val = node.next.val— 次のノードの値を現在のノードにコピーするnode.next = node.next.next— 現在のノードの参照先を、次の次のノードに付け替える
この手法は、削除対象ノードの前のノードが分からない場合でも機能するのが特徴です。値を一つずつ前へずらすことで、実質的にそのノードを消し去ることができます。
Pythonでの実装例
それでは、実際のコードを見て理解を深めましょう。
class ListNode:
def __init__(self, data, next = None):
self.val = data
self.next = next
def make_list(elements):
head = ListNode(elements[0])
for element in elements[1:]:
ptr = head
while ptr.next:
ptr = ptr.next
ptr.next = ListNode(element)
return head
def print_list(head):
ptr = head
print('[', end = "")
while ptr:
print(ptr.val, end = ", ")
ptr = ptr.next
print(']')
class Solution(object):
def deleteNode(self, node, data):
"""
:type node: ListNode
:rtype: void Do not return anything, modify node in-place instead.
"""
while node.val is not data:
node = node.next
node.val = node.next.val
node.next = node.next.next
head = make_list([1,3,5,7,9])
ob1 = Solution()
ob1.deleteNode(head, 3)
print_list(head)入力
linked_list = [1,3,5,7,9] data = 3
出力
[1, 5, 7, 9]
コードの解説
このプログラムでは、まず make_list 関数を使って配列 [1, 3, 5, 7, 9] から連結リストを構築しています。続いて Solution クラスの deleteNode メソッドが呼び出され、削除したい値 3 を持つノードまでポインタを進めた後、上述の2つの操作によってノードを削除します。
最後に print_list 関数でリスト全体を出力しており、値 3 が取り除かれた [1, 5, 7, 9] が表示されることが確認できます。
なお、この手法には注意点もあります。削除対象がリストの末尾のノードである場合、node.next が存在しないためエラーになります。また、時間計算量は O(1) で非常に効率的ですが、末尾ノードの削除が必要なケースでは、従来通り前のノードを辿る方式(O(n))を採用する必要があります。
-
Pythonで連結リストのm個のノードを保持した後にn個のノードを削除するプログラム
始点ノードが「head」である連結リストと、2つの整数 m と n が与えられたとします。リストを走査しながら、先頭から数えて m 個のノードを残した直後の n 個のノードを削除する処理を、連結リストの末尾に到達するまで繰り返します。処理は head ノードから開始し、最後に変更後の連結リストを返します。今回扱う連結リストの構造は次のように定義されています。Node value : <整数値> next : <次のノードへのポインタ>例えば、入力が elements = [1, 2, 3, 4, 5, 6, 7, 8]、m = 3、n = 1 の場合、出
-
【Python】連結リストをジグザグ二分木に変換するプログラムの書き方
問題の概要単方向連結リスト(片方向リンクリスト)が与えられたとき、次のルールに従って二分木へ変換することを考えます。連結リストの先頭ノード(head)が、二分木のルートになります。それ以降の各ノードは、その値が親ノードより小さい場合は左の子に、そうでない場合は右の子になります。たとえば、入力が [2,1,3,4,0,5] の場合、変換後の二分木は次のような「ジグザグ」形状になります。解き方の手順この問題は、再帰的に呼び出す関数 solve() を定義すると、シンプルに解くことができます。具体的な手順は以下の通りです。ノードを引数として受け取る関数 solve() を定義します。ノードが nul