[C/C++] list

할랑말랑·2026년 3월 18일

C/C++

목록 보기
29/45

list

이중 연결 리스트(Doubly Linked List) 컨테이너이다

각 노드가 이전 노드와 다음 노드를 가리키는 포인터를 가지고 있다.

특징

  • 비연속적 메모리 할당
  • 양방향 순회 : 앞(begin)에서 뒤로, 뒤(end)에서 앞으로 모두 이동할 수 있는 양방향 반복자(Bidirectional Iterator)사용 가능
  • 임의 접근 불가
  • 삽입과 삭제가 빠름 : 인터 연결만 바꾸면 되기 때문에, 리스트의 어느 위치에서든 데이터를 넣고 빼는 속도가 일정하고 매우 빠르다(위치를 알고 있을 경우)

주요 멤버함수

1. 생성자 / 초기화 / 할당

#include <iostream>
#include <list>
#include <string>
#include <vector>

// 리스트 내용을 출력하기 위한 템플릿 도우미 함수
template<typename T>
void print_list(const std::list<T>& l, const std::string& name)
{
    std::cout << name << ": [ ";
    for (const auto& item : l)
    {
        std::cout << item << " ";
    }
    std::cout << "]" << std::endl;
}

int main()
{
    // =================================================================
    // Part 1: std::list의 다양한 생성자 및 대입 연산자 
    // =================================================================
    std::cout << "--- Part 1: 생성자 및 대입 연산자 ---" << std::endl;

    // 1. 기본 생성자 : 빈 리스트 생성
    std::list<int> list1;
    print_list(list1, "1. 기본 생성자 list1");

    // 2. 크기 지정 생성자 : 10개의 아이템을 기본값 0으로 초기화
    std::list<int> list2(10);
    print_list(list2, "2. 크기 지정 list2(10)");

    // 3. 크기, 값 지정 생성자 : 10개의 아이템을 20으로 초기화
    std::list<int> list3(10, 20);
    print_list(list3, "3. 크기,값 지정 list3(10, 20)");

    // 4. 초기화 리스트 생성자
    std::list<int> list4 = { 1, 2, 3, 4, 5 };
    print_list(list4, "4. 초기화 리스트 list4");

    // 5. 범위 생성자 : 다른 컨테이너의 반복자 범위로 초기화
    std::list<int> list5(list4.begin(), list4.end());
    print_list(list5, "5. 범위 생성자 list5");

    // 6. 복사 생성자
    std::list<int> list6(list5);
    print_list(list6, "6. 복사 생성자 list6");

    // 7. 이동 생성자
    std::list<int> list7(std::move(list6));
    print_list(list7, "7. 이동 생성자 list7");
    print_list(list6, "   이동 후 list6 (내용이 비워짐)");

    // 8. 복사 대입 연산자
    std::list<int> list8;
    list8 = list7;
    print_list(list8, "8. 복사 대입 list8");

    // 9. 이동 대입 연산자
    std::list<int> list9;
    list9 = std::move(list7);
    print_list(list9, "9. 이동 대입 list9");
    print_list(list7, "   이동 후 list7 (내용이 비워짐)");

    // 10. 초기화 리스트 대입
    list9 = { 1, 2, 3, 4, 5, 6 };
    print_list(list9, "10. 초기화 리스트 대입 list9");

    // =================================================================
    // Part 2: assign() 멤버 함수
    // =================================================================
    std::cout << "\n--- Part 2: assign() 멤버 함수 ---" << std::endl;
    // assign() : list의 기존 내용을 지우고 새롭게 할당

    std::list<std::string> str_list = { "청새치","공상어","갈치","삼치","꽁치","상어","고래" };
    std::list<int> int_list1 = { 1,2,3,4,5,6,7,8,10,11,12,13,14,15,16 };
    std::list<int> int_list2 = { 6,5,4,3,2,1 };
    print_list(int_list1, "원본 int_list1");

    // 1. void assign(size_type count, const T& value) : count개 만큼 value 값으로 채우기
    int_list1.assign(10, 10);
    print_list(int_list1, "1. assign(10, 10) 후");

    // 2. template<class InputIt> void assign(InputIt first, InputIt last) : 반복자 범위로 할당
    print_list(int_list1, "원본 int_list1");
    print_list(int_list2, "복사할 int_list2");
    int_list1.assign(int_list2.begin(), int_list2.end());
    print_list(int_list1, "2. assign(범위) 후");

    // 3. void assign(std::initializer_list<T> ilist) : 초기화 리스트로 할당
    print_list(int_list2, "원본 int_list2");
    int_list2.assign({ 20, 43, 423, 324, 234 });
    print_list(int_list2, "3. assign(초기화 리스트) 후");

    // 시간 복잡도: O(N) - N은 새로 할당되는 요소의 개수

    return 0;
}

2. 접근자

#include <list>
#include <string>
#include <iostream>

int main()
{
    std::list<std::string> list1 = { "참다랑어","장어","곰장어","갈치","삼치","꽁치","상어","고래" };
    std::list<int> list2 = { 1,2,3,4,5,6,7,8,10,11,12,13,14,15,16 };

    // --- front() ---
    // front() : list의 맨 앞(첫 번째) 요소에 접근하는 함수
    //
    // reference front()
    // const_reference front() const
    // 반환값 : 첫 번째 요소의 참조 (reference)
    // 주의 : 빈 list에서 호출하면 정의되지 않은 동작(Undefined Behavior)을 일으킴
    if (!list1.empty()) // 안전하게 사용하기 위해 비어있는지 확인
    {
        std::string s1 = list1.front();
        std::cout << "list1.front() : " << s1 << std::endl;

        // front()가 반환하는 것은 참조이므로, 이를 통해 원본 값을 수정할 수 있음
        list1.front() = "대왕고래";
        std::cout << "첫 번째 요소 수정 후: " << list1.front() << std::endl;
    }

    // --- back() ---
    // back() : list의 맨 뒤(마지막) 요소에 접근하는 함수
    //
    // reference back()
    // const_reference back() const
    // 반환값 : 마지막 요소의 참조 (reference)
    // 주의 : 빈 list에서 호출하면 정의되지 않은 동작(Undefined Behavior)을 일으킴
    if (!list1.empty()) // 안전하게 사용하기 위해 비어있는지 확인
    {
        std::string s2 = list1.back();
        std::cout << "\nlist1.back() : " << s2 << std::endl;

        // back()이 반환하는 참조를 통해 원본 값을 수정
        list1.back() = "상괭이";
        std::cout << "마지막 요소 수정 후: " << list1.back() << std::endl;
    }

    return 0;
}

3. 조작(삽입)

#include <list>
#include <string>
#include <iostream>

// 리스트 내용을 출력하기 위한 도우미 함수
void print_list(const std::list<std::string>& l, const std::string& message)
{
    std::cout << "--- " << message << " ---" << std::endl;
    std::cout << "[ ";
    for (const auto& val : l)
    {
        std::cout << "\"" << val << "\" ";
    }
    std::cout << "]" << std::endl << std::endl;
}

int main()
{
    std::list<int> list1 = { 1,3,5 };
    std::list<std::string> list2; // 초기에는 비어있음
    std::list<std::string> list3 = { "참다랑어","장어","곰장어" };

    // --- push_front / push_back ---
    // push_front(value) : 맨 앞에 요소 추가
    // 반환값 : void
    // 시간 복잡도: O(1)
    list1.push_front(7); // list1: [ 7 1 3 5 ]

    // push_back(value) : 맨 뒤에 요소 추가
    // 반환값 : void
    // 시간 복잡도: O(1)
    list1.push_back(9); // list1: [ 7 1 3 5 9 ]

    // --- emplace_front / emplace_back ---
    // emplace_front() : 맨 앞에 요소를 직접 생성하여 추가
    // 복사 없이 직접 객체 생성
    // 반환값 : C++11: void 반환, C++17 이후: 추가된 요소에 대한 참조 반환(std::string&)
    list2.emplace_front("갈치");
    print_list(list2, "emplace_front(\"갈치\") 후");

    // emplace_back() : 리스트의 맨 뒤에 요소를 직접 생성하여 추가
    // 복사 없이 직접 객체 생성
    // 반환값 : C++11: void 반환, C++17 이후: 추가된 요소에 대한 참조 반환(std::string&)
    list2.emplace_back("아귀상어");
    print_list(list2, "emplace_back(\"아귀상어\") 후");

    // --- insert() : list의 특정 위치에 요소를 삽입 ---
    // 용도: 리스트의 특정 위치에 요소 삽입
    // 유연성: 단일/다중/범위 삽입 모두 가능
    // 효율성: std::list는 중간 삽입이 효율적 (O(1))
    // 반환값: 삽입된 요소의 iterator 반환

    // 1. 단일 요소 삽입
    // iterator insert(const_iterator pos, const T& value);
    // iterator insert(const_iterator pos, T&& value);
    list2.insert(list2.begin(), "꽁치");
    print_list(list2, "1. 맨 앞에 \"꽁치\" insert 후");

    // 2. 여러 개의 같은 값 삽입
    // iterator insert(const_iterator pos, size_type count, const T& value);
    list2.insert(list2.end(), 2, "해파리");
    print_list(list2, "2. 맨 뒤에 \"해파리\" 2개 insert 후");

    // 3. 범위 삽입
    // template<class InputIt>
    // iterator insert(const_iterator pos, InputIt first, InputIt last);
    list2.insert(list2.end(), list3.begin(), list3.end());
    print_list(list2, "3. 맨 뒤에 list3의 모든 요소 insert 후");

    // 4. 초기화 리스트 삽입 (C++11)
    // iterator insert(const_iterator pos, std::initializer_list<T> ilist);
    list2.insert(list2.begin(), { "기름치","조개","새우","왕새우","가재" });
    print_list(list2, "4. 맨 앞에 초기화 리스트 insert 후");

    // --- emplace() ---
    // template<class... Args>
    // iterator emplace(const_iterator pos, Args&&... args);
    // emplace() : list의 특정 위치에 객체(요소)를 직접 생성하여 삽입
    // 반환값: 삽입된 요소를 가리키는 iterator
    // 용도: 리스트의 특정 위치에 효율적으로 요소 삽입
    // 장점: 불필요한 복사/이동 제거
    // 권장: 복잡한 객체나 성능이 중요한 경우 insert() 대신 사용
    list2.emplace(list2.begin(), "구피");
    print_list(list2, "맨 앞에 \"구피\" emplace 후");

    // --- 최종 출력 ---
    std::cout << "===== 최종 list2 내용 =====" << std::endl;
    for (const auto& val : list2)
    {
        std::cout << val << " ";
    }
    std::cout << std::endl;

    return 0;
}

4. 조작(삭제)

#include <list>
#include <string>
#include <iostream>
#include <iterator> // std::advance를 위해 필요

// 리스트 내용을 출력하기 위한 도우미 함수
template<typename T>
void print_list(const std::list<T>& l, const std::string& message)
{
    std::cout << "--- " << message << " ---" << std::endl;
    std::cout << "[ ";
    for (const auto& val : l)
    {
        std::cout << val << " ";
    }
    std::cout << "]" << std::endl << std::endl;
}

int main()
{
    const std::list<std::string> original_list1 = { "참다랑어","장어","곰장어","갈치","삼치","꽁치","상어","고래" };
    const std::list<int> original_list2 = { 1,2,3,4,5,6,7,8,10,11,12,13,14,15,16 };

    // --- pop_front() / pop_back() ---
    {
        std::list<std::string> list1 = original_list1;
        print_list(list1, "pop_front/back 전 원본 list1");

        // void pop_front() : list의 맨 앞 요소를 제거
        // 반환값: 없음 (void)
        // 주의: 빈 list에서 호출하면 정의되지 않은 동작(Undefined Behavior)
        // 성능: O(1) - 매우 효율적
        list1.pop_front();
        print_list(list1, "pop_front() 후");

        // void pop_back() : list의 맨 뒤 요소를 제거
        // 반환값: 없음 (void)
        // 주의: 빈 list에서 호출하면 정의되지 않은 동작(Undefined Behavior)
        // 성능: O(1) - 매우 효율적
        list1.pop_back();
        print_list(list1, "pop_back() 후");
    }

    // --- erase() : list의 특정 위치 또는 범위의 요소를 제거 ---
    {
        // 1. 단일 요소 제거
        std::list<std::string> list1 = original_list1;
        print_list(list1, "erase(단일) 전 원본 list1");
        // iterator erase(const_iterator pos);
        // 반환값: 제거된 요소 다음 위치의 iterator
        list1.erase(list1.begin()); // 맨 앞의 "참다랑어" 제거
        print_list(list1, "erase(list1.begin()) 후");

        // 2. 범위 제거
        list1 = original_list1; // 리스트 초기화
        print_list(list1, "erase(범위) 전 원본 list1");
        // iterator erase(const_iterator first, const_iterator last);
        // [first, last) 범위의 요소를 제거. last는 포함되지 않음.
        std::list<std::string>::iterator first = list1.begin();
        std::list<std::string>::iterator last = list1.begin();
        std::advance(last, 3); // last를 3칸 뒤로 이동 (begin() + 3 위치)
        list1.erase(first, last); // 0, 1, 2번 인덱스 요소 제거
        print_list(list1, "erase(begin, begin+3) 후");
    }

    // --- remove() : 특정 값과 일치하는 모든 요소를 제거 ---
    {
        std::list<std::string> list_with_duplicates = {"상어", "고래", "상어", "돌고래", "상어"};
        print_list(list_with_duplicates, "remove() 전 원본");
        // void remove(const T& value);
        // 반환값: 없음 (void)
        // 성능: O(n) - 리스트를 한 번 순회
        list_with_duplicates.remove("상어");
        print_list(list_with_duplicates, "remove(\"상어\") 후");
    }

    // --- remove_if() : 특정 조건을 만족하는 모든 요소를 제거 ---
    {
        std::list<int> list2 = original_list2;
        print_list(list2, "remove_if() 전 원본 list2");
        // template<class Predicate>
        // void remove_if(Predicate pred);
        // 매개변수: 조건을 판단하는 함수/람다/함수 객체
        // 반환값: 없음 (void)
        // 동작: 조건이 true인 모든 요소를 제거
        int comp = 5;
        // 5보다 작은 요소 삭제
        list2.remove_if([comp](int a) { return a < comp; });
        print_list(list2, "5보다 작은 요소를 remove_if() 후");
    }

    // --- clear() : list의 모든 요소를 제거 ---
    {
        std::list<std::string> list1 = original_list1;
        print_list(list1, "clear() 전 원본 list1");
        // void clear();
        // 반환값: 없음 (void)
        list1.clear();
        print_list(list1, "clear() 후");
    }

    return 0;
}

5. 용량

#include <list>
#include <string>
#include <iostream>

// 리스트 내용을 출력하기 위한 도우미 함수
template<typename T>
void print_list_info(const std::list<T>& l, const std::string& name)
{
    std::cout << "--- " << name << " 정보 ---" << std::endl;
    std::cout << "내용: [ ";
    for (const auto& val : l)
    {
        std::cout << val << " ";
    }
    std::cout << "]" << std::endl;
    std::cout << "size(): " << l.size() << std::endl;
    std::cout << "empty(): " << (l.empty() ? "true" : "false") << std::endl;
    std::cout << std::endl;
}

int main()
{
    std::list<std::string> list1 = { "참다랑어","장어","곰장어","갈치","삼치","꽁치","상어","고래" };
    std::list<int> list2 = { 1,2,3,4,5,6,7,8,10,11,12,13,14,15,16 };

    // --- size_type size() const ---
    // list에 포함된 요소의 개수를 반환
    // 반환값 : 요소의 개수 (size_type, 일반적으로 size_t)
    // 시간복잡도 : O(1)
    size_t s1 = list1.size();
    std::cout << "list1.size() : " << s1 << std::endl;

    // --- bool empty() const ---
    // list가 비어있는지 확인
    // 반환값 : 비어있으면 true, 요소가 있으면 false
    // 시간복잡도 : O(1)
    bool b1 = list2.empty();
    std::cout << "list2.empty() : " << (b1 ? "true" : "false") << std::endl;

    // --- size_type max_size() const ---
    // list가 이론적으로 담을 수 있는 최대 요소 개수를 반환
    // 반환값 : 최대 가능한 요소 개수 (size_type, 일반적으로 size_t)
    // 시간복잡도 : O(1)
    // 주의 : 실제 할당 가능한 메모리와는 다름. 시스템 아키텍처에 따른 이론적 한계치.
    size_t s2 = list1.max_size();
    std::cout << "list1.max_size() : " << s2 << " (이론적 최대치)" << std::endl;
    std::cout << std::endl;

    // --- resize() : list의 크기를 변경 ---
    // void resize(size_type count)
    // void resize(size_type count, const value_type& value)
    // count : 새로운 크기
    // value : 크기가 늘어날 경우 추가될 요소의 값 (선택적)
    // 반환값 : 없음 (void)
    // 시간복잡도 : O(n) - n은 추가/제거되는 요소 개수
    // 용도 : 리스트를 특정 크기로 정확하게 맞춰야 할 때 매우 유용

    print_list_info(list2, "resize() 전 list2");

    // 1. 현재 크기(16)보다 크게 만들기
    list2.resize(20, 99); // 20개로 늘리고, 추가된 요소는 99로 채움
    print_list_info(list2, "resize(20, 99) 후 list2");

    // 2. 현재 크기(20)보다 작게 만들기
    list2.resize(10); // 뒤에서부터 요소가 제거되어 10개로 줄어듦
    print_list_info(list2, "resize(10) 후 list2");

    // 3. 값을 지정하지 않고 크게 만들기
    list2.resize(15); // 추가된 요소들은 기본값(int의 경우 0)으로 채워짐
    print_list_info(list2, "resize(15) 후 list2");

    return 0;
}

6. 반복자

#include <list>
#include <string>
#include <iostream>

int main()
{
    std::list<int> list3 = { 6, 5, 4, 3, 2, 1 };

    std::cout << "원본 리스트: [ 6 5 4 3 2 1 ]" << std::endl;
    std::cout << "------------------------------------" << std::endl;

    // ======================================================
    // 1. 정방향 반복자 (Forward Iterators)
    // ======================================================

    // begin() : 첫 번째 요소를 가리키는 반복자
    // cbegin() : 첫 번째 요소를 가리키는 읽기 전용(const) 반복자
    auto it_begin = list3.begin();
    auto cit_begin = list3.cbegin();
    std::cout << "begin()이 가리키는 값: " << *it_begin << std::endl;
    std::cout << "cbegin()이 가리키는 값: " << *cit_begin << std::endl;
    // *it_begin = 60; // 가능: 일반 반복자로는 값 수정 가능
    // *cit_begin = 60; // 컴파일 에러: const 반복자로는 값 수정 불가능

    // end() : 마지막 요소 '다음'을 가리키는 반복자 (sentinel)
    // cend() : 마지막 요소 '다음'을 가리키는 읽기 전용(const) 반복자
    // 주의: end()가 가리키는 위치에는 유효한 요소가 없으므로 역참조(*it_end)하면 안됨!
    std::cout << "\n[정방향 순회] (begin -> end)" << std::endl;
    for (auto it = list3.begin(); it != list3.end(); ++it)
    {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    // ======================================================
    // 2. 역방향 반복자 (Reverse Iterators)
    // ======================================================
    std::cout << "\n------------------------------------" << std::endl;

    // rbegin() : 역방향 순회의 시작 (즉, 원본 리스트의 '마지막' 요소)을 가리키는 반복자
    // crbegin() : 역방향 순회의 시작을 가리키는 읽기 전용(const) 반복자
    auto it_rbegin = list3.rbegin();
    auto cit_rbegin = list3.crbegin();
    std::cout << "rbegin()이 가리키는 값: " << *it_rbegin << std::endl;
    std::cout << "crbegin()이 가리키는 값: " << *cit_rbegin << std::endl;

    // rend() : 역방향 순회의 끝 (즉, 원본 리스트의 '첫 번째' 요소 '이전')을 가리키는 반복자
    // crend() : 역방향 순회의 끝을 가리키는 읽기 전용(const) 반복자
    // 주의: rend() 역시 유효한 요소를 가리키지 않으므로 역참조하면 안됨!
    std::cout << "\n[역방향 순회] (rbegin -> rend)" << std::endl;
    for (auto it = list3.rbegin(); it != list3.rend(); ++it)
    {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    return 0;
}

7. 기타

#include <iostream>
#include <list>
#include <string>

// 리스트 내용을 간편하게 출력하기 위한 도우미 함수
template<typename T>
void print_list(const std::list<T>& l, const std::string& name)
{
    std::cout << name << " (" << l.size() << "개): [ ";
    for (const auto& item : l)
    {
        std::cout << item << " ";
    }
    std::cout << "]" << std::endl;
}

int main()
{
    // =================================================================
    // 1. sort() : list의 요소를 정렬
    // =================================================================
    std::cout << "--- 1. sort() ---" << std::endl;
    {
        std::list<int> list_to_sort = { 32, 582, 23, 421, 2, 213, 4, 334, 42, 38, 876, 7, 576 };
        print_list(list_to_sort, "정렬 전");

        // 기본 sort() : 오름차순 정렬 (< 연산자 사용)
        list_to_sort.sort();
        print_list(list_to_sort, "기본 sort() (오름차순) 후");

        // 사용자 정의 비교 함수를 사용한 sort() : 내림차순 정렬
        list_to_sort.sort([](const int& a, const int& b) { return a > b; });
        print_list(list_to_sort, "사용자 정의 sort() (내림차순) 후");
        std::cout << std::endl;
    }

    // =================================================================
    // 2. reverse() : list의 요소 순서를 반대로 뒤집음
    // =================================================================
    std::cout << "--- 2. reverse() ---" << std::endl;
    {
        std::list<int> list_to_reverse = { 32, 582, 23, 421, 2, 213 };
        print_list(list_to_reverse, "뒤집기 전");

        // reverse() : 요소 복사 없이 내부 포인터만 재연결하므로 매우 빠름 (O(n))
        list_to_reverse.reverse();
        print_list(list_to_reverse, "reverse() 후");
        std::cout << std::endl;
    }

    // =================================================================
    // 3. unique() : 연속된 중복 요소를 제거
    // =================================================================
    std::cout << "--- 3. unique() ---" << std::endl;
    {
        // unique()는 '연속된' 중복만 제거하므로, 모든 중복을 제거하려면 먼저 정렬해야 함
        std::list<int> list_to_unique = { 1, 2, 1, 2, 2, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7 };
        print_list(list_to_unique, "정렬 전 원본");
        list_to_unique.sort();
        print_list(list_to_unique, "정렬 후");

        // 기본 unique() : 바로 옆 요소와 같은지(==) 비교하여 제거
        list_to_unique.unique();
        print_list(list_to_unique, "기본 unique() 후");

        // 사용자 정의 비교 함수를 사용한 unique()
        std::list<int> list2 = { 1, 2, 4, 5, 7, 8, 10 };
        print_list(list2, "\n다른 리스트 원본");
        // 예: 차이가 1 이하인 연속된 요소들을 제거 (2와 1, 5와 4, 8과 7이 제거됨)
        list2.unique([](const int& a, const int& b) { return std::abs(a - b) <= 1; });
        print_list(list2, "차이가 1 이하인 요소 unique() 후");
        std::cout << std::endl;
    }

    // =================================================================
    // 4. merge() : 두 개의 '정렬된' 리스트를 병합
    // =================================================================
    std::cout << "--- 4. merge() ---" << std::endl;
    {
        std::list<int> list_main = { 1, 5, 9, 12 };
        std::list<int> list_sub = { 2, 3, 8, 10 };
        print_list(list_main, "병합 전 list_main");
        print_list(list_sub, "병합 전 list_sub");

        // list_main으로 list_sub의 요소들을 '이동'시켜 병합. list_sub는 비워짐.
        // 두 리스트 모두 같은 기준으로 정렬되어 있어야 함 (기본: 오름차순)
        list_main.merge(list_sub);
        print_list(list_main, "merge() 후 list_main");
        print_list(list_sub, "merge() 후 list_sub (비워짐)");
        std::cout << std::endl;
    }

    // =================================================================
    // 5. splice() : 다른 list의 요소를 복사 없이 '이동'
    // =================================================================
    std::cout << "--- 5. splice() ---" << std::endl;
    {
        std::list<int> dest_list = { 100, 200 };
        std::list<int> source_list1 = { 1, 2, 3 };
        std::list<int> source_list2 = { 10, 20, 30, 40, 50 };
        print_list(dest_list, "초기 dest_list");
        print_list(source_list1, "초기 source_list1");
        print_list(source_list2, "초기 source_list2");
        std::cout << std::endl;

        // 1. 리스트 전체 이동: source_list1의 모든 요소를 dest_list의 끝으로 이동
        dest_list.splice(dest_list.end(), source_list1);
        print_list(dest_list, "1. source_list1 전체 splice 후");
        print_list(source_list1, "   -> source_list1 (비워짐)");

        // 2. 단일 요소 이동: source_list2의 첫 번째 요소를 dest_list의 처음으로 이동
        dest_list.splice(dest_list.begin(), source_list2, source_list2.begin());
        print_list(dest_list, "\n2. source_list2의 첫 요소 splice 후");
        print_list(source_list2, "   -> source_list2");

        // 3. 범위 이동: source_list2의 남은 요소들을 dest_list의 끝으로 이동
        dest_list.splice(dest_list.end(), source_list2, source_list2.begin(), source_list2.end());
        print_list(dest_list, "\n3. source_list2의 나머지 범위 splice 후");
        print_list(source_list2, "   -> source_list2 (비워짐)");
    }

    return 0;
}

0개의 댓글