-
Linked List (연결 리스트)알고리즘/자료구조 2020. 12. 29. 21:26
Linked List
리스트 자료구조는 중복 저장을 허용하며 데이터를 나란히 저장한다.
자바에는 리스트 자료구조를 정의해놓은
List
컬렉션이 있다. (인터페이스)- 객체를 인덱스로 관리하여 객체를 삽입하면 인덱스가 자동으로 부여된다.
- 그래서 인덱스로 객체에 검색, 삭제가 가능하다.
- 객체를 직접 저장하고 있지 않고 객체의 주소를 가지고 있다.
- null도 저장이 가능하다. (아무것도 참조하지 않는 상태)
- 구현체로 ArrayList, LinkedList, Vector 등이 있다.
LinkedList(연결 리스트)
는 List 인터페이스의 구현체로메모리의 동적할당을 기반
으로 구현된 리스트다.
LinkedList의 모든 노드는 인접 노드를 참조해서 체인처럼 관리한다.노드를 리스트의 중간에 삽입하여도 인접한 노드들의 링크만 변경하면 되고, 다른 노드들에는 영향이 없다.
따라서 빈번한 객체 삽입/삭제가 일어날때 적합하다.ArrayList의 경우는 중간에 노드를 삽입하려면 해당 인덱스 뒤의 노드들을 모두 1씩 밀어야한다. 그래서 비용이 커진다.
그러나 맨 마지막에 객체를 추가하거나 인덱스 검색을 하는 경우엔 ArrayList의 성능이 더 좋다.자바 메소드
객체 추가
- booleanadd(E e)
: 객체를 맨 끝에 추가한다. 성공적으로 추가되면 true를 리턴한다.
- voidadd(int index, E element)
: 주어진 인덱스에 객체 추가한다.
- Eset(int index, E element)
: 주어진 인덱스에 저장된 객체를 주어진 객체로 바꾼다. 바꾸기 전 원래 객체를 리턴한다.
객체 검색
- booleancontains(Object o)
: 주어진 객체가 저장되어 있는지 여부를 확인한다. 저장되있으면 true를 리턴한다.
- Eget(int index)
: 주어진 인덱스에 저장된 객체를 리턴한다.
- booleanisEmpty()
: 컬렉션이 비어있으면 true를 리턴한다.
- intsize()
: 리스트의 크기를 리턴한다.
객체 삭제
- voidclear()
: 저장된 모든 객체를 삭제한다.
- Eremove(int index)
: 주어진 인덱스에 저장된 객체를 삭제하고 삭제한 객체를 리턴한다.
- booleanremove(Object o)
: 주어진 객체를 찾아서 삭제한다.자바 LinkedList 구현 (정수 저장 자료구조 LinkedNode)
package com.example.LinkedList; import java.util.Objects; public class ListNode { protected ListNode next; protected int data; public ListNode() { } public ListNode(int data) { this.data = data; } // before = 대상 인덱스를 가리키고 있는 노드 static public ListNode add(ListNode head, ListNode nodeToAdd, int position) { validatePositionInput(position); ListNode before = head; while (position > 0) { validateNextNode(before.next); before = before.next; position--; } if (!Objects.isNull(before.next)) { // 삽입하려는 인덱스가 비어있지 않은 경우 nodeToAdd.next = before.next; } before.next = nodeToAdd; return nodeToAdd; } public static ListNode remove(ListNode head, int positionToRemove) { validatePositionInput(positionToRemove); ListNode before = head; while (positionToRemove > 0) { validateNextNode(before.next); before = before.next; positionToRemove--; } ListNode removed = before.next; before.next = before.next.next; return removed; } static private void validatePositionInput(int position) { if (position < 0) { throw new IllegalArgumentException("포지션은 0이상 이어야 합니다."); } } static private void validateNextNode(ListNode nextNode) { if (Objects.isNull(nextNode)) { throw new NullPointerException("포지션이 리스트의 길이를 초과합니다."); } } public static boolean contains(ListNode head, ListNode nodeToCheck) { ListNode before = head; while (!Objects.isNull(before.next)) { if (before.next.equals(nodeToCheck)) { return true; } before = before.next; } return false; } }