[자료구조] 연결리스트 그리고 스택 & 큐

2024. 8. 29. 00:39· Computer Science
목차
  1. ✒️ 0. 들어가기 전
  2. ✒️ 1. 연결리스트(Linked List)
  3. 💡 시간 복잡도
  4. 💡 연결리스트의 종류
  5. 💡 랜덤(직접)접근과 순차적 접근
  6. 💡 언제 사용해야 할까?
  7. ✒️ 2. 스택(Stack)
  8. 💡 시간복잡도
  9. 💡 스택의 구현
  10. 💡 언제 사용해야 할까?
  11. ✒️ 3. 큐(Queue)
  12. 💡 시간 복잡도
  13. 💡 큐의 구현
  14. 💡 언제 사용해야 할까?
  15. 📝 면접 예상 질문
반응형

✒️ 0. 들어가기 전


이번 글에서는 연결리스트, 스택, 큐와 같은 기본적인 자료구조에 대해 깊이 있게 탐구해보겠다.

각 자료구조의 개념, 구조, 시간 복잡도, 그리고 실전 코드 예제까지 다루면서 그 원리를 이해하고, 어떻게 구현되고 사용하는지를 배워보자.

 

✒️ 1. 연결리스트(Linked List)


연결리스트는 메모리에서 연속되지 않은 위치에 노드를 저장하며, 각 노드는 다음 노드로의 포인터를 가지고 있다.

이는 배열과 같은 순차적인 자료구조와는 다르게, 삽입과 삭제가 빠르게 이루어질 수 있는 장점을 제공한다.

노드는 데이터와 다음 노드를 가리키는 포인터로 구성되며, 이 포인터를 통해 노드들이 연결된다.

각 노드는 next 또는 next, prev라는 포인터로 서로 연결된 선형적인 자료구조!!

 

연결리스트는 주로 데이터의 삽입과 삭제가 빈번한 상황에서 사용된다.

연결 리스트

 

💡 시간 복잡도

- 참조 : O(n)
- 탐색 : O(n)
- 삽입 / 삭제 : O(1)

 

💡 연결리스트의 종류

1. 싱글 연결리스트(Singly Linked List)

싱글 연결리스트는 각 노드가 오직 다음 노드를 가리키는 포인터(next)만을 가지고 있다.

노드를 탐색할 때는 첫 번째 노드부터 시작하여 차례로 다음 노드를 따라가야 하므로,

특정 위치의 노드를 찾는 데 O(n)의 시간이 소요된다.

하지만 노드의 삽입과 삭제는 O(1)의 시간 복잡도를 가진다.


      
class Node {
public:
int data;
Node* next;
Node(int data) : data(data), next(nullptr) {}
};

 

2. 이중 연결리스트(Doubly Linked List)

이중 연결리스트는 각 노드가 다음 노드(next)와 이전 노드(prev)를 가리키는 두 개의 포인터를 가지고 있다.

따라서 양방향으로 탐색이 가능하며, 노드의 삽입과 삭제 시에도 해당 노드의 이전 노드를 쉽게 접근할 수 있어 더 유연하게 사용할 수 있다.


      
class Node {
public:
int data;
Node* next;
Node* prev;
Node(int data) : data(data), next(nullptr), prev(nullptr) {}
};

 

3. 원형 연결리스트(Circular Linked List)

원형 연결리스트는 마지막 노드가 첫 번째 노드를 가리키도록 구성된 연결리스트이다.

이를 통해 리스트의 끝에서 시작으로 다시 돌아가는 구조를 가지게 된다.

원형 연결리스트는 싱글 또는 이중 연결리스트로 구현될 수 있다.

원형 싱글 연결리스트
원형 이중 연결리스트


      
// 원형 싱글 연결리스트 예시
class Node {
public:
int data;
Node* next;
Node(int data) : data(data), next(nullptr) {}
};
void createCircular(Node* head) {
Node* temp = head;
while (temp->next != nullptr) {
temp = temp->next;
}
temp->next = head; // 마지막 노드가 첫 노드를 가리키도록
}

 

💡 랜덤(직접)접근과 순차적 접근

직접 접근이라고 하는 랜덤 접근(random access)은 동일한 시간에 배열과 같은 순차적인 데이터가 있을때 임의의 인덱스에 해당하는 데이터에 접근할 수 있는 기능이다.

이는 데이터를 저장된 순서대로 검색해야 하는 순차적 접근(sequential access)과는 반대이다.

 

vector, Array와 같은 배열은 랜덤접근이 가능해서 n번째 요소에 접근할 때 O(1)이 걸리며

연결리스트, 스택, 큐는 순차적 접근만이 가능해서 n번째 요소에 접근할 때 O(n)이 걸린다.

 

💡 언제 사용해야 할까?

>> 연결리스트는 요소의 추가와 삭제가 빈번히 일어나는 상황에 적합하지만,
   임의의 요소에 접근하는 데 시간이 많이 소요되므로, 랜덤 접근이 자주 요구되는 경우에는 적합하지 않다.

 

✒️ 2. 스택(Stack)


스택은 후입선출(LIFO, Last In First Out) 구조를 가진 자료구조이다.

이것이 가장 큰 특징이기 떄문에, 이를 기억하고 있으면! 다른 부분이 자연스럽게 이해될 것이다.

먼저 들어온 것이 가장 먼저 나간다!

 

이는 가장 마지막에 추가된 요소가 가장 먼저 제거되는 구조이다!!!

 

자연스럽게 생각해보면, 마지막 한 행위를 다시 끄집어 낼 때 사용하면 좋을 것 같다.

예를 들어, 웹 브라우저의 방문 기록이나 텍스트 에디터의 되돌리기 기능 등이 스택을 활용한 대표적인 사례이다.

💡 시간복잡도

- n번째 참조: O(n)
- 가장 앞부분 참조: O(1)
- 탐색: O(n)
- 삽입/삭제(n번째 제외): O(1)

 

💡 스택의 구현

스택은 연결리스트나 배열을 기반으로 구현할 수 있다.

연결리스트 기반의 스택은 동적으로 메모리를 할당하여, 메모리 크기에 제한 없이 사용할 수 있는 반면,

배열 기반의 스택은 고정된 크기의 메모리를 사용하므로, 스택의 크기가 초과하면 오버플로우가 발생할 수 있다.


      
#include <stack>
#include <iostream>
int main() {
std::stack<std::string> stk;
stk.push("엄");
stk.push("준");
stk.push("식");
while (!stk.empty()) {
std::cout << stk.top() << "\n";
stk.pop();
}
return 0;
}

 

위의 예제에서는 엄, 준, 식 을 차례로 스택에 푸시(push)하고, 스택이 비어질 때까지 팝(pop)하면서 출력한다.

결과는 스택의 특성에 따라 식, 준, 엄의 순서로 출력된다.

 

💡 언제 사용해야 할까?

>> 스택은 주로 함수 호출 관리, 깊이 우선 탐색(DFS), 그리고 뒤로 가기와 같은 기능에서 중요한 역할을 한다.

 

✒️ 3. 큐(Queue)


큐는 반대로 선입선출(FIFO, First In First Out) 구조를 가진 자료구조이다.

<편의점 알바를  한 번이라도 해보았으면 아는 "선입선출"!>

선입선출 아시죠~?

 

그렇다면 자연스럽게 큐는 순서를 보장하면서 데이터가 처리되도록 하는 데 강점을 가지고 있다고 이해할 수 있다.

즉, 먼저 들어간 데이터가 먼저 나오는 구조로, 프로세스 관리, 네트워크 데이터 처리, 너비 우선 탐색(BFS) 등에 자주 사용된다. 

FIFO

💡 시간 복잡도

- n번째 참조: O(n)
- 가장 앞부분 참조: O(1)
- 탐색: O(n)
- 삽입/삭제(n번째 제외): O(1)

 

💡 큐의 구현

큐는 배열이나 연결리스트를 이용해 구현할 수 있다.

배열을 사용한 큐는 고정된 크기 때문에 크기가 제한되지만,

연결리스트 기반 큐는 동적으로 메모리를 할당할 수 있어 유연하게 사용할 수 있다.


      
#include <queue>
#include <iostream>
int main() {
std::queue<int> q;
for (int i = 1; i <= 10; i++) {
q.push(i);
}
while (!q.empty()) {
std::cout << q.front() << ' ';
q.pop();
}
return 0;
}

위의 코드에서는 1부터 10까지의 정수를 큐에 차례로 푸시하고, 큐가 비어질 때까지 팝하면서 출력한다.

큐는 선입선출 구조이므로 출력 결과는 1 2 3 4 5 6 7 8 9 10이 된다!

 

💡 언제 사용해야 할까?

>> 큐는 대기열이나 작업 순서가 중요한 프로세스 관리에서 유용하게 사용된다.

   예를 들어, 운영체제의 작업 스케줄링이나 네트워크 패킷 처리에서 큐가 중요한 역할을 한다.

 

📝 면접 예상 질문


Q: 연결리스트와 배열의 차이점은 무엇인가요?
A: 연결리스트는 메모리에서 연속적이지 않은 위치에 노드가 저장되며, 각 노드는 다음 노드의 주소를 가리키는 포인터를 포함합니다. 배열은 메모리에서 연속된 위치에 데이터가 저장되며, 인덱스를 통해 빠르게 접근할 수 있습니다. 연결리스트는 삽입과 삭제가 용이하지만, 특정 요소에 접근하는 데 O(n)의 시간이 걸리고, 배열은 접근이 O(1)이지만, 삽입과 삭제는 O(n)이 걸립니다.

-> 데이터 추가와 삭제를 많이 하는 것은 연결 리스트, 참조를 많이 하는 것은 배열로 하는 것이 좋습니다.

Q: 연결리스트에서 마지막 노드를 찾기 위해 필요한 시간 복잡도는 무엇인가요?
A: 연결리스트에서 마지막 노드를 찾기 위해서는 첫 번째 노드부터 순차적으로 접근해야 하므로 시간 복잡도는 O(n)입니다.

 

Q: 스택이 실무에서 주로 사용되는 예시는 무엇인가요?
A: 스택은 재귀 함수의 호출 스택 관리, 웹 브라우저의 뒤로 가기 기능, 텍스트 편집기의 되돌리기 기능 등에서 사용됩니다. 함수 호출 시에는 호출 스택에 함수가 추가되고, 함수가 종료되면 스택에서 제거됩니다.

Q: 스택을 배열로 구현할 때 발생할 수 있는 문제점은 무엇인가요?
A: 스택을 배열로 구현할 경우, 스택의 크기가 고정되어 있어 스택이 가득 차면 오버플로우(Overflow) 문제가 발생할 수 있습니다. 이는 배열의 크기를 초과하여 더 이상 요소를 추가할 수 없음을 의미합니다.

 

Q: 큐와 스택의 차이점은 무엇인가요?
A: 큐는 선입선출(FIFO) 구조로, 먼저 들어간 데이터가 먼저 나오고, 스택은 후입선출(LIFO) 구조로, 나중에 들어간 데이터가 먼저 나옵니다. 큐는 주로 작업 스케줄링이나 데이터 흐름 제어에 사용되고, 스택은 함수 호출 관리나 알고리즘에서 사용됩니다.

반응형
저작자표시 (새창열림)
  1. ✒️ 0. 들어가기 전
  2. ✒️ 1. 연결리스트(Linked List)
  3. 💡 시간 복잡도
  4. 💡 연결리스트의 종류
  5. 💡 랜덤(직접)접근과 순차적 접근
  6. 💡 언제 사용해야 할까?
  7. ✒️ 2. 스택(Stack)
  8. 💡 시간복잡도
  9. 💡 스택의 구현
  10. 💡 언제 사용해야 할까?
  11. ✒️ 3. 큐(Queue)
  12. 💡 시간 복잡도
  13. 💡 큐의 구현
  14. 💡 언제 사용해야 할까?
  15. 📝 면접 예상 질문
'Computer Science' 카테고리의 다른 글
  • [자료구조] 맵(Map), 셋(Set), 해시테이블(Hash Table)
  • [자료구조] 트리와 그래프
  • [자료구조] 포인터 (Pointer)
  • [자료구조] 정적배열(Array)과 동적배열(Vector)
dog-pawwer
dog-pawwer
성장 중 🌱🌱
dog-pawwer
지노개발일기
dog-pawwer
전체
오늘
어제
  • 분류 전체보기 (117)
    • FrontEnd (4)
      • Android (4)
    • BackEnd (22)
    • Cloud (15)
    • Trouble Shooting (2)
    • Computer Science (52)
      • CS 개인 공부 (19)
      • 알고리즘 (코딩테스트) (1)
      • 프로그래밍언어론 (15)
      • 분산시스템 (5)
      • 정보처리기사 (개인공부용) (3)
    • 강의 (18)
      • 자바-스프링부트-서버개발 (8)
      • UMC (Study) (9)
      • 스프링 부트와 JPA (1)
    • 🚨ERROR (4)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • GitHub

공지사항

인기 글

태그

  • 카카오 로그인
  • kakao
  • oauth
  • 오어스
  • RestAPI
  • 카카오
  • 카카오 로그인 구현
  • java
  • 스프링부트
  • springboot
  • 9-0

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.1
dog-pawwer
[자료구조] 연결리스트 그리고 스택 & 큐
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.