0
0
Lập trình
Flame Kris
Flame Krisbacodekiller

Hướng Dẫn Chi Tiết Về Danh Sách Liên Kết Vòng (Circular Linked List) Trong Python

Đăng vào 5 ngày trước

• 8 phút đọc

Giới thiệu về Danh Sách Liên Kết Vòng

Danh sách liên kết vòng (Circular Linked List) là cấu trúc dữ liệu tương tự như danh sách liên kết đơn (Singly Linked List) nhưng có những điểm khác biệt quan trọng:

  • Node cuối cùng (tail node) sẽ trỏ trở về node đầu (head node) thay vì trỏ đến null (None).
  • Không có điểm kết thúc rõ ràng trong danh sách, điều này có nghĩa là nếu bạn duyệt qua nó mà không kiểm tra điều kiện cụ thể, bạn có thể lặp lại mãi mãi.

Danh sách liên kết vòng thường được sử dụng trong các bài toán cần tính năng lặp vô hạn hoặc khi bạn cần quay trở lại điểm đầu tiên sau khi hoàn thành một chu kỳ, ví dụ như trong việc phát lại danh sách nhạc.

Khởi Tạo Danh Sách Liên Kết Vòng

python Copy
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

class CircularLinkedList:
    def __init__(self):
        self.head = None

Phương Thức Append

Phương thức append được sử dụng để thêm một node mới vào cuối danh sách. Trong trường hợp danh sách rỗng, node mới sẽ trở thành node đầu (head) và trỏ đến chính nó, tạo thành vòng tròn. Nếu danh sách đã có node, ta sẽ duyệt đến node cuối cùng và gán node mới sau node cuối đó, tiếp tục giữ cấu trúc vòng tròn.

python Copy
def append(self, data):
        new_node = Node(data)
        if not self.head:
            self.head = new_node
            new_node.next = self.head
        else:
            current = self.head
            while current.next != self.head:
                current = current.next
            current.next = new_node
            new_node.next = self.head

In Nội Dung Danh Sách

Phương thức print_list cho phép bạn duyệt và in dữ liệu của từng node trong danh sách bắt đầu từ head cho đến khi trở về vị trí head, để thấy được tính chất vòng. Điều này rất hữu ích để kiểm tra nội dung của danh sách.

python Copy
def print_list(self):
        current = self.head
        if self.head:
            while True:
                print(current.data, end=" -> ")
                current = current.next
                if current == self.head:
                    break
            print("(head)")
        else:
            print("Danh sách trống.")

Phương Thức Prepend

Nếu bạn muốn thêm một node mới vào đầu danh sách, bạn có thể sử dụng phương thức prepend. Nó sẽ đặt node mới trước head hiện tại và cập nhật con trỏ next của node cuối cùng, đảm bảo rằng danh sách vẫn giữ được tính chất vòng tròn.

python Copy
def prepend(self, data):
        new_node = Node(data)
        current = self.head
        new_node.next = self.head

        if not self.head:
            new_node.next = new_node
        else:
            while current.next != self.head:
                current = current.next
            current.next = new_node
        self.head = new_node

Phương Thức Remove

Phương thức remove giúp bạn xóa một node theo giá trị cụ thể khỏi danh sách. Khi thực hiện xóa, bạn cần đảm bảo rằng cấu trúc vòng của danh sách vẫn được bảo toàn, đặc biệt khi xóa head hoặc node giữa danh sách.

python Copy
def remove(self, key):
        if self.head:
            if self.head.data == key:
                current = self.head
                while current.next != self.head:
                    current = current.next
                if self.head == self.head.next:
                    self.head = None
                else:
                    current.next = self.head.next
                    self.head = self.head.next
            else:
                current = self.head
                prev = None
                while current.next != self.head:
                    prev = current
                    current = current.next
                    if current.data == key:
                        prev.next = current.next
                        break

Chia Danh Sách Liên Kết Vòng Thành Hai Nửa

Bạn có thể chia danh sách liên kết vòng thành hai nửa bằng cách:

  1. Tìm kiếm chiều dài danh sách.
  2. Tính toán điểm giữa.
  3. Duyệt đến điểm giữa và ngắt liên kết vòng tại đó.

Dưới đây là cách thực hiện điều này:

python Copy
    def length(self):
        if not self.head:
            return 0
        temp = self.head
        count = 1
        while temp.next != self.head:
            count += 1
            temp = temp.next
        return count

    def split(self):
        if not self.head:
            return None, None

        length = self.length()
        if length == 1:
            return self, None

        mid = length // 2
        current = self.head
        prev = None

        for _ in range(mid):
            prev = current
            current = current.next

        second_list = CircularLinkedList()
        second_list.head = current
        prev.next = self.head

        temp = second_list.head
        while temp.next != self.head:
            temp = temp.next
        temp.next = second_list.head

        return self, second_list

Ví Dụ Sử Dụng

Dưới đây là ví dụ về cách sử dụng danh sách liên kết vòng:

python Copy
# Tạo một danh sách liên kết vòng mới
cll = CircularLinkedList()
for i in range(1, 11):
    cll.append(i)

print("Danh sách liên kết vòng ban đầu:")
cll.print_list()

list1, list2 = cll.split()

print("\nDanh sách liên kết vòng thứ nhất:")
list1.print_list()

print("\nDanh sách liên kết vòng thứ hai:")
list2.print_list()

Kết quả sẽ là:

Copy
Danh sách liên kết vòng ban đầu:
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> (head)

Danh sách liên kết vòng thứ nhất:
1 -> 2 -> 3 -> 4 -> 5 -> (head)

Danh sách liên kết vòng thứ hai:
6 -> 7 -> 8 -> 9 -> 10 -> (head)

source: viblo

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào