Chuyển tới nội dung chính

std::forward_list::merge

#include <forward_list>

// Phiên bản 1: Sử dụng toán tử < để so sánh
void merge(forward_list& other);
void merge(forward_list&& other); // (since C++11)

// Phiên bản 2: Sử dụng hàm so sánh comp
template <class Compare>
void merge(forward_list& other, Compare comp);
template <class Compare>
void merge(forward_list&& other, Compare comp); // (since C++11)

Hợp nhất (merge) hai forward_list đã được sắp xếp thành một forward_list duy nhất, vẫn giữ nguyên thứ tự đã sắp xếp. Các phần tử từ forward_list khác sẽ được chuyển sang forward_list hiện tại, và forward_list kia sẽ trở thành rỗng sau khi merge() hoàn tất.

Tham số

other

  • Tham chiếu đến forward_list khác cần hợp nhất. Sau khi merge() hoàn tất, other sẽ trở thành rỗng.

comp

(phiên bản 2)

  • Hàm so sánh (comparison function) hoặc functor xác định thứ tự sắp xếp của các phần tử.
  • comp phải nhận hai đối số có kiểu là value_type của forward_list (hoặc kiểu có thể chuyển đổi thành value_type) và trả về true nếu đối số đầu tiên được coi là nhỏ hơn đối số thứ hai theo thứ tự sắp xếp, false nếu ngược lại.

Giá trị trả về

Không có giá trị trả về

Đặc điểm

  1. Yêu cầu đã sắp xếp: Cả hai forward_list (hiện tại và other) phải được sắp xếp trước khi gọi merge(). Nếu không, kết quả sẽ không xác định.
  2. Chuyển phần tử, không sao chép: merge() chuyển các phần tử từ other sang forward_list hiện tại, không tạo ra các bản sao. Do đó, thao tác này rất hiệu quả.
  3. other trở thành rỗng: Sau khi merge() hoàn tất, forward_list other sẽ trở thành rỗng.
  4. Hai phiên bản: Phiên bản thứ hai của merge() cho phép bạn định nghĩa cách so sánh các phần tử thông qua hàm so sánh comp, hữu ích khi bạn muốn hợp nhất theo một thứ tự khác ngoài thứ tự tăng dần mặc định.
  5. Có thể làm thay đổi iterator: Việc chuyển các phần tử có thể làm thay đổi (invalidate) các iterator đang trỏ đến các phần tử trong cả hai forward_list.
  6. noexcept: Phiên bản move merge() được đánh dấu là noexcept (kể từ C++11), nghĩa là nó được đảm bảo không ném ra ngoại lệ nào. Các phiên bản copy thì có thể ném ngoại lệ nếu constructor, copy constructor hoặc destructor của phần tử được chèn ném ngoại lệ.
  7. Trường hợp other là chính nó: Nếu other là chính forward_list hiện tại, merge() sẽ không làm gì cả.
  8. Độ phức tạp: Độ phức tạp của merge() là O(n + m), với n và m lần lượt là số phần tử trong hai forward_list trước khi hợp nhất.

Ví dụ

#include <iostream>
#include <forward_list>

// Hàm so sánh tùy chỉnh (giảm dần)
bool compareDescending(int a, int b) {
return a > b;
}

int main() {
std::forward_list<int> list1 = {1, 3, 5, 7};
std::forward_list<int> list2 = {2, 4, 6, 8};

list1.merge(list2); // Hợp nhất list2 vào list1 (sử dụng toán tử <)

std::cout << "list1 after merge(list2):";
for (int x : list1) std::cout << ' ' << x; // Output: list1 after merge(list2): 1 2 3 4 5 6 7 8
std::cout << '\n';
std::cout << "list2 after merge(list2):";
for (int x : list2) std::cout << ' ' << x; // Output: list2 after merge(list2): (empty)
std::cout << '\n';

std::forward_list<int> list3 = {9, 7, 5, 3};
std::forward_list<int> list4 = {8, 6, 4, 2};

list3.sort(compareDescending);
list4.sort(compareDescending);
list3.merge(list4, compareDescending); // Hợp nhất list4 vào list3 (sử dụng hàm so sánh tùy chỉnh)

std::cout << "list3 after merge(list4, compareDescending):";
for (int x : list3) std::cout << ' ' << x; // Output: list3 after merge(list4, compareDescending): 9 8 7 6 5 4 3 2
std::cout << '\n';

return 0;
}

Các hàm liên quan

splice_afterChuyển (transfer) các phần tử từ một forward_list khác hoặc từ một phạm vi trong forward_list khác sang forward_list hiện tại
insert_afterChèn một hoặc nhiều phần tử mới vào sau một vị trí iterator cho trước trong forward_list
removeXóa tất cả các phần tử có giá trị bằng với một giá trị cho trước khỏi forward_list
erase_afterXóa một hoặc nhiều phần tử khỏi forward_list tại vị trí sau một iterator cho trước
push_frontThêm một phần tử mới vào đầu forward_list