Bài 15: Cấu trúc dữ liệu danh sách liên kết và ứng dụng

Chủ đề Fcs: Giải quyết vấn đề với sự trợ giúp của máy tính – Kĩ thuật lập trình – Bài 15: Cấu trúc dữ liệu danh sách liên kết và ứng dụng – sách bài tập trang 65 lớp 11 Khoa học máy tính – Cánh Diều, mời các em tham khảo cùng Bumbii.

Chủ đề Fcs: Giải quyết vấn đề với sự trợ giúp của máy tính – Bài 15: Cấu trúc dữ liệu danh sách liên kết và ứng dụng

Câu FCS43

Giả sử em phải truy cập phần tử thứ k trong danh sách. Độ phức tạp thời gian để truy cập phần tử đó là bao nhiêu và tại sao?

Trả lời:

Vì em không có cách truy cập ngẫu nhiên tới phần tử thứ k, do đó ta buộc phải nhảy k − 1 lần bắt đầu từ phần tử đầu tiên. Vì vậy độ phức tạp là O(k).

Câu FCS44

Cho một danh sách liên kết đơn có giá trị các nút được sắp xếp theo thứ tự không giảm (nghĩa là node.Data < node.Next.Data) và một phần tử x. Hỏi độ phức tạp để chèn một nút có giá trị là x vào danh sách liên kết sao cho không thay đổi tính chất của danh sách là bao nhiêu?

Lời giải:

Độ phức tạp là O(n) với n là số phần tử của danh sách.

Cách làm: Đầu tiên em tìm nút nodenode.Next.Data có giá trị lớn hơn hoặc bằng x hoặc node.Next rỗng, sau đó chèn node có giá trị x vào giữa nodenode.Next.

Câu FCS45

Bài toán Josephus được phát biểu như sau:

n người đứng thành một vòng tròn, được đánh số thứ tự 1, 2, 3, 4,…, n. Trò chơi bắt đầu từ người thứ nhất (đánh số 1). Mọi người sẽ lần lượt đếm 1-2-1-2-1-2-… khi tới lượt của mình, bất kì ai sau khi đếm được số 2 thì phải bước ra khỏi vòng tròn. Trong toán học, người ta rút ra được một số công thức để tính ra được người còn sót lại cuối cùng trong vòng tròn, với luật chơi tổng quát (đếm tới k thay vì 2). Tuy nhiên, ở đây em lại quan tâm diễn biến của trò chơi này hơn. Em hãy dùng danh sách liên kết để mô phỏng lại trò chơi trên.

Dữ liệu: Dòng duy nhất chứa số nguyên n.

Kết quả: Dòng duy nhất chứa n số là số hiệu của những người chơi bị loại ra khỏi vòng tròn theo thứ tự.

Ví dụ:

Trả lời:

Có thể áp dụng danh sách liên kết vòng để giải quyết bài toán trên. Thao tác xoá phần tử được vận dụng nhiều.

Chương trình mẫu:

class Node:
    def __init__(self, data):
        self.data = data
        self.next = None
        
n = int(input())

head = Node(1)
node = head
for i in range(2, n+1):
    node.next = Node(i)
    node = node.next
node.next = head

node = head
while n > 1:
    print(node.next.data, end = " ")
    node.next = node.next.next  # xóa người đếm số 2
    node = node.next            # người tiếp theo - người đếm số 1
    n -= 1
print(node.data)

Câu FCS46

Em đang cần mô phỏng lại một mạng xã hội. Có tổng cộng n người dùng. Các người dùng được đánh số từ 1 tới n . Có tổng cộng m yêu cầu kết bạn, được liệt kê theo thời gian gửi tăng dần; tất cả yêu cầu đều được đồng ý ngay tại thời điểm gửi. Với mỗi người, em cần in ra danh sách bạn bè của họ.

Dữ liệu: Nhập từ thiết bị vào chuẩn:

  • Dòng đầu tiên chứa hai số nguyên dương n, m (n, m ≤ 10).
  • m dòng tiếp theo, mỗi dòng chứa hai số nguyên dương u, v.

Kết quả: Hiển thị ở thiết bị ra chuẩn n dòng, với mỗi dòng i (1 ≤ i ≤ n) là danh sách bạn bè của người thứ i. Danh sách bạn bè được in theo thứ tự kết bạn.

Ví dụ:

Trả lời:

Bài toán của ta chính là quản lí các mảng “động”: mảng không có độ dài cố định trước mà các phần tử của nó sẽ dần được thêm vào theo nhu cầu sử dụng.

Cách 1: Sử dụng danh sách liên kết.

class Node:
    def __init__(self, data):
    self.data = data
    self.next = None
n, m = map(int, input().split())
heads = [Node(0) for i in range(n+1)]
tails = heads [::]
def addNode(node, value):
    node.next = Node (value)
    return node.next
for i in range(m):
    u, v = map(int, input().split))
    tails[u] = addNode(tails[u], v)
    tails[v] = addNode(tails[v], u)
    
def traverse(node):
    while node != Node:
        print(node.data, end = " ")
        node = node.next
    print() #xuống dòng
for i in range(1, n + 1):
    traverse(heads[i].next)

Cách 2: Tận dụng cấu trúc dữ liệu sẵn có – danh sách

n, m = map(int, input().split())
friendsList = [[] for i in range(n + 1)]
for i in range(m):
    u, v = map(int, input().split())
    friendsList[u].append(v)
    friendsList[v].append(u)
for i in range(1, n + 1):
    print(*friendsList[i])

Câu FCS47

Để hiểu rõ hơn về danh sách liên kết và các thao tác trên danh sách liên kết, Tí thực hiện các thao tác thuộc hai loại sau:

Loại 1: “Quay” k lần: tức là Tí sẽ lấy phần tử đầu tiên của danh sách liên kết và chèn nó vào sau phần tử cuối cùng, thực hiện k lần như vậy.

Loại 2: Đảo ngược danh sách liên kết.

Sau nhiều giờ lập trình, Ti tiến hành kiểm thử, tuy nhiên lại không tự tin vào kết quả của mình. Tí nhờ bạn code để đối chiếu kết quả.

Biết rằng Tí đã cài sẵn danh sách liên kết trong một mô đun và import nó vào trong chương trình. Danh sách liên kết này đảm bảo hoạt động chính xác. Tí cũng code sẵn phần xử lí nhập vào, in ra dữ liệu. Hãy hoàn thiện hai hàm rotate (quay mảng) và reverseList (đảo ngược).

Cấu trúc nút được định nghĩa như sau:

Giả sử có một biến tên node thuộc kiểu Node tượng trưng cho một nút trong danh sách liên kết. Để lấy nút tiếp theo, ta viết node.next; để lấy ra giá trị, ta viết node.data. Để tạo ra một nút mới có giá trị là value, ta viết node = Node(value).

Hai hàm cần cài đặt được cung cấp tham số head: nút trỏ tới đầu của danh sách liên kết. Hàm trả về biến kiểu Node, trỏ tới phần tử đầu tiên của danh sách liên kết mới được thay đổi sau các truy vấn.

Cụ thể hơn, các hàm này được định nghĩa như sau:

Trả lời:

 Thao tác chèn và duyệt danh sách liên kết được vận dụng nhiều trong hai hàm sau.

Hàm quay mảng:

def rotate(head, k):
    tail = head
    while tail.next != None:
        tail = tail.next
    for i in range(k):
        tail.next = Node(head.data)
        head = head.next
        tail = tail.next
    return head

Hàm đảo ngược:

def reverseList(head):
    newHead = Node(head.data) #tạo ra một nút mới
    node = head.next
    while node != None:
        #Thao tác chèn phần tử vào đầu DSLK
        newNode = Node(node.data)
        newNode.next = newHead
        newHead = newNode
        node = node.next
    return newHead

Xem các bài giải khác: Giải Bài Tập SBT Lớp 11 Khoa Học Máy Tính Cánh Diều

Thông tin liên hệ & mạng xã hội:
Website: https://bumbii.com/
Facebook: https://www.facebook.com/bumbiiapp
Pinterest: https://www.pinterest.com/bumbiitech

0 0 đánh giá
Article Rating
Theo dõi
Thông báo của
guest

0 Bình luận
Phản hồi nội tuyến
Xem tất cả bình luận
0
Cùng chia sẻ bình luận của bạn nào!x