2010-01-10 43 views
24

Giả sử rằng tôi có hai cây AVL và mỗi phần tử từ cây đầu tiên nhỏ hơn thì bất kỳ phần tử nào từ cây thứ hai. Cách hiệu quả nhất để ghép chúng vào một cây AVL đơn lẻ là gì? Tôi đã tìm kiếm ở khắp mọi nơi nhưng không tìm thấy bất cứ điều gì hữu ích.Ghép/Kết hợp/Nối hai cây AVL

+0

Cảm ơn bạn câu hỏi grate, nhưng tôi nghĩ nó phù hợp hơn đối với: https: // cs .stackexchange.com/ – ChaosPredictor

Trả lời

28

Giả sử bạn có thể phá hủy các cây đầu vào:

  1. loại bỏ các yếu tố ngoài cùng bên phải cho cây trái, và sử dụng nó để xây dựng một nút gốc mới, có con bên trái là cây trái, và có con bên phải là cây phải: O (log n)
  2. xác định và đặt hệ số cân bằng của nút đó: O (log n). Trong (tạm thời) vi phạm bất biến, yếu tố cân bằng có thể bên ngoài phạm vi {-1, 0, 1}
  3. xoay để có được những yếu tố cân bằng trở lại vào khoảng: O (log n) phép quay: O (log n)

Do đó, toàn bộ thao tác có thể được thực hiện trong O (log n).

Chỉnh sửa: Theo ý nghĩ thứ hai, sẽ dễ dàng hơn để giải thích về các phép quay trong thuật toán sau. Nó cũng khá có khả năng nhanh hơn:

  1. Xác định chiều cao của cả hai cây: O (log n).
    Giả sử rằng cây phải cao hơn (trường hợp khác là đối xứng):
  2. xóa phần tử ngoài cùng bên phải khỏi cây left (xoay và điều chỉnh chiều cao được tính nếu cần). Hãy để n là yếu tố đó. O (log n)
  3. Trong cây bên phải, điều hướng sang trái cho đến khi bạn đạt đến nút có số lượng con nhiều nhất là 1 cao hơn left. Hãy để r là nút đó. O (log n)
  4. thay thế nút đó bằng nút mới có giá trị n và các subtrees leftr. O (1)
    Bằng cách xây dựng, nút mới được cân bằng AVL và nút con của nó cao hơn r.

  5. tăng số dư của phụ huynh cho phù hợp. O (1)

  6. và cân bằng lại như sau khi chèn. O (log n)
+1

Bạn có chắc chắn không? (Bạn có thể dễ dàng chính xác, nhưng tôi chỉ tò mò.) Giả sử cây trái nhỏ hơn nhiều so với cây đúng nghĩa, nhiều nông hơn. Tại sao các phép quay O (log n) khôi phục thuộc tính AVL? Làm thế nào để bạn quyết định nơi để xoay? –

+1

Những gì Dale nói: sự lựa chọn thông thường của phép quay cho cây AVL cho phép sự mất cân bằng kích thước 2 được điều chỉnh trở lại phạm vi [-1,1] với phép quay O (log n). Bạn cần một sơ đồ mới để lựa chọn phép quay để điều chỉnh sự mất cân bằng tùy ý. Vì đó là một phần của cây AVL mà tôi không bao giờ có thể nhớ, và phải tra cứu mọi lúc, tôi mong rằng ngay cả khi lựa chọn quay là hiển nhiên, nó không rõ ràng với tôi :-) –

+1

Những điểm tốt. Tôi thấy nó dễ dàng hơn để chứng minh một thuật toán khác (c.f. câu trả lời đã chỉnh sửa của tôi). – meriton

1

Tôi nghi ngờ rằng bạn sẽ chỉ phải đi bộ một cây (hy vọng nhỏ hơn) và cá nhân thêm từng phần tử của nó vào cây khác. Các hoạt động chèn/xóa AVL không được thiết kế để xử lý việc thêm toàn bộ cây con tại một thời điểm.

+0

Tôi có cảm giác rằng nó có thể được thực hiện tuyến tính. Sử dụng cách tiếp cận ngây thơ có thời gian O (n log n). – avakar

+0

Điều này có O (n log n) -> chậm hơn nhiều so với giải pháp của meriton – inspectorG4dget

+2

@ meriton của giải pháp thực sự là rất tốt đẹp, nhưng nó giả định (a) rằng mỗi nút trong một cây là đúng ít hơn tất cả các nút trong cây khác, (b) bạn có quyền truy cập vào cấu trúc dữ liệu cây avl thô và (c) có thể thực hiện phép quay trực tiếp trên các nút cây. Nếu (a) không giữ, hoặc các thao tác cây cấp thấp không có sẵn cho bạn (rất có thể vì bạn đang sử dụng thư viện avl) thì bạn có thể phải lùi lại chỉ đơn giản chèn từng nút từ cây nhỏ vào cái lớn hơn. –

6

Một giải pháp cực kỳ đơn giản (mà làm việc mà không cần bất kỳ giả định trong quan hệ giữa cây) là thế này:

  1. Làm một loại kết hợp của cả hai cây vào một mảng sáp nhập (đồng thời lặp lại cả hai cây).
  2. Tạo một cây AVL từ mảng - lấy phần tử ở giữa làm gốc và áp dụng đệ quy cho nửa trái và phải.

Cả hai bước này là O (n). Vấn đề chính với nó là phải mất không gian thêm O (n).

+1

Không phải là bước đầu tiên O (n log (n))? – stendarr

4

Giải pháp tốt nhất tôi đọc cho sự cố này có thể được tìm thấy here. Rất gần với câu trả lời của meriton nếu bạn khắc phục sự cố này:

Điều hướng thứ ba của thuật toán điều hướng sang trái cho đến khi nút có cây phụ có cùng chiều cao với cây bên trái. Điều này không phải lúc nào cũng có thể, (xem hình ảnh phản diện). Đúng cách để thực hiện bước này là hai tìm cho một cây con với chiều cao h hoặc h+1 nơi h là chiều cao của cây trái counterexample

Các vấn đề liên quan