'Programing/자료구조'에 해당되는 글 3건

  1. 2012.05.30 stl의 list 만들어 보기
  2. 2012.05.21 STL Vector와 List 차이점
  3. 2012.05.18 Big - O 표기법

template <class T>

class List

{

class Node

{

public:

Node* after;

Node* before;

T _data;

Node( T data = 0 )

{

after = NULL;

before = NULL;

_data = data;

}

};


Node* top;

Node* bottum;

int size;


public:

class Iter

{

Node* _pos;

friend class List;


public:

Iter( Node* pNode = NULL )

{

_pos = pNode;

}


Iter(const Iter &it)

{

_pos = it._pos;

}


void operator=( Iter it )

{

_pos = it._pos;

}


T operator*()

{

return _pos->_data;

}


T* operator->()

{

return &_pos->_data;

}


const bool operator==(Iter pIter)

{

return _pos == pIter._pos;

}


const bool operator!=(Iter pIter)

{

return _pos != pIter._pos;

}


void operator++(int)

{

if (_pos != NULL)

{

_pos = _pos->after;

}

}


void operator++()

{

if (_pos != NULL)

{

_pos = _pos->after;

}

}

};


List()

{

top = new Node();

bottum = new Node();

size = 0;

top->after = bottum;

bottum->before = top;

}


~List()

{

clean();

delete top;

delete bottum;

}


void clean()

{

Iter iter( begin() ); 

for ( iter; iter != end(); )

{

iter = eraser(iter);

}

}


Iter eraser( Iter pIter )

{

if (size > 0)

{

Node* pPos = pIter._pos;

if ( pPos->before )

pPos->before->after = pPos->after;

if ( pPos->after )

pPos->after->before = pPos->before;


Node* pCurrnet = pPos->after;

delete pPos;

pIter = pCurrnet;

size--;

}

return pIter;

}


Iter end()

{

return Iter(bottum);

}


Iter begin()

{

return Iter(top->after);

}


void push_back( T pData )

{

insert( end(), pData );

}


void insert( Iter pIter, T pData )

{

Node* pNewNode = new Node( pData );

pNewNode->before = pIter._pos->before;

pIter._pos->before->after = pNewNode;

pIter._pos->before = pNewNode;

pNewNode->after = pIter._pos;

size++;

}

};


class jaeho

{

public:

jaeho(int _k =0, float _j = 0.f)

{

k= _k;

j = _j;

}

int k;

float j;

};


void main()

{

List<int> test;


test.push_back(10);

test.push_back(40);

test.push_back(20);

test.push_back(240);


List<int>::Iter iter = test.begin();

  iter++;

test.insert(iter,333);

for (List<int>::Iter iter = test.begin(); iter != test.end(); iter++ )

{

printf("%d\n", *iter );

}


printf("\n");

iter = test.begin();

test.eraser(iter);

for (List<int>::Iter iter = test.begin(); iter != test.end(); ++iter )

{

printf("%d\n", *iter );

}


List<jaeho> test2;


test2.push_back(jaeho(20,41.4f));

test2.push_back(jaeho(220,211.6f));

test2.push_back(jaeho(120,52.4f));


for (List<jaeho>::Iter iter = test2.begin(); iter != test2.end(); iter++ )

{

printf("%d     %f\n", iter->k , iter->j );

}

}


자료구조 다시 환기할 겸 만들어 봤음 


stl에 list의 기능은 다 구현 안했음


기본적인것만 구현


시간 날 때 마다 하나 씩 구현 해봐야 겠다.

'Programing > 자료구조' 카테고리의 다른 글

STL Vector와 List 차이점  (0) 2012.05.21
Big - O 표기법  (0) 2012.05.18
Posted by 부우산사나이
:

STL의 Vector와 List는 언듯 보기엔 비슷하지만 큰 차이점이 있다. 

 

Vector의 방식은 메모리 할당을 연속적으로 하고, List는 따로따로 할당을 한다.

따라서 Vector는 배열과 같은 방식으로 사용할 수 있지만 List는 그렇지 않다.

 

단순하게 놓고 본다면 Vector는 배열과 비슷하고 List는 Linked List와 비슷하다.

이제 여기서 발생하는 현상(?)들을 보자.

 

 1. 메모리 할당

Vector는 미리 일정크기의 메모리를 할당해 놓고 그 이상의 값들이 추가되면 새로운 더 큰 메모리를 할당한다.*1

List는 값을 넣을때마다 메모리를 할당하게 된다.

Vector는 메모리 할당을 매번 하지 않기 때문에 매번 할당하는 List보다 pushback이 빠르다.

중간에 추가하는 Insert의 경우 Vector는 배열을 계속 재구성 해야하기 때문에 속도가 느리다.

 

 

 2. 메모리 해제

Vector는 값을 삭제하더라도 메모리 해제를 하지 않는다. 심지어 Clear를 하더라도 메모리는 그대로 남게 된다.

반대로 List의 경우 변수가 해제 될때마다 메모리에서 해제하게 된다.

할당과 마찬가지로 해제또한 popback의 경우 vector가 훨씬 빠르다.

하지만 역시 중간에 값을 삭제하는 것은 List가 더 빠르다.

Vector는 변수들을 삭제할 때 메모리 해제가 되지 않는다. 심지어 Clear함수를 사용해도 메모리는 그대로 남아있다.

 

Vector의 메모리를 해제 하는 함수

Visual Studio 2010 버전 이상 (C++11)

값들의 개수에 맞춰 메모리를 다시 할당하는 함수로 shrink_to_fit() 맴버 함수가 있다.

Visual Studio 2008 버전 이하는 함수를 만들어야 함

template <class T>

void vector_clear(vector<T>& vecObj)

{

vector<T> tempObj;

tempObj.swap(vecObj);

}

* vector의 메모리를 해제해주는 것은 상당히 많은 시간을 소요하므로 특별한 경우만 사용해야한다.  capacity()맴버함수는 현재 할당된 크기를 반환 한다.

 

 3. 메모리 사용량

Vector의 경우 연속적인 주소에 할당 되므로 추가적인 linked list처럼 next의 주소등 다른 변수들을 가지고 있을 필요가 없다.

따라서 Vector가 list보다 적은 메모리를 사용한다. 하지만 Vector도 일정 크기 이상이 넘어가면 오류가 발생 한다.

(vector는 최대 크기가 정해져 있다. 32bit 내 컴퓨터 기준으로 10억개, max_size()맴버함수로 알 수 있다.)

 

 

** 정리

맨뒤에 추가 삭제가 일어나는 경우는 vector가 빠르며 메모리도 적게 먹는다.

따라서 순서와 상관없거나 순차적으로만 추가, 삭제되는 데이터는 vector를 쓰는게 좋다.

순서가 중요하여 리스트의 중간위치에 값이 추가, 삭제가 되는 경우 list를 사용하는 것이 좋다. (메모리는 더 먹지만 속도가 빠르다)

vector는 이제까지 사용했던 가장 많은 크기의 메모리를 사용하므로 주의해야한다.

 

 

실제 게임에서 활용

벡터

- 예를 들어서 액션 관련 정보가 있다.

   이 정보들은 바뀔 경우가 거의 없다.

   읽고 쓰면 되니 이런 경우는 벡터에 저장하면 될 듯 싶다.

리스트

-

'Programing > 자료구조' 카테고리의 다른 글

stl의 list 만들어 보기  (0) 2012.05.30
Big - O 표기법  (0) 2012.05.18
Posted by 부우산사나이
:

출처 : http://blog.naver.com/anjindago?Redirect=Log&logNo=150119261447

 

빅오 표기법이란?

어떤 하나의 함수의 복잡도를 정의하는 데 즐겨 사용하는 것.
간단히 말하자면 알고리즘이 처리할 자료집합의 크기가 성장함에 따라 알고리즘의 효율이
어떻게 변화하는지를 대략적이나마 추정하는 하나의 함수라고 정의 할 수 있다.


알고리즘의 복잡도를 표현하는 데 흔히 쓰이는 함수들이 몇 가지 있는데,
복잡도의 낮은 것부터 높은 순으로 나열해보자면
(상수), (log₂n), (n), (nlog₂n), n², n³, 2ⁿ 이라고 한다.


O(c)
빅 O 표기에서 c는 상수를 뜻한다.
상수 함수의 그래프는 항상 수평을 유지한다. 이는 알고리즘의 수행에 걸리는 시간이 자료집합의 크기에
상관없이 항상 동일하다는 뜻이다. 대체로 이런 함수들이 가장 빠른 것으로 간주된다.


O(log₂n)
로그 기반의 알고리즘은 자료의 크기에 의존적인 알고리즘들 중에서는 가장 효율적인 것으로 간주된다.
즉, 데이터가 추가되면 될수록 효율이 좋아지는 녀석이다.


O(n)
선형 함수라 불리며, 어떠한 알고리즘이 1000개의 항목을 20초안에 처리한다면, 2000개의 항목은
40초에 처리하게되는 자료의 크기와 직접적인 관계를 갖는 함수이다.


O(nlog₂n)
이 함수는 일반적인 정렬 알고리즘이 가져야 할 최소한의 복잡도로 간주된다.


O(n²)
자료가 증가함에 따라 급격히 커지기 때문에 대부분의 과제들에 비해 비효율적이라고 간주된다.
예를들어 1000개의 항목을 처리하는데 20초가 걸렸다면 2000개의 항목을 처리하기위해선 80초의
시간이 소요된다. 항목의 갯수가 2배증가하면 시간은 4배가 증가하는 셈이다.
일반적으로 어떤 알고리즘이 O(n²)이라면 일단 다른 알고리즘을 찾아보는 것이 더 낫다. (최대한 쓰지말자)
전형적인 예는  for 루프 안에 다른 for 루프가 내포된 형태이다.


O(n³)
1000개의 항목을 처리하는데 20초라면 2000개는 160초(8배)
위의 것보다 더 최악... 그냥 쓰지말자


O(2ⁿ )
흔히 기수 2 지수 함수라 부르며 항목 개수가 1 증가할 때마다 함수는 2배가 된다.
매우 비효율적이므로 피해야하는 알고리즘이다.


여러가지 복잡도들의 비교


복잡도

16

32

64

128

O(log n)

4

5

6

7

O(n)

16

32

64

128

O(nLog n)

64

160

384

896

O(n2)

256

17

68

273

O(n3)

68

546

74시간

24

O(2n)

18시간

136

5억년

--------

'Programing > 자료구조' 카테고리의 다른 글

stl의 list 만들어 보기  (0) 2012.05.30
STL Vector와 List 차이점  (0) 2012.05.21
Posted by 부우산사나이
: