List의 주요 인터페이스와 특징 접기
[ list의 템플릿 형식 ]
템플릿 형식
Template<typename T, typename Alloctor = allocator<T>>
class list
T는 list 컨테이너 원소의 형식
[ list의 인터페이스 ]
생성자
list lt
lt는 빈 컨테이너이다.
list lt(n)
lt는 기본값으로 초기화된 n개의 원소를 갖는다.
list lt(n,x)
lt는 x값으로 초기화된 n개의 원소를 갖는다.
list lt(lt2)
lt는 lt2 컨테이너의 복사본이다(복사 생성자 호출).
list lt(b,e)
lt는 반복자 구간[b,e)로 초기화된 원소를 갖는다.
멤버 함수
lt.assign(n,x)
lt에 x값으로 n개의 원소를 할당한다.
lt.assign(b,e)
lt를 반복자 구간[b,e)로 할당한다.
lt.back()
lt의 마지막 원소를 참조한다(const, 비 const 버전이 있음)
p=lt.begin()
p는 lt의 첫 원소를 가리키는 반복자(const, 비 const 버전이 있음)
lt.clear()
lt는 모든 원소를 제거한다.
lt.empty()
lt가 비었는지 조사한다.
p=lt.end()
p는 lt의 끝을 표식하는 반복자이다(const, 비 const버전이 있음)
q=lt.erase(p)
p가 가리키는 원소를 제거한다. q는 다음 원소를 가리킨다.
q=lt.erase(b,e)
반복자 구간[b,e)의 모든 원소를 제거한다. q는 다음 원소.
lt.front()
lt의 첫 번째 원소를 참조한다.(const, 비 const 버전이 있음)
q=lt.insert(p,x)
p가 가리키는 위치에 x값을 삽입한다. q는 삽입한 원소를 가리키는 반복자이다.
lt.insert(p,n,x)
p가 가리키는 위치에 n가의 x값을 삽입한다.
lt.insert(p,b,e)
p가 가리키는 위치에 반복자 구간[b,e)의 원소를 삽입한다.
x=lt.max_size()
x는 lt가 담을 수 있는 최대 원소의 개수다(메모리의 크기)
lt.merge(lt2)
lt2를 lt로 합병 정렬한다(오름차 순: less);
lt.merge(lt2,pred)
lt2를 lt로 합병 정렬한다. pred(조건자)를 기준으로 합병한다(predsms 이항 조건자))
lt.pop_back()
lt의 마지막 원소를 제거한다.
lt.pop_front()
lt의 첫 원소를 제거한다.
lt.push_back(x)
lt의 끝에 x를 추가한다.
lt.push_back(x)
lt의 앞쪽에 x를 추가한다.
p=lt.rbegin()
p는 lt의 역 순차열의 첫 원소를 가리키는 반복자다(const 비 const 버전이 있음)
lt.remove(x)
x 원소를 모두 제거한다.
lt.remove_if(pred)
pred(단항 조건자)가 ‘참’인 모든 원소를 제거한다.
p=lt.rend()
p는 lt의 역 순차열의 끝을 표식하는 반복자(const 비 const 버전이 있음)
lt.rsize(n)
lt의 크기를 n으로 변경하고 확장되는 공간의 값을 기본값으로 초기화 한다.
lt.rsize(n,x)
lt의 크기를 n으로 변경하고 확장되는 공간의 값을 x값으로 초기화 한다.
lt.size()
lt 원소의 개수다.
lt.reverse()
lt 순차열을 뒤집는다.
lt.swap(lt2)
lt와 lt2를 swap한다.
lt.sort()
lt의 모든 원소를 오름차 순(less)으로 정렬한다.
lt.sort(pred)
lt의 모든 원소를 pred(조건자)를 기준으로 정렬한다. pred(조건자)는 이항 조건자다.
lt.splice(p,lt2)
p가 가리키는 위치에 lt2의 모든 원소를 잘라 붙인다.
lt.splice(p,lt2,q)
p가 가리키는 위치에 lt2의 q가 가리키는 원소를 잘라 붙인다.
lt.splice(p,lt2,b,e)
p가 가리키는 위치에 lt2의 순차열[b,e)를 잘라 붙인다.
lt.unique()
인접한 원소의 값이 같다면 유일한 원소의 순차열로 만든다.
lt.unique(pred)
인접한 원소가 pred(이항조건자)의 기준에 맞다면 유일한 원소의 순차열을 만든다.
연산자
lt1 == lt2
lt1과 lt2의 모든 원소가 같은가(bool형식)
lt1 != lt2
lt1과 lt2의 모든 원소 중 하나라도 다른 원소가 있는가? (bool형식)
lt1 < lt2
문자열 비교처럼 lt2가 lt1보다 큰가? (bool형식)
lt1 <= lt2
문자열 비교처럼 lt2가 lt1보다 크거나 같은가? (bool 형식)
lt1 > lt2
문자열 비교처럼 lt1이 lt2보다 큰가? (bool형식)
lt1 >= lt2
문자열 비교처럼 lt1이 lt2보다 크거나 같은가? (bool 형식)
[ list의 템플릿 멤버 형식 ]
멤버 형식
allocator_type
메모리 관리자 형식
const_iterator
const 반복자 형식
const_pointer
const value_type* 형식
const_reference
const value_type& 형식
const_relterse_iterator
const 역 반복자 형식
difference_type
두 반복자 사이의 형식
iterator
반복자 형식
pointer
value_typr* 형식
reference
value_typr& 형식
relterse_iterator
역 반복자 형식
size_type
첨자(index)나 원소의 개수 등의 형식
value_type
원소의 형식
접기
list는 시퀀스 컨테이이며, 노드 기반 컨테이너로 원소가 노드 단위로 저장되며 list는 이중 연결 리스트(Double Linked List)로 구현됩니다.
list는 시퀀스 컨테이너가 갖는 모든 특징을 갖습니다. (push_front, push_back, pop_front, pop_back, front, back, insert, erase )
순차열 중간에 삽입, 제거가 빈번하게 발생하며, 원소의 상대적인 순서가 중요하다면 list 컨테이너를 사용합니다.
list는 노드 기반 컨테이너로 at()과 []연산자가 없으며 임의 접근 반복자가 아닌 양방향 반복자를 제공합니다.
그래서 모든 원소를 탐색하려면 양방향 반복자의 연산인 ++, -- 를 사용합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <list>
using namespace std;
int main(){
list<int > lt;
lt.push_back(10);
lt.push_back(20);
lt.push_back(30);
lt.push_back(40);
lt.push_back(50);
list<int >::iterator Iter = lt.begin();
for ( ; Iter != lt.end(); ++Iter){
cout<< *Iter <<" " ;
}
cout<<endl;
lt.push_front(100); //앞쪽에 추가
lt.push_front(200);
for (Iter = lt.begin(); Iter != lt.end(); ++Iter){
cout<< *Iter <<" " ; // 200 100 10 20 30 40 50
}
system("pause" );
return 0;
}
list의 가장 큰 특징 중 하나는 순차열 중간에 원소를 삽입(insert), 제거(erase)하더라도 상수 시간 복잡도의 수행 성능을 보인다는 점입니다. 이유는 배열 기반 컨테이너 vector나 deque처럼 원소를 밀어내지 않고 노드를 서로 연결하기만 하며녀 되기 때문입니다.
또한, 노드 기반 컨테이너의 삽입(insert)과 제거(erase) 동작은 반복자를 무효화 시키지 않습니다. 반복자가 가리키는 원소 자체가 제거되지 않는 한 반복자가 가리키는 원소는 그대로 존재합니다. 하지만, 배열 기반 컨테이너(vector, deque)의 반복자는 원소의 삽입과 제거 동작이 발생하면 "메모리가 재할당되거나 원소가 이동" 할 수 있으므로 반복자가 무효화 됩니다.
[ 반복자 무효화 현상 ]
: 반복자가 가리키고 있는 원소를 지웠을 때 반복자가 다음을 가르키지 못하는 현상
while( v1.empty() != true )
{
v1.erase(Iter);
Iter++; // erase삭제 후 현재 가르키는 위치가 무효화 되어 연산을 할 수 없다.
}
위의 예제처럼 주로 삭제시 발생하는데, 위의 에러를 방지 하려면, 아래와 같이 코딩 해야한다.
while( v1.empty() != true )
{
Iter = v1.erase(Iter);
}
[ 배열 기반 컨테이너 반복자 무효상태 ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int > lt;
lt.push_back(10);
lt.push_back(20);
lt.push_back(30);
lt.push_back(40);
lt.push_back(50);
vector<int >::iterator Iter = lt.begin();
Iter++;
Iter++; // 30을 가르킴
// 메모리 재할당으로 인한 반복자 무효화 상태
lt.push_back(60);
lt.push_back(70);
lt.push_back(80);
cout<<*Iter<<endl; // 에러발생
system("pause" );
return 0;
}
[ list의 insert(), erase() 멤버함수 ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <list>
using namespace std;
int main(){
list<int > lt;
lt.push_back(10);
lt.push_back(20);
lt.push_back(30);
lt.push_back(40);
lt.push_back(50);
list<int >::iterator Iter = lt.begin();
Iter++;
Iter++; // 30을 가르킴
// vector와 다르게 반복자 무효화 현상은 잃어 나지 않음
lt.push_back(60);
lt.push_back(70);
lt.push_back(80);
//30이 삭제되고 40을 가리키는 반복자 리턴
Iter = lt.erase(Iter);
lt.insert(Iter, 30); // 40의 앞쪽에 30을 넣는다.
Iter = lt.begin();
while ( Iter != lt.end() ){
cout<< *(Iter++) <<endl;
}
system("pause" );
return 0;
}
위의 예제에서 insert(), erase() 사용법과, 반복자의 무효화 현상이 일어나지 않음을 확인할 수 있다.
list는 노드단위로 생성되어 Iter가 가르키는 위치에 노드하나만 연결만 시켜주기때문에 속도가 빠르며, 반복자들이 무효화 되지 않습니다.
즉! 각각의 노드단위로 구성되어있기때문에, 가르키는 노드가 삭제되지 않는 한 무효화 되지 않는다고 보면 된다.
[ list의 remove() 멤버 함수 ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <list>
using namespace std;
int main(){
list<int > lt;
lt.push_back(10);
lt.push_back(20);
lt.push_back(30);
lt.push_back(40);
lt.push_back(10);
lt.push_back(30);
lt.push_back(10);
lt.push_back(40);
lt.push_back(10);
lt.push_back(10);
list<int >::iterator Iter = lt.begin();
lt.remove(10); // 10 원소의 노드를 모두 제거 한다.
Iter = lt.begin();
while ( Iter != lt.end() ){
cout<< *(Iter++) <<endl;
}
system("pause" );
return 0;
}
list의 remove() 함수는 컨테이너의 모든 원소를 순차적으로 검색하며, 해당원소를 제거 합니다.
또한, list만이 remove() 멤버함수를 유일하게 가지고, erase()처럼 해당 값의 노드만을 제거하므로 속도가 빠르다.
반복자가 아닌 원소의 값으로 컨테이너의 원소를 제거해야 한다면 list 컨테이너를 선택하는 것이 좋습니다.
[ list의 remove_if() 멤버 함수 ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <list>
using namespace std;
bool predicate( int n ) // 단항 조건자
{
return 10 <= n && n <= 30;
}
int main(){
list<int > lt;
lt.push_back(10);
lt.push_back(20);
lt.push_back(30);
lt.push_back(40);
lt.push_back(50);
lt.push_back(10);
lt.push_back(10);
lt.push_back(10);
lt.push_back(10);
list<int >::iterator Iter = lt.begin();
while ( Iter != lt.end() ){
cout<< *(Iter++) <<" " ;
}
cout<<endl;
// 조건자가 참인 모든 원소를 제거
lt.remove_if(predicate);
Iter = lt.begin();
while ( Iter != lt.end() ){
cout<< *(Iter++) <<" " ;
}
cout<<endl;
system("pause" );
return 0;
}
remove_if() 멤버함수는 단항 조건자가 참인 모든 원소를 제거합니다. 조건자는 bool 형식을 반환하는 함수류( 함수, 함수객체, 함수 포인터) 입니다.
[ list의 splice() 멤버 함수 ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include <iostream>
#include <list>
using namespace std;
int main(){
list<int > lt;
list<int > lt2;
lt.push_back(10);
lt.push_back(20);
lt.push_back(30);
lt.push_back(40);
lt.push_back(50);
lt2.push_back(100);
lt2.push_back(200);
lt2.push_back(300);
lt2.push_back(400);
lt2.push_back(500);
list<int >::iterator Iter = lt.begin();
cout<<"lt1 : " ;
while ( Iter != lt.end() ){
cout<< *(Iter++) <<" " ; //10 20 30 40 50
}
cout<<endl;
Iter = lt2.begin();
cout<<"lt2 : " ;
while ( Iter != lt2.end() ){
cout<< *(Iter++) <<" " ; //100 200 300 400 500
}
cout<<endl << "=====================" <<endl;
Iter = lt.begin();
++Iter;
++Iter; // lt의 30을 가르킴
list<int >::iterator Iter2 = lt2.begin();
++Iter2; // lt2의 200을 가르킴
// splice() 1번 방법 반복자가 가리키는 원소를 잘라붙임
// Iter가 가리키는 위치에 Iter2가 가리키는 위치의 lt2의 원소를 잘라붙임
lt.splice(Iter, lt2, Iter2);
Iter = lt.begin();
cout<<"lt1 : " ;
while ( Iter != lt.end() ){
cout<< *(Iter++) <<" " ; //10 20 200 30 40 50
}
cout<<endl;
Iter2 = lt2.begin();
cout<<"lt2 : " ;
while ( Iter2 != lt2.end() ){
cout<< *(Iter2++) <<" " ;
}
cout<<endl << "=====================" <<endl;
// splice() 2번 list의 순차열을 잘라 붙임
// lt.end()가 가리키는 위치에 순차열 [lt2.begin(), lt2.end())를 잘라붙임
lt.splice(lt.end(), lt2, lt2.begin(), lt2.end() );
Iter = lt.begin();
cout<<"lt1 : " ;
while ( Iter != lt.end() ){
cout<< *(Iter++) <<" " ; //10 20 200 30 40 50 100 300 400 500
}
cout<<endl;
if ( lt2.empty() ){
cout<< "원소 없음!!" ;
}else {
Iter2 = lt2.begin();
cout<<"lt2 : " ;
while ( Iter2 != lt2.end() ){
cout<< *(Iter2++) <<" " ; // lt2의 순차열을 lt.end() 에 붙였기 때문에 lt2는 원소 없음
}
}
cout<<endl << "=====================" <<endl;
// splice() 3번 lt2의 모든 원소를 잘라 붙임
// Iter2가 가리키는 위치에 lt의 모든원소를 잘라 붙임
Iter2 = lt2.begin();
lt2.splice(Iter2, lt);
if ( lt.empty() ){
cout<< "원소 없음!!" ;
}else {
Iter = lt.begin();
cout<<"lt1 : " ;
while ( Iter != lt.end() ){
cout<< *(Iter++) <<" " ; //lt의 모든 원소를 lt2에 붙였기 때문에 lt는 원소 없음
}
}
cout<<endl;
Iter = lt2.begin();
cout<<"lt2 : " ;
while ( Iter != lt2.end() ){
cout<< *(Iter++) <<" " ; //10 20 200 30 40 50 100 300 400 500
}
cout<<endl;
system("pause" );
return 0;
}
[ 결과 ]
splice() 멤버함수는 다른 list 컨테이너의 순차열을 잘라 붙일 수 있습니다.
splice() 멤버함수는 상수 시간의 실행 동작을 보입니다. 이유는 lt와 lt2의 노드들을 단지 연결하기 때문 입니다.
[ list의 reverse() 멤버 함수 ]
1
2
//모든 원소를 뒤집는다.
lt.reverse();
reverse() 멤버 함순는 모든 원소의 순차열을 반대로 뒤집습니다.
reverse() 멤버 함수는 이중 연결 리스트의 탐색 경로를 서로 바꿈으로써 순차열을 리버스 시킵니다.
[ list의 unique() 멤버 함수 ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>
#include <list>
using namespace std;
//이항 조건자
bool predicate(int first, int second){
// 다음원소 - 현재 원소 <= 0
// 조건자 : 두원소의 차가 0보다 작거나 같으면
return second - first <= 0 ;
}
int main(){
list<int > lt;
lt.push_back(10);
lt.push_back(10);
lt.push_back(20);
lt.push_back(30);
lt.push_back(30);
lt.push_back(30);
lt.push_back(40);
lt.push_back(50);
lt.push_back(10);
for ( list<int >::iterator Iter = lt.begin(); Iter != lt.end(); ++Iter ){
cout<< *Iter <<" " ; // 10 10 20 30 30 30 40 50 10
}
cout<<endl;
// 1번 unique() 함수 사용법
// 인접한 같은 원소를 유일하게 만듭니다. ( 10 20 30 40 50 10 )
// 연속된 같은 원소는 삭제하고 하나로 만듬
// 연속된 원소만 하나만 남긴다. 그래서 맨마지막 10이 남은것 이다.
lt.unique();
for ( list<int >::iterator Iter = lt.begin(); Iter != lt.end(); ++Iter ){
cout<< *Iter <<" " ;
}
cout<<endl;
cout<<endl;
//----------------------------------------------------------------------------
list<int > lt2;
lt2.push_back(10);
lt2.push_back(10);
lt2.push_back(20);
lt2.push_back(30);
lt2.push_back(30);
lt2.push_back(30);
lt2.push_back(40);
lt2.push_back(50);
lt2.push_back(10);
for ( list<int >::iterator Iter = lt2.begin(); Iter != lt2.end(); ++Iter ){
cout<< *Iter <<" " ; //10 10 20 30 30 30 40 50 10
}
cout<<endl;
// 2번 이항조건자를 이용한 unique() 함수 사용법
lt2.unique(predicate);
for ( list<int >::iterator Iter = lt2.begin(); Iter != lt2.end(); ++Iter ){
cout<< *Iter <<" " ; //10 20 30 40 50
}
cout<<endl;
system("pause" );
return 0;
}
unique() 멤버 함수는 인접한 같은 원소를 유일하게 만듭니다. ( 단! 연속되지 않으면 중복될 수 있음 )
[ list의 sort() 멤버 함수 ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <list>
using namespace std;
struct Greater{
bool operator () (int left, int right){
return left > right; // 내림차순 > 연산
}
};
int main(){
list<int > lt;
lt.push_back(20);
lt.push_back(10);
lt.push_back(50);
lt.push_back(30);
lt.push_back(40);
list<int >::iterator Iter;
for ( Iter = lt.begin(); Iter != lt.end(); ++Iter ){
cout<< *Iter <<" " ; // 20 10 50 30 40
}
cout<<endl;
// 1번 sort() 멤버함수 사용
lt.sort(); // 디폴트 : 오름차순(less)정렬 ( < 연산 )
for ( Iter = lt.begin(); Iter != lt.end(); ++Iter ){
cout<< *Iter <<" " ; // 10 20 30 40 50
}
cout<<endl;
cout<<endl;
//---------------------------------------------------------------
list<int > lt2;
lt2.push_back(20);
lt2.push_back(10);
lt2.push_back(50);
lt2.push_back(30);
lt2.push_back(40);
for ( Iter = lt2.begin(); Iter != lt2.end(); ++Iter ){
cout<< *Iter <<" " ;
}
cout<<endl;
// 2번 조건자사용 sort() 멤버함수 사용
// 참 이면 두원소(left, right)를 바꾸지않고, 거짓이면 바뀜
lt2.sort(Greater());
for ( Iter = lt2.begin(); Iter != lt2.end(); ++Iter ){
cout<< *Iter <<" " ;
}
cout<<endl;
system("pause" );
return 0;
}
정렬을 수행할 수 있는 컨테이너는 시퀀스 컨테이너( vector, deque, list ) 입니다.
연관 컨테이너는 자체 정렬 기준에 의해 자동정렬 됩니다.
vector와 deque은 알고리즘 함수 sort() 을 사용하여 정렬 할 수 있습니다.
하지만 list는 sort() 알고리즘을 수행할 수 없습니다.
sort() 알고리즘은 임의 접근 반복자( 대부분 quick sort로 구현됨 )를 지원하는 컨테이너만 사용 가능 하기 때문입니다.
그래서 list는 자체 정렬 멤버함수인 sort()를 제공합니다.
[ list의 merge() 멤버 함수 ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <iostream>
#include <list>
using namespace std;
int main(){
list<int > lt1;
lt1.push_back(10);
lt1.push_back(20);
lt1.push_back(30);
lt1.push_back(40);
lt1.push_back(50);
list<int > lt2;
lt2.push_back(25);
lt2.push_back(35);
lt2.push_back(45);
list<int >::iterator Iter;
for ( Iter = lt1.begin(); Iter != lt1.end(); ++Iter ){
cout<< *Iter <<" " ; // 10 20 30 40 50
}
cout<<endl;
for ( Iter = lt2.begin(); Iter != lt2.end(); ++Iter ){
cout<< *Iter <<" " ; // 25 35 45
}
cout<<endl<<"=============================" <<endl;
// 1번 merge() 멤버함수 사용
// lt2를 lt1으로 합병 정렬. 정렬 기준은 less 오름차순
// merge() 멤버함수는 lt1과 lt2가 오름차순 정렬되어있다고 가정하에 동작하며
// 결과도 오름차순 정렬됩니다.
lt1.merge(lt2);
for ( Iter = lt1.begin(); Iter != lt1.end(); ++Iter ){
cout<< *Iter <<" " ; // 10 20 25 30 35 40 45 50
}
cout<<endl;
if ( lt2.empty() ){
cout<<"비었음!!" ;
}else {
for ( Iter = lt2.begin(); Iter != lt2.end(); ++Iter ){
cout<< *Iter <<" " ;
}
}
cout<<endl<<"=============================" <<endl;
cout<<endl;
list<int > lt3;
lt3.push_back(50);
lt3.push_back(40);
lt3.push_back(30);
lt3.push_back(20);
lt3.push_back(10);
list<int > lt4;
lt4.push_back(45);
lt4.push_back(35);
lt4.push_back(25);
for ( Iter = lt3.begin(); Iter != lt3.end(); ++Iter ){
cout<< *Iter <<" " ; // 50 40 30 20 10
}
cout<<endl;
for ( Iter = lt4.begin(); Iter != lt4.end(); ++Iter ){
cout<< *Iter <<" " ; // 45 35 25
}
cout<<endl<<"=============================" <<endl;
// 2번 이항 조건자 사용 merge()멤버함수
// lt3과 lt4의 정렬기준이 내림차순 같아야 한다. 아니면 오류
// 두 list의 정렬기준이 greater( > 연산)라는 것을 predicate로 지정
lt3.merge(lt4, greater<int >());
for ( Iter = lt3.begin(); Iter != lt3.end(); ++Iter ){
cout<< *Iter <<" " ; // 50 45 40 35 30 25 20 10
}
cout<<endl;
if ( lt4.empty() ){
cout<<"비었음!!" ;
}else {
for ( Iter = lt4.begin(); Iter != lt4.end(); ++Iter ){
cout<< *Iter <<" " ;
}
}
cout<<endl;
system("pause" );
return 0;
}
merge() 멤버 함수는 두 list를 합병합니다.
merge() 멤버 함수는 정렬된 두 list를 하나의 정렬된 list로 합병하므로 합병할 두 list는 정렬 되어 있어야 합니다.
만약 정렬 기준이 틀렸거나 합병할 list가 정렬돼 있지 않았다면 merge() 멤버 함수는 실패하며 오류가 발생합니다.
반드시 정렬 되어 있어야 합니다.
vector의 erase()와 list의 erase()의 차이점
: vector의 erase()는 제거하는 원소 다음의 모든 원소를 앞쪽으로 이동시켜야 하지만 list의 erase()는 제거하는 원소의 노드만 제거하면 됩니다.
vector의 insert()와 list의 insert()의 차이점
: erase()와 마찬가지로 vector의 insert()는 삽입하는 원소 다음의 모든 원소를 뒤쪽으로 이동시켜야 하지만, list의 erase()는 삽입하는 원소의 노드를 앞뒤로 연결하면 됩니다.
list의 insert() 멤버 함수와 splice() 멤버 함수의 차이점
: insert()는 원본(source)의 순차열에 변화가 없지만, splice()는 원본(source)의 순차열을 잘라내어 대상 순차열에 붙입니다.