チェーンテーブルデータ構造-力ブラシチェーンテーブル問題を知る必要がある(Python)
5305 ワード
チェーンテーブルは前後順に並べられたデータ構造で、ここでは単一チェーンテーブルを例に、筆者が初めて力ボタンを塗ったとき、チェーンテーブルがどのように来たのか分からない.ここでは基礎的な知識を補充して紹介し、読者がチェーンテーブルの問題を理解するのを助ける必要がある.
チェーンテーブルノード
単一チェーンテーブルノードの定義式は非常に簡潔で、ここでは2つのインスタンス変数を持つクラスで定義します.ノードの値(val)は、整数であってもよいし、他のデータ構造であってもよい. このノードが指す次のノード(next)も、ノードである.
デュアルチェーンテーブルの場合、前のノードを指す前のノード(prev)もあります.
チェーンテーブルの作成
チェーンテーブルはノードからなり、チェーンテーブルはノードの結合であるため、チェーンテーブルの作成にはノードの作成とノードの接続の2つのステップが含まれます.
チェーンテーブルコピー
チェーンテーブルのコピーは、チェーンテーブルを作成するときに別のチェーンテーブル制約で作成するプロセスに相当します.チェーンテーブルレプリケーションはチェーンテーブルの浅いコピーに相当し,チェーンテーブルのタイトルではチェーンテーブルが関数に入った後に修正されるなどの状況を避けることができる.
チェーンテーブル印刷
チェーンテーブルの開始ノードが得られると、チェーンテーブル全体のすべてのノードが得られるすべての値に相当します.
以上の方法ではチェーンテーブルがリングチェーンテーブルではない場合を判別するしかなく,チェーンテーブルにリング構造があればプログラムはデッドサイクルに陥り,ステップアップバージョンのプログラムを書き換え,リングチェーンテーブルを判別することができる.
たとえば、次のコードを実行します.
印刷結果が表示されます.
リングチェーンテーブルを構築する場合は、先ほどのコードに基づいて一言追加します.
印刷結果が表示されます.
チェーンメーター判定等
チェーンテーブル判定等は、チェーンテーブルの該当要素の値が等しいか否かを判断すればよい.
チェーンゲージリング
チェーンテーブルにリング構造がある場合は、ループ時にループしたノードに必ず遭遇します.そうしないと、必ず最後のノードにループします.
質問やアドバイスがあれば、コメントエリアへようこそ~
チェーンテーブルノード
単一チェーンテーブルノードの定義式は非常に簡潔で、ここでは2つのインスタンス変数を持つクラスで定義します.
デュアルチェーンテーブルの場合、前のノードを指す前のノード(prev)もあります.
class ListNode:
"""
"""
def __init__(self, x): # ,
self.val = x #
self.next = None # , None
チェーンテーブルの作成
チェーンテーブルはノードからなり、チェーンテーブルはノードの結合であるため、チェーンテーブルの作成にはノードの作成とノードの接続の2つのステップが含まれます.
def create_linked_list(nums):
"""
:param nums:
:return: ,
"""
if not nums: #
return
head = prev = ListNode(nums[0]) #
for num in nums[1:]:
tmp = ListNode(num) #
prev.next = tmp #
prev = prev.next #
return head
チェーンテーブルコピー
チェーンテーブルのコピーは、チェーンテーブルを作成するときに別のチェーンテーブル制約で作成するプロセスに相当します.チェーンテーブルレプリケーションはチェーンテーブルの浅いコピーに相当し,チェーンテーブルのタイトルではチェーンテーブルが関数に入った後に修正されるなどの状況を避けることができる.
def copy_linked_list(head):
"""
,
:param head:
:return:
"""
new_head, cur = ListNode(0), head # ,
tmp = new_head #
while cur: #
new_cur = ListNode(cur.val) #
tmp.next = new_cur #
cur = cur.next #
tmp = tmp.next #
return new_head.next #
チェーンテーブル印刷
チェーンテーブルの開始ノードが得られると、チェーンテーブル全体のすべてのノードが得られるすべての値に相当します.
def print_linked_list(head):
"""
:param head:
:return:
"""
tmp = head #
nums = []
while tmp:
nums.append(tmp.val)
tmp = tmp.next
print(nums)
return nums
以上の方法ではチェーンテーブルがリングチェーンテーブルではない場合を判別するしかなく,チェーンテーブルにリング構造があればプログラムはデッドサイクルに陥り,ステップアップバージョンのプログラムを書き換え,リングチェーンテーブルを判別することができる.
def print_linked_list(head):
"""
:param head:
:return:
"""
cur = head # ,
nums = [] #
nodes = []
circle_flag = False # flag
circle_nums = [] #
while cur:
nodes.append(cur)
if circle_flag:
circle_nums.append(cur.val) #
else:
nums.append(cur.val)
cur = cur.next
if cur in nodes:
if nodes.count(cur) == 2: #
break
else: # , flag
circle_flag = True
if circle_flag:
print(" ")
print(" :{}".format(nums))
print(" :{}".format(circle_nums))
print(" :{}".format(nums[len(nums)-len(circle_nums)]))
else:
print(" :{}".format(nums))
return nums
たとえば、次のコードを実行します.
if __name == '__main__':
n1 = ListNode(1)
n2 = ListNode(2)
n3 = ListNode(3)
n4 = ListNode(4)
n1.next = n2
n2.next = n3
n3.next = n4
print_linked_list(n1)
印刷結果が表示されます.
:[1, 2, 3, 4]
リングチェーンテーブルを構築する場合は、先ほどのコードに基づいて一言追加します.
if __name == '__main__':
n1 = ListNode(1)
n2 = ListNode(2)
n3 = ListNode(3)
n4 = ListNode(4)
n1.next = n2
n2.next = n3
n3.next = n4
n4.next = n2 #
print_linked_list(n1)
印刷結果が表示されます.
:[1, 2, 3, 4]
:[2, 3, 4]
:2
チェーンメーター判定等
チェーンテーブル判定等は、チェーンテーブルの該当要素の値が等しいか否かを判断すればよい.
def list_equal(head1, head2):
"""
:param head1:
:param head2:
:return:
"""
cur1, cur2 = head1, head2 # ,
tmp = head1 #
while cur1 and cur2:
if cur1.val != cur2.val:
return False
cur1, cur2 = cur1.next, cur2.next
if cur1 == tmp:
return True
return not cur1 and not cur2
チェーンゲージリング
チェーンテーブルにリング構造がある場合は、ループ時にループしたノードに必ず遭遇します.そうしないと、必ず最後のノードにループします.
def is_circle(head):
"""
:param head:
:return: ,
"""
if not head:
return False
tmp = head
while head:
head = head.next
if not head: #
return False #
if head == tmp: #
return True #
質問やアドバイスがあれば、コメントエリアへようこそ~