자료구조는 프로그래밍에서 데이터를 효율적으로 저장하고 관리하기 위한 중요한 개념입니다. 그중에서도 리스트(List)는 가장 기본적이면서도 다양한 활용성을 가진 자료구조입니다. 이번 글에서는 리스트 인터페이스를 설계하겠습니다.
1. 리스트란?
리스트(List)는 자료를 순서대로 저장하는 선형 자료구조입니다.
- 선형 구조란 데이터가 논리적 혹은 물리적으로 순서대로 연결되어 있다는 것을 의미합니다.
- 리스트는 데이터를 추가하거나 삭제, 조회하기 쉽도록 설계된 자료구조로, 순차적 데이터 처리에 적합합니다.
리스트의 특징
- 데이터의 앞/뒤 순서를 유지합니다.
- 물리적이거나 논리적으로 선형 구조를 갖습니다.
- 다양한 언어에서 기본적으로 제공되며, 배열(Array)과 비슷하지만 기능이 더 확장되었습니다.
2. 리스트를 구현하는 자료구조
리스트를 구현하는 방법에는 여러 가지가 있으며, 대표적으로 배열 리스트(ArrayList)와 연결 리스트(LinkedList)가 있습니다.
배열 리스트 (ArrayList)
- 데이터가 연속된 메모리 공간에 저장됩니다.
- 장점:
- 인덱스를 통한 데이터 접근이 빠릅니다. 시간 복잡도(O1)
- 구현이 쉽고, 데이터가 많지 않을 경우 효율적입니다.
- 단점:
- 크기를 미리 지정해야 하며, 크기 변경이 어렵습니다.
- 중간에 데이터를 추가/삭제할 때 비효율적입니다.
연결 리스트 (LinkedList)
- 데이터가 노드(Node)라는 단위로 저장되고, 각 노드가 다음 노드를 가리키는 포인터를 가집니다.
- 장점:
- 크기를 동적으로 조정할 수 있습니다.
- 데이터의 추가/삭제가 효율적입니다.
- 단점:
- 특정 위치에 접근하려면 처음부터 순회해야 하므로 속도가 느립니다.
- 구현이 배열 리스트보다 복잡합니다.
3. 리스트를 구현하기 위한 메서드
리스트 자료구조를 설계할 때 필요한 핵심 동작은 다음과 같습니다:
- 리스트 생성: 리스트를 초기화합니다.
- 데이터 추가:
- 리스트 끝에 데이터를 추가합니다. (append/add)
- 특정 위치에 데이터를 삽입합니다. (insert)
- 데이터 삭제:
- 특정 위치의 데이터를 삭제합니다. (remove)
- 리스트 전체 데이터를 삭제합니다. (removeAll)
- 데이터 조회:
- 특정 위치의 데이터를 가져옵니다. (get)
- 리스트 상태 확인:
- 리스트 크기를 반환합니다. (size)
- 리스트가 비어 있는지 확인합니다. (isEmpty)
- 리스트 출력: 리스트의 모든 데이터를 출력합니다. (printAll)
4. 제네릭(Generic) 이해하기
제네릭(Generic)이란 타입을 일반화하여, 여러 가지 타입에 대해 동작할 수 있는 코드를 작성하는 방법입니다.
리스트 같은 자료구조는 다양한 데이터 타입(예: Integer, String, Double)을 저장할 수 있어야 하므로 제네릭이 유용합니다.
제네릭의 주요 특징
- 타입 안정성:
- 제네릭을 사용하면 컴파일 단계에서 타입 체크를 수행하므로, 런타임 에러를 줄일 수 있습니다.
- 코드 재사용성:
- 한 번 작성한 제네릭 클래스나 인터페이스는 여러 타입에서 재사용할 수 있습니다.
- 명확한 타입 지정:
- 데이터 타입을 명시적으로 지정하므로 코드 가독성이 향상됩니다.
예시
public interface ListIfs<T> {
void add(T data); // 데이터를 추가
T get(int index); // 데이터를 가져옴
T remove(int index); // 데이터를 삭제
boolean isEmpty(); // 리스트가 비어있는지 확인
int size(); // 리스트 크기 반환
}
위 코드에서 T는 타입 매개변수로, 리스트에 저장할 데이터 타입을 나타냅니다.
사용 예:
- ListIfs<String>: 문자열 데이터를 저장하는 리스트.
- ListIfs<Integer>: 정수를 저장하는 리스트.
5. 설계한 리스트 인터페이스
아래는 앞으로 저희가 설계할 리스트 인터페이스입니다
package util.linkedlist;
public interface ListIfs<T> {
// 데이터를 리스트 끝에 추가
void add(T x);
// 특정 위치에 데이터 삽입
void insert(int i, T x);
// 특정 위치의 데이터 반환
T get(int i);
// 특정 위치의 데이터 삭제
T remove(int i);
// 리스트의 모든 데이터 삭제
void removeAll();
// 리스트 크기 반환
int size();
// 리스트가 비어 있는지 확인
boolean isEmpty();
// 리스트의 모든 데이터를 출력
void printAll();
}
인터페이스를 활용한 구현은 다음 글에서 뵙겠습니다.
'Java' 카테고리의 다른 글
[Java] 인스턴스 내부 클래스 (0) | 2024.12.05 |
---|---|
[Java] for-each 루프 (0) | 2024.12.04 |
[Java] 1급 커넥션 (0) | 2024.10.14 |
[Java] Arrays, Array 메소드 정리 (0) | 2024.08.14 |
[Java] String 메소드 정리 (0) | 2024.08.13 |