연결 리스트 (Linked List)

2024. 6. 23. 21:41·CS/Data Structure
목차
  1. 자료구조: 연결 리스트

자료구조: 연결 리스트

연결 리스트(Linked List)는 노드(Node)라는 개별 요소들이 순차적으로 연결된 형태의 자료구조입니다. 각 노드는 데이터와 다음 노드에 대한 참조(포인터)를 가지고 있습니다. 연결 리스트는 배열과 달리 요소들이 메모리 상에 연속적으로 배치되지 않으며, 동적으로 크기가 조정될 수 있습니다.

연결 리스트의 종류

  1. 단일 연결 리스트(Singly Linked List):
    • 각 노드는 하나의 데이터와 다음 노드를 가리키는 하나의 포인터를 가집니다.
    • 마지막 노드는 다음 노드에 대한 포인터가 null입니다.
  2. 이중 연결 리스트(Doubly Linked List):
    • 각 노드는 데이터와 두 개의 포인터(이전 노드와 다음 노드)를 가집니다.
    • 양방향으로 순회가 가능합니다.
  3. 원형 연결 리스트(Circular Linked List):
    • 마지막 노드의 다음 노드가 첫 번째 노드를 가리키는 구조입니다.
    • 단일 또는 이중 연결 리스트 형태로 구현될 수 있습니다.

연결 리스트의 특징

  • 동적 크기 조정: 노드를 추가하거나 제거함에 따라 리스트의 크기가 동적으로 조정됩니다.
  • 비연속적 메모리 배치: 노드들이 메모리 상에 비연속적으로 배치됩니다.
  • 삽입 및 삭제의 효율성: 중간에 노드를 삽입하거나 삭제하는 연산이 배열보다 효율적입니다.

연결 리스트의 장단점

장점:

  • 크기가 동적으로 조정되므로 메모리 효율적 사용이 가능합니다.
  • 중간에 요소를 삽입하거나 삭제하는 작업이 배열보다 효율적입니다(포인터 조작만으로 가능).

단점:

  • 인덱스를 통한 접근 속도가 느립니다(O(n)).
  • 추가적인 포인터 저장 공간이 필요합니다.

연결 리스트와 배열의 비교

  • 접근 속도: 배열은 인덱스를 통한 빠른 접근이 가능 > 연결 리스트는 순차적으로 접근
  • 삽입 및 삭제: 연결 리스트는 중간에 요소를 삽입하거나 삭제할 때 효율적 > 배열은 모든 요소를 이동시켜야 하기 때문에 비효율적입니다.
  • 메모리 사용: 배열은 고정된 크기를 가지며, 크기를 변경하기 어렵지만, 연결 리스트는 필요에 따라 크기를 조정할 수 있습니다.
  배열 연결리스트
크기 고정 동적
주소 연속 불연속
데이터 참조 O(1) O(n)
삽입과 삭제 O(n) -  기존 모든 데이터 이동 필요 O(n) - 삽입하려는 노드까지 계속 타고 가야 함

 

자바스크립트 예시

class Node {
    constructor(value) {
        this.value = value;
        this.next = null;
    }
}

class LinkedList {
    constructor() {
        this.head = null;
        this.size = 0;
    }

    // 리스트의 끝에 노드를 추가합니다.
    append(value) {
        const newNode = new Node(value);
        if (this.head === null) {
            this.head = newNode;
        } else {
            let current = this.head;
            while (current.next !== null) {
                current = current.next;
            }
            current.next = newNode;
        }
        this.size++;
    }

    // 특정 인덱스에 노드를 추가합니다.
    insertAt(value, index) {
        if (index < 0 || index > this.size) {
            return console.log("Invalid index");
        }
        const newNode = new Node(value);
        let current = this.head;
        let previous;
        if (index === 0) {
            newNode.next = this.head;
            this.head = newNode;
        } else {
            for (let i = 0; i < index; i++) {
                previous = current;
                current = current.next;
            }
            newNode.next = current;
            previous.next = newNode;
        }
        this.size++;
    }

    // 특정 인덱스의 노드를 제거합니다.
    removeAt(index) {
        if (index < 0 || index >= this.size) {
            return console.log("Invalid index");
        }
        let current = this.head;
        let previous;
        if (index === 0) {
            this.head = current.next;
        } else {
            for (let i = 0; i < index; i++) {
                previous = current;
                current = current.next;
            }
            previous.next = current.next;
        }
        this.size--;
        return current.value;
    }

    // 특정 값을 가진 노드를 제거합니다.
    remove(value) {
        let current = this.head;
        let previous = null;

        while (current !== null) {
            if (current.value === value) {
                if (previous === null) {
                    this.head = current.next;
                } else {
                    previous.next = current.next;
                }
                this.size--;
                return current.value;
            }
            previous = current;
            current = current.next;
        }
        return null;
    }

    // 리스트에서 특정 값을 찾습니다.
    indexOf(value) {
        let current = this.head;
        let index = 0;

        while (current !== null) {
            if (current.value === value) {
                return index;
            }
            current = current.next;
            index++;
        }
        return -1;
    }

    // 리스트가 비어 있는지 확인합니다.
    isEmpty() {
        return this.size === 0;
    }

    // 리스트의 크기를 반환합니다.
    sizeOfList() {
        return this.size;
    }

    // 리스트의 모든 원소를 출력합니다.
    printList() {
        let current = this.head;
        let result = '';
        while (current !== null) {
            result += current.value + (current.next ? ' -> ' : '');
            current = current.next;
        }
        console.log(result);
    }
}

// 사용 예시
const ll = new LinkedList();

 

'CS > Data Structure' 카테고리의 다른 글

해시테이블 (Hash Table)  (0) 2024.07.01
덱 (Deque)  (0) 2024.06.30
큐 (Queue)  (0) 2024.06.25
스택 (Stack)  (0) 2024.06.24
배열 (Array)  (0) 2024.06.23
  1. 자료구조: 연결 리스트
'CS/Data Structure' 카테고리의 다른 글
  • 덱 (Deque)
  • 큐 (Queue)
  • 스택 (Stack)
  • 배열 (Array)
예슬e
예슬e
예슬e
예슬e개발로그
예슬e
전체
오늘
어제
  • 분류 전체보기 (27)
    • 💙 At work in 2024 (0)
    • FrontEnd (7)
      • React (7)
      • Package Manager (0)
      • Build System (0)
      • Transpiler & Bundler (0)
      • Architecture (0)
      • Test (0)
    • BackEnd (2)
    • CS (8)
      • Data Structure (7)
      • Network (1)
    • Algorithm (10)
    • Project (0)
    • Blog (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

재귀
jsx
useEffect
자료구조
useState
자바스크립트배열
메모이제이션
리액트딥다이브
하노이의탑
api만들기
리액트 파이버
알고리즘
리렌더링
리액트
리액트파이버
useCallback
자바스크립트
백엔드
타뷸레이션
프론트엔드

최근 댓글

최근 글

hELLO· Designed By정상우.v4.5.3
예슬e
연결 리스트 (Linked List)
상단으로

티스토리툴바

단축키

내 블로그

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

블로그 게시글

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

모든 영역

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

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