Enqueueing
Bạn không cần phải duyệt qua toàn bộ danh sách để tìm đuôi mới, bạn chỉ cần thêm một nút mới nơi đuôi hiện tại trỏ đến và đặt nút đó làm đuôi mới.
Mã giả (giả sử rằng head != null
và tail != null
):
function enqueue(value) {
node = new Node(value) // O(1)
tail.next = node // O(1)
tail = node // O(1)
size++ // O(1)
}
Từ đó chúng ta có thể kết luận rằng độ phức tạp của thời gian là Ô ( 1 ).
Dequeueing
Để khử nhiễu, chúng ta chỉ cần đặt nút tiếp theo của đầu hiện tại làm đầu mới và trả về giá trị của đầu cũ.
Lưu ý : Đừng quên rằng nếu đầu mới được đặt thành null
, đuôi cũng sẽ được đặt thành null
:
Mã giả (giả sử rằng head != null
và tail != null
):
function dequeue() {
value = head.value // O(1)
head = head.next // O(1)
size-- // O(1)
if (head == null) { // O(1)
tail = null // O(1)
}
return value // O(1)
}
Tất cả các hoạt động này có Ô ( 1 ) độ phức tạp thời gian, làm cho độ phức tạp thời gian của hàm dequeue Ô ( 1 ) cũng.
Đang tìm kiếm
Tìm kiếm một giá trị được thực hiện bằng cách duyệt qua tất cả các mục, bắt đầu từ đầu. Trong trường hợp xấu nhất, bạn sẽ cần phải đi qua toàn bộ hàng đợi, điều này làm cho độ phức tạp của thời gian trong trường hợp xấu nhấtÔ ( n ).
Ví dụ: nếu bạn muốn loại bỏ đuôi, độ phức tạp thời gian sẽ là Ô ( n ). Điều này là do bạn sẽ cần tìm đuôi mới cho hàng đợi và vì đuôi không có quyền truy cập vào phần tử trước đó trong danh sách liên kết đơn, nên bạn sẽ cần tìm kiếm toàn bộ hàng đợi cho đuôi mới.
Mã giả (giả sử rằng head != null
và tail != null
):
function removeLast() {
// Edge case when there is only 1 element in the queue.
if (head == tail) { // O(1)
value = head.value // O(1)
head = null // O(1)
tail = null // O(1)
return value // O(1)
}
// Searching for the new tail.
newTail = head // O(1)
while (newTail.next != tail) { // O(n)
newTail = newTail.next // O(1)
}
value = tail.value // O(1)
newTail.next = null // O(1)
tail = newTail // O(1)
return tail // O(1)
}
Từ đó có thể thấy rằng sự phức tạp thời gian thực sự là Ô ( n ).