연결리스트의 경우 O(1)에 삽입 및 삭제가 가능하다
연결 리스트의 특징:
- 각 데이터는 노드(Node)로 구성이 되어있다
- 노드는 메모리상 서로 각기 다른 위치에 존재한다
- 포인터를 이용하여 노드들을 연결한다
포인터를 통해 노드를 연결하다 보니, 삽입의 경우는 포인터로 다음 노드를 가리키면 끝이다.
-----------
| newNode |
-----------
----------- -----------
| nodeA | --> | nodeB |
----------- -----------
// nodeA와 nodeB 사이에 newNode 삽입
int data = 17;
Node *newNode = new Node(data);
newNode->next = nodeA->next
nodeA->next = newNode
----------- ----------- -----------
| nodeA | --> | newNode | --> | nodeB |
----------- ----------- -----------
마찬가지로 삭제의 경우, 삭제가 될 노드와 연결되어 있는 노드(들)의 포인터를 해제하면 된다.
// newNode (두 번째 노드) 삭제
Node *curr = nodeA
Node *removeNode = curr->next;
curr->next = curr->next->next
removeNode->next = NULL;
delete removeNode
----------- -----------
| nodeA | --> | nodeB |
----------- -----------
삽입과 삭제의 경우 좋은 성능을 보이지만, 노드를 사용하는 만큼 메모리 사용량이 증가한다. 또한 삽입할 위치를 탐색하거나, 삭제할 노드가 있는 위치 만큼 이동을 해야하기 때문에 삽입 및 삭제 함수 자체의 시간복잡도는 O(n)
이 된다. 이는 어디까지나 탐색의 시간이 포함된 것 뿐, 삽입과 삭제는 O(1)
이다.
확장 🌱
- 노드를 사용하므로써 메모리 사용량이 증가하지만, 배열보다는 메모리 친화적이지 않을까? 배열과 다르게 낭비되는 자원이 없으니까. -> 250516124750
- 정말 없을까? 일단 메모리 누수의 위험도는 배열보다 높음. 포인터를 실수로 날려버리거나 덮어씌우면 그 이후 노드에 접근할 수 없음. -> 250517213935
- 노드를 template로 구현하면, 각 노드마다 다른 타입의 데이터를 담을 수 있을까?
Node<int> nodeA
->Node<bool> nodeB
->Node<double> nodeC
- 포인터가 없는 혹은 사용할 수 없는 언어들의 경우, 연결리스트를 구현하는 방법
관련 노트 📘
- 250512043750 - 배열의 삽입과 삭제에는 O(n)의 시간이 필요하다