Cs

자료구조

Terror123 2025. 1. 23. 16:23

개요

  • 자료구조에 대한 차이점을 구분하고 이해 할 수 있습니다

ArrayList의 가장 큰 특징과 그로 인해 발생하는 장점과 단점에 대해 설명해주세요

  • 순차적으로 데이터를 저장함 (연속된 메모리공간을 유지)
  • 장점
    • 데이터에 순서가 있기때문에 0부터 시작하는 index가 존재하며, index를 사용해 특정 요소를 찾고 조작이 가능
  • 단점
    • 순차적으로 존재하는 데이터의 중간에 요소가 삽입되거나 삭제되는 경우 그 뒤의 모든 요소들을 한칸씩 뒤로 밀거나 당겨줘야함
  • 이러한 이유로 Array는 정보가 자주 삭제되거나 추가되는 데이터를 담기에는 적절치 않습니다
  • 특정 인덱스 접근:
    • O(1)
  • 삽입 (add):
    • O(1)
  • 중간삽입 (인덱스를 활용한)
    • O(N)
  • 삭제:
    • O(N)
    • [1,2,3,4,5] 라는 배열이 존재할때, 3을 없애버리면
    • [1,2,-,4,5] 가되고, Array는 연속된 메모리 공간을 유지 해야하기 때문에
    • [1,2,4,5,-] 가되면서, O(n)의 시간이 소요된다

Array를 적용시키면 좋을 데이터의 예를 구체적으로 들어주세요

  • Array를 적용시키면 좋은 예시로 영화관의 좌석이 있습니다
  • 고정된 좌석수에서, 순서가 중요하고 특정 Index의 자리를 빠르게 탐색 할 수 있습니다

Stack과 Queue

  • 선형 자료구조의 일종
    • 데이터가 연속적이고 순차적으로 배치되는 구조

Stack

  • LIFO (Last In First Out), 마지막에 들어간 원소가 처음 나오는구조

Queue

  • FIFO (First In First Out), 처음 들어간 원소가 처음 나오는 구조

Tree와 Heap

Tree

  • 비선형 자료구조
  • 계층적 관계를 표현하기에 적합

Heap

  • 최댓값 또는 최솟값을 찾아내는 연산을 쉽게 하기위해 고안된 구조
  • 각 노드의 키값이 자식의 키값보다 작지않거나(최대힙), 그 자식의 키값보다 크지 않은(최소힙) 완전이진트리

Stack과 Queue의 실사용 예를 간단히 설명해주세요

Stack

  • LIFO
  • 웹브라우저의 뒤로가기 기능
  • 새페이지를 방문할떄 Stack에 쌓이고
  • 뒤로가기 버튼을 눌렀을떄 맨마지막에 Stack에 쌓인(바로 최근에 누른 새페이지)를 pop하고 이전페이지로 이동

Queue

  • FIFO
  • 프린터 작업 대기열
  • 먼저 요청받은 용지를, 먼저 처리하는 방식

Priority Queue(우선순위 큐)에 대해 설명해주세요

  • 들어간 순서에 상관없이 우선순위가 높은 데이터를 먼저 꺼내기 위해 고안된 자료구조
  • 우선순위 큐 구현 방식에는 배열,연결 리스트(Linked List), 힙이 있고, 그 중 힙 방식이 worst case라도
    시간 복잡도 O(log n)을 보장하기 때문에 일반적으로 완전 이진 트리 형태의 힙을 이용해 구현합니다

Array와 ArrayList의 차이점

  • ArrayList도 내부적으로는 Array에 기반하여 동작되기 때문에, 기존 배열 갯수를 초과하여 데이터를 넣지않는 이상까지는 동일하다

    Array

  • 크기가 고정적
  • 초기화시 메모리에 할당되어 속도가 빠름
  • Ex)
    • 크기가 4인 배열이 존재
    • append를 통해 4개까지 삽입가능

ArrayList

  • 크기가 가변적
  • 데이터 추가 및 삭제시 메모리의 재할당으로 인한 속도의 느림
  • Ex)
    • 크기가 n인 가변배열 존재
    • add를 통해 데이터를넣고, n개를 초과할경우
    • 새로운 배열 (기존 배열보다 큰)을 만든다 -> 기존 배열의 데이터를 새로운 배열에 옮긴다 -> add를 통한 데이터를 추가 하는 방식

Array와 LinkedList의 장/단점

Array

  • 연속적인 메모리 특성
  • 장점:
    • 인덱스 기반 조회속도 O(1)
  • 단점:
    • 중간삽입,삭제시 O(n) 연산소요

LinkedList

  • 비연속적인 메모리 특성
  • 장점:
    • 중간삽입,삭제시 O(1) 연산소요
  • 단점:
    • 각 노드는 포인터로 연결되어있어, 특정 위치의 데이터를 찾기위해 첫 노드부터 탐색해야하므로, O(n)의 연산수행이 소요된다
    • 노드1을 통해야만, 노드2로 갈 수 있고
    • 노드2를 통해야만, 노드3를 갈 수 있다는 의미이다

Test (조회)

package 리스트;

import java.util.ArrayList;
import java.util.LinkedList;

public class ExamList {
    public static void main(String[] args) {
        LinkedList<Integer> linkList = new LinkedList<>();
        ArrayList<Integer> list = new ArrayList<>();

        for ( int i=0; i<10000000; i++ ) {
            linkList.add(i);
            list.add(i);
        }

        long start = System.nanoTime();
        linkList.get(9999999);
        long end = System.nanoTime();
        System.out.println("링크 리스트 조회 시간" + (end - start) + "ns");
        start = System.nanoTime();
        list.get(9999999);
        end = System.nanoTime();
        System.out.println("일반 리스트" + (end - start) + "ns");

    }
}

  • 확실히 Array에 기반한 List의 속도가 더욱 빠른것을 알 수 있다
  • 다음은 삭제 속도를 비교해보자

Test (삭제)

package 리스트;

import java.util.ArrayList;
import java.util.LinkedList;

public class ExamList {
    public static void main(String[] args) {
        LinkedList<Integer> linkList = new LinkedList<>();
        ArrayList<Integer> list = new ArrayList<>();

        for ( int i=0; i<10000000; i++ ) {
            linkList.add(i);
            list.add(i);
        }

        long start = System.nanoTime();
        linkList.remove(555555);
        long end = System.nanoTime();
        System.out.println("링크 리스트 삭제 시간" + (end - start) + "ns");
        start = System.nanoTime();
        list.remove(555555);
        end = System.nanoTime();
        System.out.println("일반 리스트 삭제 시간" + (end - start) + "ns");

    }
}

  • 확실히 속도가 빠른것을 확인 할 수 있다

Test (중간삽입)

package 리스트;

import java.util.ArrayList;
import java.util.LinkedList;

public class ExamList {
    public static void main(String[] args) {
        LinkedList<Integer> linkList = new LinkedList<>();
        ArrayList<Integer> list = new ArrayList<>();

        for ( int i=0; i<10000000; i++ ) {
            linkList.add(i);
            list.add(i);
        }

        long start = System.nanoTime();
        linkList.add(555555,99);
        long end = System.nanoTime();
        System.out.println("링크 리스트 중간삽입 시간" + (end - start) + "ns");
        start = System.nanoTime();
        list.add(555555,99);
        end = System.nanoTime();
        System.out.println("일반 리스트 중간삽입 시간" + (end - start) + "ns");

    }
}

  • 검증이 완료되었다

Hash Table

  • 데이터를 key-value 쌍으로 저장하는 자료 구조
  • 데이터를 빠르게 삽입,삭제,검색 할수있도록 설계되었으며, 해싱이라는 방식을 사용하여 데이터를 저장하고 조회합니다
  • 해시 함수
    • key를 받아 고유한 정수 (해시코드)로 변환
    • 이 해시코드가 내부적으로 인덱스 역할을하여 O(1)의 검색조회속도가 가능하다

Test

  • 예시를 봐보자
package 맵;

import java.util.Hashtable;

public class ExamMap {
    public static void main(String[] args) {
        Hashtable<String, Integer> map = new Hashtable<>();
        map.put("One",1);
        map.put("Two",2);
        map.put("Three",3);
    }
}
  • 위와같은 코드는 아래와 같은 형태로 저장되어있다
  • One이라는 키의 value를 찾는 흐름은 아래와 같다:
    1. One의 hashCode() % 16 = 4
      • 여기서 16은 HashMap의 내부 배열 크기 (기본값: 16)다.
    2. Index 4에 접근 (O(1))
      • 배열의 4번 인덱스에 바로 접근.
    3. Index 4에 저장된 데이터는 "버켓(Bucket)"에 저장되어 있다.
      • 버켓은 기본적으로 연결 리스트 또는 Red-Black Tree로 구현된다.
    4. 버켓 내부에서 One이라는 키를 찾기 위해 키를 비교하며 탐색.
      • 최악의 경우 O(n)의 시간 복잡도가 발생한다.
      • Java 8 이후, 연결 리스트가 8개 이상이면 Red-Black Tree로 변환되어 탐색이 O(log n)으로 최적화된다.
    5. 키가 One과 일치하는 데이터를 찾으면 해당 value를 반환한다.

Red Black Tree?

  • BST를 기반하여 만들어진 Tree
  • 각 노드의 색깔을 빨강,검정으로 구분짓는다
  • 빨강 노드가 연속 두번으로 나오면 규칙을 위반하였다고 판단 (트리가 한쪽으로 치우쳐졌다고 판단)
  • 트리를 재조정하는 형식이다

HashMap과, HashTable의 차이점


BST, BT에 대해 설명해주세요

  • BT (Binary Tree - 이진 트리):
    • 자식 노드가 최대 두개인 노드들로 구성된 트리
  • BST (Binary Search Tree - 이진 탐색 트리)
    • 이진탐색 + LikedList를 결합한 자료구조
    • 검색할때의 시간복잡도는 O(h)
    • 트리가 치우쳐진 worst case의 경우 O(n)까지 소요될 수 있음
  • 이러한 worst case의 BST를 막기위한 Tree가 RBT(Red-Black-Tree)다

RBT에 대해 설명해주세요

  • 자기 균형 이진 탐색 트리
  • BST에 기반한 Tree 형식 자료구조
  • BST의 삽입,삭제 연산과정에서 발생할 수 있는 문제점을 만들기위해 만들어짐
  • BST의 특징을 모두 가지고 있음
  • 노드의 child가 없을 경우, child를 가리키는 포인터는 NIL값을 저장
  • 이러한 NIL들을 leaf node로 간주
  • 모든 노드를 Red or Black으로 색칠하며, 연결된 노드들은 색이 중복되지 않음
  • 항상 균형상태를 유지하여 최악의 경우(worst case)에서도 O(log n)을 유지

참조 문헌

https://dev-coco.tistory.com/159

'Cs' 카테고리의 다른 글

HTTPS ?  (0) 2025.01.28
CS 기초 공부 - IP 주소  (0) 2025.01.23
Tree ?  (1) 2025.01.22
TCP/IP 4계층 모델이란 ?  (1) 2025.01.22
사이드 이펙트란?  (0) 2025.01.21