배열 | 연결 리스트 | |
---|---|---|
k번째 원소에 접근 | O(1) | O(k) |
임의 위치에 원소 추가/제거 | O(N) | O(1) |
메모리 상의 배치 | 연속 | 불연속 |
추가적으로 필요한 공간(overhead) | - | O(N) |
struct NODE {
struct NODE *prev, *next;
int data;
};
const int MX = 1000005;
int dat[MX], pre[MX], nxt[MX];
int unused = 1;
fill(pre, pre+MX, -1);
fill(nxt, nxt+MN, -1);
void traverse() {
int cur = nxt[0];
while (cur != -1) {
cout << dat[cur] << ' ';
cur = nxt[cur];
}
cout << "\n\n";
}
#include <bits/stdc++.h>
using namespace std;
const int MX = 1000005;
int dat[MX], pre[MX], nxt[MX];
int unused = 1;
// addr은 연결 리스트 상의 주소가 아닌 해당 원소의 주소를 의미
void insert(int addr, int num) {
dat[unused] = num;
pre[unused] = addr;
nxt[unused] = nxt[addr];
// 마지막 위치에 원소 삽입 시 예외 처리 필요
if (nxt[addr] != -1) pre[nxt[addr]] = unused;
nxt[addr] = unused;
unused++;
}
void erase(int addr) {
nxt[pre[addr]] = nxt[addr];
// 마지막 위치의 원소 삭제 시 예외 처리 필요
if (nxt[addr] != -1) pre[nxt[addr]] = pre[addr];
}
int main(void) {
list<int> L = {1, 2}; // 1, 2
// C++ 11 이상이라면 auto t = L.begin(); 으로 작성 가능
list<int>::iterator t = L.begin(); // t는 1을 가리키게 됨
L.push_front(10); // 10 1 2
cout << *t << '\n'; // t가 가리키는 값 1을 출력
L.push_back(5); // 10 1 2 5
L.insert(t, 6); // t가 가리키는 곳 앞에 6을 삽입 -> 10 6 1 2 5
t++; // t를 1칸 앞으로 전진 -> 현재 t는 2를 가리킴
t = L.erase(t); // t가 가리키는 값 제거 -> 그 다음 원소 위치인 5를 반환
cout << *t << '\n'; // 5
}
for (auto i : L) cout << i << ' ';
for (list<int>::iterator it = L.begin(); it != L.end(); it++)
cout << *it << ' ';
끗..