반응형

Intro


안녕하세요. STL에서 기존에 리스트 자료구조를 사용하는 std::list가 있습니다. std::list가 일반적으로는 사용하기 편하지만, 양방향으로 데이터를 탐색할 필요가 없을 때에는 메모리 사용이나 처리 속도 면에서 아쉬운 점이 있습니다. 실제로 개발을 하다 보면 양방향 리스트가 필요한 경우보다는 단방향 리스트 만으로 충분한 경우가 많습니다. 그래서 이번 포스팅에서는 forward_list의 사용방법에 대해 다뤄보도록 하겠습니다.

forward_list


forward_list의 설계 방침

  • 특별한 이유가 없으면 forward_list는 기존 list 설계에 맞춘다.
  • 설계상 선택지가 여러 개이면 성능을 최우선으로 한다.
  • std::list의 insert와 erase를 forward_list에서 제공할 수 있지만, 구현이 복잡해지고 성능 면에서 좋지 않으므로 제공하지 않는다.
  • 다른 stl의 컨테이너에 있는 size 함수를 제공하지 않는다. 요소 수를 보존하는 멤버를 가지고 있으면 C 언어에서 구현한 것과 비교해서 불필요한 메모리를 사용하기 때문이다. forward_list와 list의 차이점 forward_list와 list의 차이점

STL의 list 컨테이너와 다른 점

  • forward_list는 단방향 리스트다. 각 요소는 기 다음 요소를 가리키는 포인터를 하나만 가지고 있다.(list는 양방향 리스트)
  • list에 비해서 메모리를 작게 사용한다. 각 요소의 메모리만이 아닌 컨테이너 그 자체의 사이즈도 작다. int형에 대해서 list가 12바이트라면 forwar_list는 8바이트이다.(32바이트 기준이고, 64바이트에서 list는 24바이트고 forward_list는 16바이트다.)
  • list보다 삽입/삭제 속도가 더 빠르지만, 차이는 크지 않다.
  • 한 방향으로만 이동할 수 있다.
  • 삽입과 삭제는 지정한 요소의 다음 요소에 한해서만 가능하다.
  • forward_list 사용하기forward_list 사용하기

forward_list 사용하기
list컨테이너와 forward_list는 크게 차이가 없습니다. 다만, forward_list는 단방향 리스트라는 것과 다른 컨테이너에서 지원하는 일부 기능이 없습니다. 그 점을 유의하셔야 합니다.

#include <iostream>
#include<forward_list>
using namespace std;
int main(void)
{

    forward_list<int> flist;
    forward_list<int> flist2;

    for (int i = 0;i < 5;i++)//0~4까지 forward_list에 입력
        flist.push_front(i);
    for (auto value : flist)
        cout << value << endl;

    flist2.assign(flist.begin(), flist.end());
    for (auto value : flist2)
        cout << value << endl;


}

결과

데이터 추가하기

  • insert_after : 저장된 위치 뒤에 새로운 데이터를 추가한다.
  • emplace_after : 지정된 위치 뒤에 새로운 데이터를 추가한다.
  • emplace_front : 맨 앞에 새로운 요소를 추가한다.
#include <iostream> 
#include<forward_list> 
using namespace std; i
nt main(void) 
{ 
    forward_list <int> flist; 
    forward_list <int> flist2; 
    forward_list <int> flist3; 
    for (int i = 0;i < 5;i++) 
    { 
        flist.push_front(i); 
        flist2.push_front(i); 
        flist3.push_front(i);
    }
    cout << "insert_after를 사용하여 추가" << endl;
    flist.insert_after(flist.begin(), 99);
    for (auto value : flist)
           cout << value << " ";
    cout << endl;
    cout << "emplace_after를 사용하여 추가" << endl;
    flist2.emplace_after(flist2.begin(), 99);
    for (auto value : flist2)
        cout << value << " ";;
    cout << endl;
    cout << "emplace_front를 사용하여 추가" << endl;
    flist3.emplace_front(99);
    for (auto value : flist3)
        cout << value << " ";
}

결과

데이터 삭제하기

  • pop_front : 첫 번째 위치의 데이터를 지운다.
  • rease_after : 지정된 위치 다음이나 지정된 위치 이후의 지정한 범위에 있는 모든 데이터를 지운다.

#include  
#include  
using namespace std;  
int main(void)  
{


forward_list<int> flist;
forward_list<int> flist2;
forward_list<int> flist3;

for (int i = 0;i < 5;i++)
{
    flist.push_front(i);
    flist2.push_front(i);
    flist3.push_front(i);
}

cout << "pop_font로 삭제" << endl;
flist.pop_front();
for (auto value : flist)
    cout << value << " ";;

cout << "erase_after로 삭제" << endl;
flist2.erase_after(flist2.begin());
for (auto value : flist2)
    cout << value << " ";;

cout << "erase_after로 범위를 지정하여 삭제" << endl;
flist3.erase_after(flist3.begin(), flist3.end());
for (auto value : flist3)
    cout << value << " ";;

}

결과

마무리


오늘은 forward_list에대해 포스팅했습니다. 이번 포스팅에서는 sort나 unique를 이용한 중복 제거, merge는 들어가지 않았습니다. 참조 부탁드립니다.
사실 forward_list는 list보다 성능면에서 이점이 있지만, 사용자가 사용하기에는 list가 편하긴 합니다.
그럼 이상으로 포스팅 마무리하겠습니다. 감사합니다.

반응형

+ Recent posts