반응형
1. Why
만약, 배열에 데이터가 있을 때, 중간에 삭제하게 되면, 삭제한 부분을 어떻게 메꿔야 할까?
만약, 배열의 시작 지점(arr[0]) 앞에 데이터를 삽입할 경우가 생긴다면 어떻게 해야할까?
이러한 문제를 해결 할 수는 없을까?
2. What / How
순차적으로 하나씩 입력이 가능한 배열이다.
리스트의 장점은 중간에 새로운 데이터를 삽입할 때,
기존 데이터를 전부 다 뒤로 한칸씩 미룰 필요가 없다.
(이유는 포인터로 주소값을 가지기 때문)
링크드 리스트 비용
삽입 (Insert) | 삭제 (Remove) | 탐색 (contains or search) | |
링크드 리스트 | O(1) | O(n) | O(n) |
각 함수의 설명은 코드로 대신하겠습니다.
void init(int size);
void insert(Type value);
void insert(Type value, Type position);
bool remove(Type value);
bool contains(Type value);
3. 샘플코드
참고로 편의상 다 public 으로 선언했는데, head, tail, size, MAX 는 숨기는 게 설계상 맞다.
public 과 private의 구분이 왜 필요한지 간략하게 설명하면, 이 클래스를 사용하는 입장에서 굳이 몰라도 되는 것들을 가리는 것이다.
하지만 알고리즘 공부할 때는 어차피 혼자 다 구현하고, 서비스간 복잡도도 계산할 필요없으니, 그딴 건 일도 없어~
#include <iostream>
using namespace std;
template <typename Type>
class Node {
public:
Type value;
Node *next;
Node *prev;
};
template <typename Type>
class LinkedList {
public:
Node<Type> *head;
Node<Type> *tail;
int size;
int MAX;
LinkedList();
~LinkedList();
void init(int size);
void insert(Type value); // insert a data(value) at the rear of the list
void insert(Type value, Type position); // insert a data(value) after the position.
bool remove(Type value);
bool contains(Type value);
};
template <typename Type>
LinkedList<Type>::LinkedList() {
size = 0;
head = new Node<Type>;
tail = new Node<Type>;
head->next = head;
head->prev = tail;
tail->next = head;
tail->prev = tail;
}
template <typename Type>
LinkedList<Type>::~LinkedList() {
Node<Type> *current = tail;
while (current != current->next) {
current = current->next;
Node<Type> *temp = current;
delete temp;
}
}
template <typename Type>
void LinkedList<Type>::init(int size) {
MAX = size;
}
template <typename Type>
void LinkedList<Type>::insert(Type value) {
if (size + 1 == MAX) {
return;
}
Node<Type> *prev = head->prev;
Node<Type> *newNode = new Node<Type>;
newNode->value = value;
newNode->next = head;
newNode->prev = prev;
prev->next = newNode;
head->prev = newNode;
size++;
}
template <typename Type>
void LinkedList<Type>::insert(Type value, Type position) {
if (size + 1 == MAX) {
return;
}
Node<Type> *current = tail;
while (current != current->next) {
if (current->value == value) {
Node<Type> *next = current->next;
Node<Type> *newNode = new Node<Type>;
newNode->value = value;
newNode->next = next;
newNode->prev = current;
current->next = newNode;
next->prev = newNode;
size++;
break;
}
}
}
template <typename Type>
bool LinkedList<Type>::remove(Type value) {
if (size == 0) {
return false;
}
Node<Type> *current = tail;
while (current != current->next) {
current = current->next;
if (current->value == value) {
Node<Type> *prev = current->prev;
Node<Type> *next = current->next;
delete current;
prev->next = next;
next->prev = prev;
size--;
return true;
}
}
return false;
}
template <typename Type>
bool LinkedList<Type>::contains(Type value) {
Node<Type> *current = tail;
while(current != current->next) {
current = current->next;
if (current->value == value) {
return true;
}
}
return false;
}
int main() {
LinkedList<int> linkedList;
linkedList.init(4);
for (int i = 1; i <= 5; ++i) {
linkedList.insert(i);
}
cout << "contains 0: " << linkedList.contains(0) << endl; // 1
cout << "contains 3: " << linkedList.contains(3) << endl; // 1
cout << "contains 4: " << linkedList.contains(4) << endl; // 0
cout << "remove 2: " << linkedList.remove(2) << endl; //1
cout << "contains 1: " << linkedList.contains(1) << endl; // 0
}
이 코드에 void push(Type value), Type pop()만 잘 구현하면, 스택(Stack)이랑 큐(Queue) 쌉파써블.
반응형
': Algorithm' 카테고리의 다른 글
[C/C++] 제곱 (0) | 2021.05.26 |
---|---|
[C/C++] 큰 수의 곱셈 (karatsuba, 카라츄바) (2) | 2021.05.04 |
[C/C++] vector 구현 (4) | 2021.04.29 |
[C/C++] 트라이 (Trie) (0) | 2021.04.22 |
알고리즘 사이트 추천 (0) | 2021.04.15 |