DataStructrue
[자료구조] 리스트_연결 리스트(Linked List)
유하_122
2020. 9. 1. 18:22
연결 리스트(Linked List)
각 노드가 데이터와 포인터를 가지고 한 줄로 연결시키면서 자료를 저장하는 구조
장점 : 데이터의 추가/삭제가 빠르다.
단점 : 연결리스트를 처음부터 끝까지 순회해야돼서 조회가 느리다.
구조
구현
생성
LinkedList num = new LinkedList();
클래스
public class LinkedList {
private Node head; // 시작 위치
private Node tail; // 끝 위치
private int size = 0; // list 크기
private class Node {
private Object data; // data field, 노드 데이터
private Node next; // Link field, 다음 노드 정보
public Node(Object input) { // 초기화
this.data = input;
this.next = null;
}
public String toString() {
return String.valueOf(this.data);
}
}
}
추가
< 맨 앞에 추가 >
num.addFirst(30);
num.addFirst(20);
num.addFirst(10);
-
노드 생성
-
새로운 노드에 HEAD가 가리키는 노드(20)를 지정
-
HEAD에 새로운 노드 지정
public void addFirst(Object input) {
Node newNode = new Node(input); //노드 생성
newNode.next = head; // 새 노드의 Linked field에 head(다음노드) 지정
head = newNode; // 헤드에 새 노드 지정
size++; // list 크기
if (head.next == null) { // 노드가 하나일때
tail = head;
}
}
<맨 뒤에 추가>
num.addLast(10);
num.addLast(20);
num.addLast(30);
-
새로운 노드 생성
-
TAIL이 가리키는 노드(30)의 다음 노드로 새로운 노드를 지정
-
TAIL 노드에 마지막 노드 갱신
public void addLast(Object input) {
Node newNode = new Node(input); //새 노드 생성
if (size == 0) { //첫 노드일 경우
addFirst(input);
} else {
tail.next = newNode; // 마지막 노드에 다음 노드로 새 노드 지정
tail = newNode; // 마지막 노드 갱신
size++;
}
}
<특정한 위치에 노드 추가>
num.add(2,25);
-
temp1에 k번째 바로 전 노드를 지정
-
temp2에 k번째 노드 지정
-
새로운 노드 생성
-
temp1의 다음 노드로 새 노드를 지정
-
새 노드 다음 노드로 temp2 지정
public void add(int k, Object input) {
if (k == 0) { //첫 노드에 추가
addFirst(input);
} else {
Node temp1 = node(k - 1); //temp1에 k번째 바로 전 노드를 지정
Node temp2 = temp1.next; //temp2에 k번째 노드 지정
Node newNode = new Node(input); //새 노드 생성
temp1.next = newNode; //temp1의 다음 노드로 새 노드를 지정
newNode.next = temp2; //새 노드 다음 노드로 temp2 지정
size++;
if(newNode.next == null) //다음 노드가 없을 때(마지막노드)
tail = newNode;
}
}
탐색
Node node(int index) {
Node x = head; // head 노드 지정
for (int i = 0; i < index; i++) {
x = x.next;
}
return x;
}
삭제
<맨 앞 노드 삭제>
num.removeFirst();
-
temp 에 head(첫번째 노드) 지정
-
head에 두번째 노드 지정
-
삭제될 값을 리턴하기 위해 임시 변수에 넣음
public Object removeFirst() {
Node temp = head; // temp 에 head(첫번째 노드) 지정
head = head.next; // head에 두번째 노드 지정
Object returnData = temp.data; // 삭제될 값을 리턴하기 위해 임시 변수에 넣음
temp = null; // 노드 삭제
size--;
return returnData;
}
<특정한 위치에 있는 노드 삭제>
num.remove(5);
public Object remove(int k) {
if(k == 0) {
return removeFirst();
}else {
Node temp = node(k-1); // k번째 앞 노드의 값을 temp에 지정
Node todoDeleted = temp.next; // k번째 노드를 todoDeleted에 넣음
temp.next = temp.next.next; // k번째 뒷 노드를 temp의 다음 노드로 지정
Object returnData = todoDeleted.data;
if(todoDeleted == tail) { // 삭제하는 노드가 마지막 노드일 때
tail = temp;
}
todoDeleted = null; // 노드 삭제
size--;
return returnData;
}
}
리스트 크기
num.size();
public int size() {
return size;
}
가져오기
num.get(2);
public Object get(int k) {
Node temp = node(k);
return temp.data;
}
결과
public static void main(String[] args) {
LinkedList num = new LinkedList();
num.addFirst(30);
num.addFirst(20);
num.addFirst(10);
System.out.println(num);
num.addLast(10);
num.addLast(20);
num.addLast(30);
System.out.println(num);
num.add(2, 25);
System.out.println(num);
num.removeFirst();
num.remove(5);
System.out.println(num);
System.out.println("size : " + num.size());
System.out.println("get(2) : " + num.get(2));
}
[10,20,30]
[10,20,30,10,20,30]
[10,20,25,30,10,20,30]
[20,25,30,10,20]
size : 5
get(2) : 30