우선순위 큐(std::priority_queue)의 경우 힙을 기반으로 하고, 힙은 내부적으로 '완전 균형 이진 트리'로 구성되어 있음
vector<Player*> v; // 벡터가 동적으로 크기가 늘어나면서 복사가 일어날 때
// 이 복사 비용을 줄이기 위해 포인터가 벡터의 요소가 되도록 함
// 10만명 입장
for (int i = 0; i < 100000; i++) {
Player* p = new Player(i);
v.push_back(p);
}
// 5만명 퇴장
srand(time(NULL));
int K = rand() % 100000;
for (int i = 0; i < 50000; i++) {
int randIdx = rand() % v.size();
// 실험을 위해 ID가 K인 원소는 삭제하지 않는다.
if (randIdx == K) {
i++;
continue;
}
Player* p = v[randIdx];
delete p;
v.erase(v.begin() + randIdx); // 한 번의 삭제 연산에 O(N)의 시간 복잡도 소모..
}
//for (int i = 0; i < v.size(); i++) {
// cout << v[i]->_playerId << endl;
//}
// 2, 4, 6, 7, 9, 14, 17 .... (50000개)
// id: K인 유저를 찾으려면?
size_t vsize = v.size();
for(int i=0; i< vsize; i++) {
if (v[i]->_playerId == K) {
v.erase(v.begin() + i);
continue;
}
}
// 루프를 돌려야한다. 최악의 경우 O(50000)
// map<키 타입, 벨류 타입>
map<int, Player*> MAP;
// 10만명 유저 생성
for (int i = 0; i < 100000; i++) {
pair<int, Player*> p(i, new Player(i * 100));
MAP.insert(p);
}
// 5만명 유저 퇴장
srand(static_cast<unsigned int>(time(nullptr)));
int K = rand() % 100000;
for (int i = 0; i < 50000; i++) {
int randKey = rand() % 100000;
// 실험을 위해 ID가 50000인 원소는 삭제하지 않는다.
if (randKey == K) {
i++;
continue;
}
delete MAP[randKey]; // 자원 반환
MAP.erase(randKey); // 삭제될 키가 이미 삭제되었다면,
// erase 함수는 그냥 무시함
}
// ID: K인 플레이어를 찾는 것과 삭제하는 것은 각 각 O(logN)에 불과하다
auto iter = MAP.find(K);
MAP.erase(iter);