🔷 특성
🔷 노드
데이터 필드
링크 필드
🔷 헤드
🔷 연결 구조
삽입
삭제
🖥 Node.java
// 데이터 필드, 다음 노드를 가리키는 링크 필드 하나로 구성
public class Node {
public String data; // 제네릭 이용시 더 포괄적인 데이터 사용 가능
public Node link; // 주소를 저장하기 위해 Node 자료형 사용
public Node() {} // 기본 생성자
public Node(String data) {
this.data = data;
this.link = null; // null은 알아서 초기화되기 때문에 필요 없는 코드
}
@Override
public String toString() {
return "Node [data=" + data + "]";
}
}
🖥 SinglyLinkedList.java
public class SinglyLinkedList {
// 필드
private Node head; // 노드의 시작점
private int size; // 연결리스트의 노드의 개수 (필수는 아니지만 있을 때 편하다)
// 조회
public Node get(int idx) {
// 인덱스가 범위를 초과해버릴 때 예외 처리
if(idx < 0 || idx >= size) {
// null return 혹은 첫번째 노드나 마지막 노드 반환 등
return null;
}
// idx 위치만큼 이동
Node curr = head;
for(int i = 0; i < idx; i++) {
curr = curr.link;
}
return curr;
}
// 첫번째 위치에 원소 삽입
public void addFirst(String data) {
// 노드 생성
Node node = new Node(data); // 생성자를 이용한 인스턴스 생성
// 순서 중요! (head를 먼저 끊으면 이후의 것들이 가비지컬렉터에게 잡아먹힘)
node.link = head;
head = node; // head가 첫번째 원소를 가리킨다
size++;
}
// 마지막 위치에 원소 삽입
public void addLast(String data) {
// 공백 리스트일 때는 처음에 넣는다.
if(size == 0) {
addFirst(data);
return;
}
Node node = new Node(data);
// 마지막 노드 탐색
Node curr = head;
while(curr.link != null) {
curr = curr.link;
}
curr.link = node;
size++;
}
// 중간 원소 삽입
public void add(int idx, String data) {
// 리스트 범위 초과 시
if(idx < 0 || idx >= size) {
System.out.println("잘못된 인덱스입니다.");
return;
}
// 들어온 인덱스가 0(처음)일 시
if(idx == 0) {
addFirst(data);
return;
}
// 들어온 인덱스가 마지막 위치일 시
if(idx == size) {
addLast(data);
return;
}
Node pre = get(idx-1); // 조회 함수 이용
Node node = new Node(data);
node.link = pre.link;
pre.link = node;
size++;
}
// 첫 번째 원소 삭제
public String remove() {
if(head == null)
return null;
String data = head.data;
head = head.link;
size--;
return data;
}
// 중간 원소 삭제
public String remove(int idx) {
if(idx == 0)
return remove(); // 주의! 함수를 리턴한 것이 아니라 함수의 결과값(문자열)을 리턴한 것!
if(idx < 0 || idx >= size)
return null;
Node pre = get(idx-1);
Node rmNode = pre.link; // 삭제할 노드
String data = rmNode.data;
pre.link = rmNode.link;
size--;
return data;
}
// 연결리스트 내용물 출력
public void printList() {
Node curr = head;
if(head == null) {
System.out.println("공백 상태입니다.");
return;
}
// 1. size를 쓰는 for문
// 2. size를 쓰지 않는 while문 (현재)
while(curr != null) {
System.out.print(curr.data + " -> ");
curr = curr.link;
}
System.out.println();
}
}
🖥 Test.java
public class Test {
public static void main(String[] args) {
SinglyLinkedList list = new SinglyLinkedList();
list.printList();
list.addFirst("박영규");
list.printList();
list.addFirst("박영순");
list.printList();
list.addFirst("박영훈");
list.printList();
list.addLast("박민정");
list.printList();
System.out.println(list.get(0));
System.out.println(list.get(-1));
list.add(2, "박지원");
list.add(4, "박씨");
list.printList();
list.remove();
list.printList();
list.remove(2);
list.printList();
}
}
🔷 특성
🔷 연결 구조
삽입
삭제
🌟
배열
VS연결리스트
삽입과 삭제 면에서는 연결리스트가 좋지만
조회 면에서는 배열이 더 좋다.