Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonで連結リストを反転する方法|再帰を使った実装をわかりやすく解説

連結リスト(リンクリスト)が与えられたとき、それを逆順に並べ替えることを考えます。たとえば、リストが 1 → 3 → 5 → 7 の場合、反転後の新しいリストは 7 → 5 → 3 → 1 となります。

解き方のアプローチ

この問題は、再帰を使った手順「solve(head, back)」を定義することで解決できます。具体的な流れは以下のとおりです。

  • リストの反転を再帰的に行う手順 solve(head, back) を定義する
  • head が存在しない場合は、head をそのまま返す
  • temp := head.next として、次のノードを一時的に保存する
  • head.next := back として、ポインタの向きを前のノードへ逆向きにする
  • back = head として、現在のノードを「前のノード」として記録する
  • temp が空の場合は、head を返して処理を終了する
  • head = temp として、次のノードへ進む
  • solve(head, back) を再帰的に呼び出す

実装例

以下の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 reverseList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        return self.solve(head, None)

    def solve(self, head, back):
        if not head:
            return head
        temp = head.next
        head.next = back
        back = head
        if not temp:
            return head
        head = temp
        return self.solve(head, back)

list1 = make_list([1, 3, 5, 7])
ob1 = Solution()
list2 = ob1.reverseList(list1)
print_list(list2)

入力

list1 = [1,3,5,7]

出力

[7, 5, 3, 1]

処理のポイント

このアルゴリズムでは、各ノードの next ポインタを前のノードに向けることで、リスト全体の向きを反転させています。back 変数が「これまで処理済みの部分リストの先頭」を保持し、再帰呼び出しがリストの末尾に到達した時点で、最後のノードが新しい先頭となり、完全に反転されたリストが完成します。

  1. Pythonで連結リストのサイクル(循環)を検出する方法

    連結リストのサイクル検出とは連結リスト(Linked List)の中にサイクル(循環)が存在するかどうかを判定する問題を考えてみましょう。この問題では、サイクルの有無を表現するために整数値のポインタ pos を使用します。pos は、リストの末尾ノードが接続されている位置を示します。つまり、pos = -1 の場合はサイクルが存在しないことを意味します。例えば、連結リストが [5, 3, 2, 0, -4, 7] で pos = 1 の場合、末尾ノード(7)が2番目のノード(3)に接続されているため、サイクルが存在することになります。解法のアプローチ:ハッシュセットを使う最もシンプルな方法は、

  2. Pythonで連結リストのノードを削除する方法

    連結リスト(リンクリスト)にいくつかの要素が格納されているとします。ここでの課題は、指定されたノードをリストから削除する関数を作成することです。例えば、リストが 1 → 3 → 5 → 7 → 9 の場合、値 3 を削除すると、結果は 1 → 5 → 7 → 9 になります。削除の基本的な考え方削除したいノードを指すポインタ「node」が与えられている場合、以下の2つの操作を実行することでノードを削除できます。node.val = node.next.val — 次のノードの値を現在のノードにコピーするnode.next = node.next.next — 現在のノードの参照先を、次の次のノ