0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

「世界で闘うプログラミング力を鍛える本」Pythonコード解答例 - 2.8 ループの検出

Last updated at Posted at 2020-02-03

「世界で闘うプログラミング力を鍛える本」Pythonコード解答例 - 2.8 ループの検出

###CHAP2. 連結リスト

  1. 重複要素の削除
  2. 後ろからK番目を返す
  3. 間の要素を削除
  4. リストの分割
  5. リストで表された2数の和
  6. 回文
  7. 交わるノード
  8. ループの検出

#Pythonコード解答例


from chap2_function import* 

def FindBeginning(head_node):
    
    slow = head_node
    fast = head_node

    while fast and fast.next:

        slow = slow.next
        fast = fast.next.next
        
        if slow == fast:
            break

    if fast == None or fast.next == None:
        return None

    slow = head_node

    while slow != fast:
        slow = slow.next
        fast = fast.next

    return fast


sll = SinglyLinkedList()

sll.append(1)
sll.append(2)
sll.append(3)
sll.append(4)
sll.append(5)

sll.printList(sll.head)

sll.insertNode(sll.head.next.next.next.next,sll.head.next.next)

print("sll[0]: ", sll.head.data)
print("sll[1]: ",sll.head.next.data)
print("sll[2]: ",sll.head.next.next.data)
print("sll[3]: ",sll.head.next.next.next.data)
print("sll[4]: ",sll.head.next.next.next.next.data)
print("sll[5]: ",sll.head.next.next.next.next.next.data)
print("sll[6]: ",sll.head.next.next.next.next.next.next.data)

print("出力: ",FindBeginning(sll.head).data)

#Python関数(ノードクラス, 双方向リストクラス)

chap2_function.py
# ノードクラス
class Node: 
  
    # コンストラクタ
    def __init__(self, data): 
        self.data = data 
        self.next = None
        self.prev = None
  
# 単方向リストクラス
class SinglyLinkedList: 
  
    # コンストラクタ
    def __init__(self): 
        self.head = None

    def insertNode(self, prev_node, new_node): 
  
        if prev_node is None: 
            print("the given previous node cannot be NULL")
            return 
        
        if new_node is None: 
            print("the given new node cannot be NULL")
            return 
  
        # prev_nodeで指定したノードの次ノードを新ノードにする
        prev_node.next = new_node 
  
  
    # 最終ノードからのノード挿入
    def append(self, new_data): 
  
        # ノード生成 
        new_node = Node(new_data) 
  
        # 新ノードの次ノードをNone定義
        new_node.next = None
  
        # もしヘッドノードが設定されていない(空のリスト)場合、新ノードをヘッドノードに設定する
        if self.head is None: 
            new_node.prev = None
            self.head = new_node 
            return 
  
        # 最終ノードを設定する(順方向走査)
        last = self.head 
        while(last.next is not None): 
            last = last.next
  
        # 新ノードを最終ノードに指定する
        last.next = new_node 
  
        return

    # This function prints contents of linked list 
    # starting from the given node 
    def printList(self, node): 

        last = None
  
        print("単方向リスト: \n") 

        print("順方向走査")
        while(node is not None): 
            print(node.data,end="") 
            last = node 
            node = node.next
            if node:
                print(" -> ",end="")
            else:
                print("\n")
  


# 双方向リストクラス
class DoublyLinkedList: 
  
    # コンストラクタ
    def __init__(self): 
        self.head = None
  
    # 第一ノードからのノード挿入
    def push(self, new_data): 
  
        # ノード生成
        new_node = Node(new_data) 
  
        # 新ノードの次ノードをそもそもヘッドノードだったものにする
        new_node.next = self.head 
  
        # そもそもヘッドノードだったものの前ノードを新ノードにする
        if self.head is not None: 
            self.head.prev = new_node 
  
        # 新ノードをヘッドノードにする
        self.head = new_node 
  
    # 中間地点でのノード挿入 
    def insert(self, prev_node, new_data): 
  
        # prev_nodeで指定したノードの後にノード挿入するか指定
        # もしNoneの場合は、関数を出る
        if prev_node is None: 
            print("the given previous node cannot be NULL")
            return 
  
        # ノード生成
        new_node = Node(new_data) 
  
        # 新ノードの次ノードをprev_nodeで指定したノードの次ノードにする
        new_node.next = prev_node.next
  
        # prev_nodeで指定したノードの次ノードを新ノードにする
        prev_node.next = new_node 
  
        # 新ノードの前ノードをprev_nodeで指定したノードにする
        new_node.prev = prev_node 
  
        # 新ノードの次ノードをprev_nodeで指定したノードの次ノードにしたが、そのノードの前ノードも新ノードにする
        if new_node.next is not None: 
            new_node.next.prev = new_node 

    def insertNode(self, prev_node, new_node): 
  
        # prev_nodeで指定したノードの後にノード挿入するか指定
        # もしNoneの場合は、関数を出る
        if prev_node is None: 
            print("the given previous node cannot be NULL")
            return 
        
        if new_node is None: 
            print("the given new node cannot be NULL")
            return 
  
        # prev_nodeで指定したノードの次ノードを新ノードにする
        prev_node.next = new_node 
  
        # 新ノードの前ノードをprev_nodeで指定したノードにする
        new_node.prev = prev_node 
  
  
    # 最終ノードからのノード挿入
    def append(self, new_data): 
  
        # ノード生成 
        new_node = Node(new_data) 
  
        # 新ノードの次ノードをNone定義
        new_node.next = None
  
        # もしヘッドノードが設定されていない(空のリスト)場合、新ノードをヘッドノードに設定する
        if self.head is None: 
            new_node.prev = None
            self.head = new_node 
            return 
  
        # 最終ノードを設定する(順方向走査)
        last = self.head 
        while(last.next is not None): 
            last = last.next
  
        # 新ノードを最終ノードに指定する
        last.next = new_node 
  
        # 7. 新ノードの前ノードをそもそも最終ノードだったものにする
        new_node.prev = last 
  
        return
  
    def delete(self,del_node):

        if self.head == None or del_node == None: 
            return 

        if self.head == del_node: 
            self.head = del_node.next

        if del_node.next != None: 
            del_node.next.prev = del_node.prev 

        if del_node.prev != None: 
            del_node.prev.next = del_node.next

    # This function prints contents of linked list 
    # starting from the given node 
    def printList(self, node): 

        last = None
  
        print("双方向リスト: \n") 

        print("順方向走査")
        while(node is not None): 
            print(node.data,end="") 
            last = node 
            node = node.next
            if node:
                print(" -> ",end="")
            else:
                print("\n")
  
        print("逆方向走査")
        while(last is not None): 
            print(last.data,end="")
            last = last.prev 
            if last:
                print(" -> ",end="")
            else:
                print("\n")
  
if __name__ == '__main__':
    # 空の双方向リストの生成
    # DLL: None
    dll = DoublyLinkedList() 
    # DLL: None -> 6(ヘッド/ラスト) -> None
    dll.append(6) 
    # DLL: None -> 7(ヘッド) -> 6(ラスト) -> None 
    dll.push(7) 
    # DLL: None -> 1(ヘッド) -> 7 -> 6(ラスト) -> None 
    dll.push(1) 
    # DLL: None -> 1(ヘッド) -> 7 -> 6 -> 4(ラスト) -> None 
    dll.append(4) 
    # DLL: None -> 1(ヘッド) -> 7 -> 8 -> 6 -> 4(ラスト) -> None 
    dll.insert(dll.head.next, 8) 
    # DLL: None -> 1(ヘッド) -> 8 -> 6 -> 4(ラスト) -> None 
    dll.delete(dll.head.next) 


    dll.printList(dll.head) 

    sll = SinglyLinkedList()

    sll.append(1)
    sll.append(8)
    sll.append(6)
    sll.append(4)

    sll.printList(sll.head)

#参考文献
[1] GeeksforGeeks: Doubly Linked List | Set 1 (Introduction and Insertion)
[2] GeeksforGeeks: Delete a node in a Doubly Linked List

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?