자격증 정복/컴퓨터시스템기사

컴퓨터시스템기사 실기 02 — 자료구조 I (스택·큐·트리 순회·정렬·탐색)

올드 IT직장인 2026. 10. 11. 19:00

컴퓨터시스템기사 실기 02 — 자료구조 I (스택·큐·트리 순회·정렬·탐색)

출제기준(실기) 4. 자료구조 활용 — 4-1 기본 자료구조 활용(연결 리스트·스택·큐·트리), 4-2 정렬 및 탐색
수식 표기법 변환과 트리 순회는 복원 기출에서 거의 매 회차 반복됩니다. 계산 과정까지 쓰는 연습이 핵심이에요!

01편에서 6개 주요항목 맵을 정리했으니, 이번 편부터 항목별로 들어갑니다.

자료구조는 2026년 개편 출제기준에서 독립 항목이 되었고, 구 기출에서도 표기법 변환과 트리 순회가 반복해서 나온 영역입니다.


이번 편의 출제기준 위치

코드 세세항목
4-1-1 연결 리스트를 활용할 수 있다
4-1-2 스택을 활용할 수 있다
4-1-3 큐를 활용할 수 있다
4-1-4 트리를 활용할 수 있다
4-2-1 주어진 자료를 정렬할 수 있다
4-2-2 주어진 자료를 탐색할 수 있다

실기 출제 포인트

복원 기출 정리 파일에서 확인한 출제 현황입니다.

유형 확인된 회차 중요도
수식 후위·전위 표기 변환 2017-3(전위), 2020 수시, 2020 통합, 2021-1, 2021-3,
2024-1(전위), 2024-3·2025-1·2025-3(2021-3과 동일 문항)
⭐⭐⭐
트리 순회 (후위·전위) 2018-1·2018-3(후위), B형 2019-11(전위) ⭐⭐⭐
트리의 차수·단말 노드 2016-1, 2020-3, 2025-1(동일 문항) ⭐⭐
재귀 호출의 지역 변수·복귀 주소 저장 구조 → 스택 2026-1 Q14 ⭐⭐
0-주소 명령어 스택 PUSH/POP 추적 2020 통합, 2024-3 ⭐⭐
정렬 C 코드 출력 예측 2021-1, 2022-1 ⭐⭐
AVL 트리 2026-1 Q18 (원문 불완전 복원) ⭐⭐
비교 정렬 하한 2026-1 Q19 ⭐⭐
연결 리스트·큐·이진 탐색 직접 출제 확인 안 됨 (출제기준에는 있으므로 개념 정리) ⭐

키워드 박스 (답안 필수 단어)

스택     — LIFO, push / pop, top, 오버플로 / 언더플로
큐       — FIFO, enqueue / dequeue, front / rear, 원형 큐
연결 리스트 — 노드(data + next), head, 삽입·삭제 O(1), 탐색 O(n)
트리     — 루트, 노드의 차수, 트리의 차수, 단말 노드, 높이
순회     — 전위(Root-Left-Right), 중위(Left-Root-Right), 후위(Left-Right-Root)
AVL      — 균형 인수 |왼쪽 높이 − 오른쪽 높이| ≤ 1, 회전 LL / RR / LR / RL
정렬     — 비교 정렬 하한 Ω(n log n), 안정성, 평균·최악 시간 복잡도
탐색     — 순차 O(n), 이진 O(log n) (정렬된 자료가 전제)

스택과 큐 ⭐⭐

구조 원리 대표 연산 시간 복잡도 대표 활용
구조 원리 대표 연산 시간 복잡도 대표 활용
스택 LIFO (나중에 들어간 것이 먼저 나옴) push, pop O(1) 함수 호출·복귀 주소, 후위 표기 계산,
괄호 검사, DFS
큐 FIFO (먼저 들어간 것이 먼저 나옴) enqueue, dequeue O(1) (원형 큐) 준비 큐(스케줄링), 버퍼, BFS
덱 양쪽 끝에서 입출력 4가지 연산 O(1) 스택·큐 겸용
스택 오류:  오버플로(가득 찬 스택에 push) / 언더플로(빈 스택에서 pop)
큐 오류:    가득 찬 큐에 enqueue / 빈 큐에서 dequeue
원형 큐:    rear가 끝에 닿으면 앞으로 돌아와서 빈 칸을 재사용

수식 표기법 변환 ⭐⭐⭐

같은 수식을 연산자 위치에 따라 세 가지로 씁니다. A + B * C로 비교해 보세요.

표기법 연산자 위치 결과
중위(Infix) 피연산자 사이 A + B * C
전위(Prefix) 피연산자 앞 + A * B C
후위(Postfix) 피연산자 뒤 A B C * +

 

변환 방법

후위 변환 (괄호 → 우선순위 → 같은 우선순위는 왼쪽부터)
  1. 괄호 안을 먼저 변환
  2. 우선순위가 높은 연산자부터 "피연산자 피연산자 연산자"로 묶음
  3. 우선순위가 같으면 왼쪽 연산이 먼저 (좌결합)

예) A / B * ( C - D ) + E
  ( C - D )          → C D -
  A / B              → A B /
  ( A B / ) * ( C D - ) → A B / C D - *
  ( A B / C D - * ) + E → A B / C D - * E +

전위 변환: 같은 방식으로 묶되 연산자를 맨 앞에 둔다
예) A / B * ( C + D ) + E
  ( C + D )   → + C D
  A / B       → / A B
  ( / A B ) * ( + C D ) → * / A B + C D
  ( * / A B + C D ) + E → + * / A B + C D E

 

 

⚠️ 함정 패턴

"/ 와 * 는 우선순위가 같다 → 오른쪽의 (C-D)부터 묶는다" → 오답! (같으면 왼쪽부터)
"대입문 X = ... 을 변환할 때 = 를 빼먹음" → 감점! (후위에서는 X 우변결과 = 순서)
"전위와 후위를 헷갈려 연산자를 반대쪽에 둠" → 오답!

 

기출 모음

문제 정답 출제
A / B * (C − D) + E → 후위 A B / C D − * E + 2020 통합, 2021-1
A / B * (C + D) + E → 전위 + * / A B + C D E 2024-1
A * B + C → 전위 + * A B C 2017-3
X = A + B + C / D * E − F → 후위 X A B + C D / E * + F − = 2021-3, 2024-3, 2025-1, 2025-3
A / (B × C) − D + E / F → 후위 A B C * / D − E F / + 2020 수시 (원문에 정답 없음, 직접 계산)

후위식 값 계산 (스택 사용)

후위식은 왼쪽부터 읽으면서 피연산자는 push, 연산자는 pop 2번 후 계산 결과를 push 합니다.

식:  8 2 / 5 3 - * 1 +

push 8, push 2   → [8, 2]
  /              → 8 / 2 = 4        → [4]
push 5, push 3   → [4, 5, 3]
  -              → 5 - 3 = 2        → [4, 2]
  *              → 4 * 2 = 8        → [8]
push 1           → [8, 1]
  +              → 8 + 1 = 9        → [9]

결과: 9

0-주소 명령어의 스택 추적 (2020 통합, 2024-3)

0-주소 명령어는 피연산자를 스택에서 꺼내 씁니다. 같은 후위 표기 원리입니다.

A = B * ( C + D * E - F / G )

PUSH B → [B]
PUSH C → [B, C]
PUSH D → [B, C, D]
PUSH E → [B, C, D, E]
(1) MUL → D*E          → [B, C, (D*E)]
(2) ADD → C + D*E      → [B, (C+D*E)]
PUSH F → [B, (C+D*E), F]
PUSH G → [B, (C+D*E), F, G]
(3) DIV → F/G          → [B, (C+D*E), (F/G)]
(4) SUB → C+D*E − F/G  → [B, (C+D*E−F/G)]
(5) MUL → B * (...)    → [B*(C+D*E−F/G)]
POP A  → 결과를 A에 저장

 

기출 정답은 (1) MUL, (2) ADD, (3) DIV, (4) SUB, (5) MUL 순서입니다.

04편(프로세서와 명령어)에서 명령어 관점으로 다시 다룹니다.


연결 리스트 ⭐

구분 배열 연결 리스트
접근 인덱스로 O(1) 처음부터 따라가야 해서 O(n)
삽입·삭제 뒤의 요소를 밀어야 해서 O(n) 위치를 알면 포인터만 바꿔 O(1)
메모리 연속 공간 노드마다 포인터 공간이 추가로 필요
단순 연결 리스트: next 포인터만 있음 (한 방향)
이중 연결 리스트: prev + next (양방향)
원형 연결 리스트: 마지막 노드가 첫 노드를 가리킴
struct Node { int data; struct Node *next; };

/* head 앞에 새 노드 삽입 */
new_node->next = head;   /* 1) 새 노드가 기존 head를 가리키게 한 뒤 */
head = new_node;         /* 2) head를 새 노드로 바꾼다 */

/* p 다음 노드 삭제 */
tmp = p->next;
p->next = tmp->next;     /* tmp를 건너뛰도록 연결 */

 

⚠️ 삽입 순서를 바꿔 head = new_node를 먼저 하면 기존 리스트를 가리키던 포인터를 잃어서 리스트가 끊깁니다.


트리 ⭐⭐⭐

용어와 차수 계산 (2016-1, 2020-3, 2025-1)

              A
          /   |   \
         B    C    D
        / \   |   / \
       E   F  G  H   I
      / \       / | \
     J   K     L  M  N
노드의 차수  = 그 노드의 자식 수
트리의 차수  = 노드의 차수 중 최댓값
단말 노드   = 차수가 0인 노드 (자식이 없는 노드)

A=3  B=2  C=1  D=2  E=2  H=3  (나머지는 0)
→ 트리의 차수 = 3
→ 단말 노드 = J, K, F, G, L, M, N, I

 

트리 순회 3종 ⭐⭐⭐

전위(Preorder)  : Root → Left → Right    (루트가 앞)
중위(Inorder)   : Left → Root → Right    (루트가 가운데)
후위(Postorder) : Left → Right → Root    (루트가 뒤)

 

기출 후위 순회 문제(2018-1, 2018-3, 2015-10 유사)의 트리입니다. 그림은 해설을 바탕으로 다시 그렸습니다.

            A
           / \
          B   C
         /   / \
        D   E   F
           / \
          G   H
전위:  A B D C E G H F
중위:  D B A G E H C F
후위:  D B G H E F C A   ← 기출 정답

후위 풀이:
  1) 왼쪽 서브트리 B → D, B
  2) 오른쪽 서브트리 C → (E의 왼쪽 G, 오른쪽 H, 루트 E), F, C
  3) 마지막에 루트 A
  → D B G H E F C A

 

 

⚠️ 함정 패턴

"후위 순회는 루트를 먼저 방문한다" → 오답! (루트는 맨 마지막)
"서브트리 안에서는 순서가 자유롭다" → 오답! (각 서브트리에도 같은 규칙을 재귀 적용)
"B형 2019-11처럼 그림이 크면 한 번에 풀려고 함" → 서브트리 단위로 쪼개서 풀기

 

AVL 트리 ⭐⭐

정의:  모든 노드에서 |왼쪽 서브트리 높이 − 오른쪽 서브트리 높이| ≤ 1
       (균형 인수가 −1, 0, 1)
복구:  삽입·삭제 후 불균형이 생기면 회전으로 균형을 맞춤
성능:  검색·삽입·삭제 모두 O(log n)
불균형 유형 회전 방법
LL (왼쪽-왼쪽) 오른쪽 회전 1회
RR (오른쪽-오른쪽) 왼쪽 회전 1회
LR (왼쪽-오른쪽) 왼쪽 자식을 왼쪽 회전한 뒤, 노드를 오른쪽 회전
RL (오른쪽-왼쪽) 오른쪽 자식을 오른쪽 회전한 뒤, 노드를 왼쪽 회전

 

⚠️ 2026년 1회 Q18은 원문이 불완전하게 복원되어 있고, "서브트리 높이 차이 1 이하 → AVL 트리"라는 키워드만 확인됩니다.

높이 차 조건이 나오면 AVL이라고 답하세요.


정렬 ⭐⭐

알고리즘 최선 평균 최악 공간 안정성
선택 정렬 O(n²) O(n²) O(n²) O(1) 불안정
삽입 정렬 O(n) O(n²) O(n²) O(1) 안정
버블 정렬 O(n) (교환 없으면 종료하는 개선형) O(n²) O(n²) O(1) 안정
병합 정렬 O(n log n) O(n log n) O(n log n) O(n) 안정
퀵 정렬 O(n log n) O(n log n) O(n²) O(log n) 불안정
힙 정렬 O(n log n) O(n log n) O(n log n) O(1) 불안정

 

비교 정렬의 하한 (2026-1 Q19)

비교 기반 정렬은 어떤 알고리즘이든 최악의 경우 Ω(n log n) 이하로 줄일 수 없다

이유:  n개를 정렬한 결과는 n!가지 순열 중 하나
       비교 결과(예/아니오)로 구분하는 결정 트리의 잎이 최소 n!개
       트리 높이 ≥ log2(n!) ≈ n log n
→ 기출 답: O(n log n)

 

⚠️ 이 하한은 비교 기반 정렬에만 적용됩니다. 비교를 하지 않는 정렬(계수 정렬 등)에는 해당하지 않아요.

 

정렬 C 코드 출력 예측 (2021-1, 2022-1)

for (a = 0; a < len; a++)
    for (b = 0; b < len - 1 - a; b++)
        if (ct[b] > ct[b + 1]) {   /* 인접 요소 비교 후 교환 (버블 정렬) */
            tmp = ct[b]; ct[b] = ct[b + 1]; ct[b + 1] = tmp;
        }
2022-1 (정답 41234): ct = {4, 2, 1, 3}, len = 4
  sort 함수 첫 줄에서 len을 출력 → 4
  a=0: {4,2,1,3} → {2,4,1,3} → {2,1,4,3} → {2,1,3,4}
  a=1: {2,1,3,4} → {1,2,3,4}
  이후 교환 없음
  main에서 ct[0]~ct[3] 출력 → 1234
  → 4 + 1234 = 41234
  (기출은 내부 반복 조건이 b < 3 - a로 고정되어 있었음)

2021-1 (정답 9580705035): ct = {95, 50, 80, 35, 70}을 내림차순 정렬
  → {95, 80, 70, 50, 35}
  printf("%d")에 구분 문자가 없으므로 붙여서 출력
  → 9580705035

 

⚠️ 출력 예측에서는 printf 서식에 공백·줄바꿈이 있는지 반드시 확인하세요. 구분이 없으면 숫자가 붙어서 나옵니다.


탐색 ⭐

방법 시간 복잡도 조건
순차 탐색 O(n) 정렬 여부와 무관
이진 탐색 O(log n) 정렬된 자료가 전제
이진 탐색 예) [3, 8, 12, 19, 25, 31, 40] 에서 25 찾기
  low=0, high=6 → mid=3 (19)   25 > 19 → low=4
  low=4, high=6 → mid=5 (31)   25 < 31 → high=4
  low=4, high=4 → mid=4 (25)   찾음
→ 비교 3회

기출 Q&A

Q. Infix 수식 A / B * (C − D) + E를 Postfix로 변환하시오.

A. A B / C D − * E +
(2020 통합, 2021-1 동일 문항) 괄호 안 → 왼쪽부터 / 와 * → 마지막 +

 

Q. 다음 트리를 후위 순회한 결과를 쓰시오. (2018-1, 2018-3 트리: A 루트, B(D), C(E(G, H), F))

A. D B G H E F C A
왼쪽 서브트리 → 오른쪽 서브트리 → 루트 순서를 각 서브트리마다 적용

 

Q. 위의 차수 계산 트리(A~N)의 차수와 단말 노드는?

A. 트리의 차수 3, 단말 노드 J, K, F, G, L, M, N, I
(2016-1, 2020-3, 2025-1 동일 문항) 노드 A와 H의 차수 3이 최댓값

 

Q. 재귀 호출에서 지역 변수와 돌아올 복귀 주소를 저장하는 자료구조는?

A. 스택(Stack)
(2026-1 Q14) 함수가 호출될 때마다 스택 프레임이 쌓이고, 리턴하면 LIFO 순서로 하나씩 꺼내며 복귀합니다.

 

Q. 비교 기반 정렬의 최악 시간 복잡도 하한을 쓰시오.

A. O(n log n)
(2026-1) 결정 트리의 잎이 n!개 이상이므로 높이는 log2(n!) ≈ n log n


예상 문제 (직접 만든 문제)

Q1. 전위 순회 결과가 A B D E C, 중위 순회 결과가 D B E A C일 때 후위 순회 결과는?

A1. D E B C A
전위의 첫 값 A가 루트 → 중위에서 A 왼쪽(D B E)이 왼쪽 서브트리, 오른쪽(C)이 오른쪽 서브트리 → B가 왼쪽 서브트리의 루트(D 왼쪽, E 오른쪽)

 

Q2. 후위식 8 2 / 5 3 - * 1 +의 값은?

A2. 9 (위 스택 계산 과정 참고)

 

Q3. 정렬된 배열 [3, 8, 12, 19, 25, 31, 40]에서 25를 이진 탐색할 때 비교 횟수는?

A3. 3회 (mid 값 19 → 31 → 25)


💡 실무에서는?

  • 스택: 함수 호출 시 복귀 주소가 스택에 쌓이기 때문에, 재귀가 너무 깊어지면 스택 오버플로로 프로세스가 죽습니다. 보안 점검에서 버퍼 오버플로가 복귀 주소를 덮어쓰는 공격을 설명할 때도 같은 구조를 씁니다.
  • 큐: 메시지 큐나 로그 수집 파이프라인에서 생산자와 소비자 속도 차이를 흡수하는 버퍼 역할을 합니다.
  • 트리: 디렉터리 구조가 트리입니다. tree나 find는 디렉터리를 순회하고, rm -r은 자식을 먼저 지우고 부모를 지우는 후위 순회 방식입니다.
  • 정렬·탐색: 로그 분석에서 sort로 정렬한 파일은 이진 탐색으로 빠르게 찾을 수 있고, 정렬 안 된 로그는 순차로 훑어야 해서 크기가 커질수록 느려집니다.

핵심 정리

✅ 스택=LIFO(push/pop) / 큐=FIFO(enqueue/dequeue)
✅ 후위 변환: 괄호 → 우선순위 → 같으면 왼쪽부터, 전위는 연산자를 앞에
✅ 후위식 계산: 피연산자 push, 연산자는 pop 2번 후 결과 push
✅ 트리의 차수 = 노드 차수의 최댓값 / 단말 노드 = 차수 0
✅ 전위 NLR / 중위 LNR / 후위 LRN — 서브트리마다 재귀 적용
✅ AVL = 높이 차 1 이하, 회전 LL·RR·LR·RL
✅ 비교 정렬 하한 Ω(n log n) / 퀵 정렬 최악 O(n²)
✅ 이진 탐색은 정렬된 자료만 가능, O(log n)
✅ C 출력 예측은 printf 서식(구분 문자 유무) 확인

 

다음 편에서는 자료구조 II (그래프·인덱스·해싱)로 이어갑니다!

 

궁금한 점은 댓글로 남겨주세요!

반응형
개인정보처리방침  |  블로그 소개