Sau đây giả định các bộ được lưu trữ dưới dạng vùng chứa được sắp xếp (như std :: set does).
Có một thuật toán phổ biến để hợp nhất hai danh sách được sắp xếp để tạo ra một danh sách thứ ba. Ý tưởng là khi bạn nhìn vào đầu của hai danh sách, bạn có thể xác định đó là thấp hơn, trích xuất đó, và thêm nó vào đuôi của đầu ra, sau đó lặp lại.
Có các biến thể phát hiện trường hợp hai đầu bằng nhau và xử lý đặc biệt này. Đặt giao lộ và công đoàn là những ví dụ về điều này.
Với sự khác biệt không đối xứng được đặt, điểm mấu chốt là đối với A-B, khi bạn giải nén đầu B, bạn loại bỏ nó. Khi bạn trích xuất phần đầu của A, bạn thêm nó vào đầu vào trừ khi phần đầu của B bằng nhau, trong trường hợp này bạn cũng lấy ra phần đầu và loại bỏ cả hai.
Mặc dù phương pháp này được thiết kế cho cấu trúc dữ liệu truy cập tuần tự (và lưu trữ băng vv), đôi khi rất hữu ích khi thực hiện điều tương tự cho cấu trúc dữ liệu truy cập ngẫu nhiên miễn là nó có hiệu quả. Và bạn không nhất thiết phải trích xuất mọi thứ cho thực - bạn có thể sao chép và thay vào đó.
Điểm mấu chốt là bạn bước qua các đầu vào tuần tự, luôn nhìn vào giá trị còn lại thấp nhất tiếp theo, để (nếu đầu vào không có bản sao), bạn sẽ thấy các mục phù hợp. Do đó, bạn luôn biết liệu giá trị thấp nhất tiếp theo của bạn để xử lý là một mục từ A không khớp với B và mục trong B không có kết quả phù hợp trong A hoặc một mục bằng nhau trong cả A và B.
Nói chung, thuật toán cho sự khác biệt thiết lập phụ thuộc vào sự biểu diễn của tập hợp. Ví dụ, nếu tập hợp được biểu diễn dưới dạng bit-bit, thì ở trên sẽ quá phức tạp và chậm - bạn chỉ cần lặp qua các vectơ thực hiện các thao tác bitwise. Nếu tập hợp được biểu diễn như là một hashtable (như trong tr1 unordered_set) ở trên là sai vì nó đòi hỏi đầu vào được đặt hàng.
Nếu bạn có mã cây nhị phân mà bạn đang sử dụng cho bộ, một tùy chọn tốt là chuyển đổi cả hai cây thành danh sách được liên kết, làm việc trên danh sách, sau đó chuyển danh sách kết quả thành cây cân bằng hoàn hảo. Sự khác biệt thiết lập danh sách liên kết rất đơn giản và hai chuyển đổi có thể sử dụng lại cho các hoạt động tương tự khác.
EDIT
Trên phức tạp - sử dụng các thuật toán hợp nhất giống như ra lệnh là O (n) cung cấp bạn có thể làm traversals trong trật tự trong thời gian O (n). Chuyển đổi thành một danh sách và ngược lại cũng là O (n) vì mỗi trong ba bước là O (n) - cây-to-list, set-sự khác biệt và danh sách-to-tree.
Danh sách cây được đưa vào danh sách về cơ bản thực hiện quá trình truyền tải độ sâu đầu tiên, phá hủy cây khi di chuyển. Có một thủ thuật để làm cho lặp đi lặp lại này, lưu trữ "ngăn xếp" trong các nút được xử lý một phần - thay đổi một con trỏ con trỏ trái thành con trỏ cha mẹ ngay trước khi bạn bước tới con trái. Đây là một ý tưởng tốt nếu cây có thể lớn và không cân bằng.
Chuyển đổi danh sách thành cây về cơ bản liên quan đến độ sâu đầu tiên của cây tưởng tượng (dựa trên kích thước, được biết từ đầu) xây dựng nó cho thực như bạn đi. Ví dụ: nếu cây có 5 nút, bạn có thể nói rằng thư mục gốc sẽ là nút 3. Bạn recurse xây dựng một cây con trái hai nút, sau đó lấy mục tiếp theo từ danh sách cho thư mục gốc đó, sau đó recurse để xây dựng một hai -nút bên phải.
Chuyển đổi danh sách thành cây không cần phải được triển khai lặp lại - đệ quy là tốt vì kết quả luôn được cân bằng hoàn hảo. Nếu bạn không thể xử lý độ sâu đệ quy log, bạn hầu như không thể xử lý toàn bộ cây đó.
Không có thứ gì như C-STL. Bạn có nghĩa là C + +? –
Tôi biết. Tôi chỉ muốn làm rõ rằng tôi không muốn các giải pháp dựa trên STL. – Aamir
Vì STL là một điều duy nhất C++ - nên bạn có thể nói rằng bạn đang sử dụng C và để nó ở đó; nếu câu trả lời của bất cứ ai đã đề nghị STL họ sẽ được downvoted (và xứng đáng như vậy). –