Notice
Recent Posts
Recent Comments
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 로드밸런서
- 알고리즘
- 백트래킹
- 월미도
- 쿠버네티스
- 스프링
- Spring
- 인천여행
- 클라우드
- 스프링 부트
- 카프카
- Kafka
- springboot
- 클라우드 컴퓨팅
- 자료구조
- Spring Data JPA
- VPC
- aws
- Spring Boot
- Docker
- DFS
- JPA
- Apache Kafka
- 코드업
- 백준
- 스프링부트
- 프로그래밍문제
- Elasticsearch
- gcp
- 오일러프로젝트
Archives
- Today
- Total
GW LABS
C++로 구현하는 자료구조 (2) - LinkedList 본문
두번째 포스팅은 대표적인 선형 자료구조인 연결리스트이다. 알고리즘과 자료구조를 공부하면서 장벽이었던 녀석이기도 하다. 구현과 더불어 연결리스트를 알고리즘 문제에서 다룰 때 하지 말아야할 실수를 정리한다.
1. LinkedList (연결리스트)
연결리스트는 자료를 저장하고 포인터를 이용해서 다음 자료를 가르키는 형식으로 구성된 선형 자료구조이다. 처음 연결리스트를 공부할 때 동적배열과 차이점을 파악하지 못했다. 가장 큰 차이점은 바로 메모리에 저장방식에 있다.
배열 혹은 동적배열의 경우 메모리에 자료를 저장할때 순서대로 저장된다. 연결리스트는 현재 메모리에 비어있는 곳에 랜덤하게 저장되고 자료를 접근할 때에는 포인터로만 접근을 한다.
2. 연결리스트를 다룰 때 주의할 점
연결리스트를 다룰 때 주의할 점은 데이터를 추가하는 등의 연산을 수행할 때 포인터를 잘 신경써줘야 하는 점이다. 다음 자료를 추가할 때 포인터에 끝까지 가서 추가하면 안된다.
// 끝 노드에서 자료를 추가하면 포인터에 연결해준 것이 아니게된다.
last = new Node(data)
// 이와 같은 방식으로 next 포인터에 자료를 할당해야 한다!
previous.next = new Node(data)
자료를 추가하거나 제거할 때 꼭 제거하려는 대상의 포인터로 진행해서 연산을 하는 것이 아니라, 이전이나 이후에서 연결을 조작해줘야 하는 점이 연결리스트 문제의 핵심이라고 볼 수 있겠다.
3. 소스코드
#pragma once
#include <iostream>
using namespace std;
template <typename T>
class Node {
public:
T value;
Node<T>* next;
Node(T value) : value(value) {}
};
template <typename T>
class LinkedList {
private:
int size = 0;
Node<T>* head;
public:
void add(T value) {
if (this->head) {
Node<T>* cursor = this->head;
while (cursor->next) {
cursor = cursor->next;
}
cursor->next = new Node<T>(value);
}
else {
this->head = new Node<T>(value);
}
this->size++;
}
T get(const int& index) {
if (index < 0 || index > this->size) {
throw std::out_of_range("범위초과");
}
int idx = 0;
Node<T>* cursor = this->head;
while (idx != index) {
cursor = cursor->next;
idx++;
}
return cursor->value;
}
void remove(const int& index) {
if (index < 0 || index > this->size) {
throw std::out_of_range("범위초과");
}
if (this->size == 0) return;
if (index == 0) {
Node<T>* cursor = this->head;
this->head = this->head->next;
delete cursor;
}
else {
int idx = 0;
Node<T>* cursor = this->head;
while (idx != index - 1) {
cursor = cursor->next;
idx++;
}
Node<T>* tmp = cursor->next;
cursor->next = cursor->next->next;
delete tmp;
}
this->size--;
}
int length() {
return this->size;
}
};
#include <string>
#include <iostream>
#include "datastructure/LinkedList.h"
using namespace std;
int main() {
LinkedList<string>* list = new LinkedList<string>();
list->add("abc");
list->add("bca");
list->add("cba");
for (int i = 0; i < list->length(); i++) {
cout << list->get(i) << endl;
}
cout << endl;
list->remove(1);
for (int i = 0; i < list->length(); i++) {
cout << list->get(i) << endl;
}
return 0;
}
'Algorithm & DataStructure' 카테고리의 다른 글
[LeetCode] Decode String (0) | 2020.09.10 |
---|---|
[LeetCode] Palindromic Substrings (0) | 2020.09.08 |
C++로 구현하는 자료구조 (1) - ArrayList (0) | 2020.09.03 |
[코드업 3002] 기억력 테스트 3 (0) | 2020.09.01 |
[HackerRank] Tree: Huffman Decoding (0) | 2020.08.03 |
Comments