배열(array)는 여러 데이터를 연속된 메모리에 저장할 때 사용하는 자료 구조로, 동일한 자료형의 데이터를 한꺼번에 순차적으로 관리할 수 있게 해준다.
따라서, 배열은 인덱스가 중요하거나 인덱스를 통한 데이터 탐색이 빈번할 때 효과적인 자료구조이다.
public class ArrayTest {
public static void main(String[] args) {
int[] numbers = new int[4];
int[] numbers2 = { 0, 1, 2 };
System.out.println(numbers.length);
System.out.println(numbers2.length);
for (int i = 0; i < numbers.length; i++) {
numbers[i] = i + 1;
}
for (int i = 0; i < numbers.length; i++) {
System.out.println(numbers[i]);
}
}
}
동적 배열(dynamic array)(a.k.a ArrayList)이란 배열의 특성은 가지되, 고정된 길이를 갖는 배열의 한계를 극복하기 위해 나온 자료구조이다.
- 배열의 크기를 변경하는 resize() 연산은 시간 복잡도가 O(n)이다.
- resize() 연산은 새로운 크기의 배열을 만든 후 기존 배열을 복사하는 방식으로 진행되기 때문에 O(n)의 시간 복잡도를 갖는다.
- 데이터를 배열의 맨 끝에 추가하는 append() 연산은 시간 복잡도가 O(1)이다.
- 재할당 전략: 데이터가 추가될 때, 배열의 크기를 기존 배열의 크기만큼 늘리는 전략
- 재할당 전략을 사용하지 않고 데이터의 메모리 크기만큼 배열의 크기를 늘린다면, append()연산을 n번 진행한다고 했을 때 n(n+1)/(2*n)만큼, 즉 O(n)의 시간 복잡도를 가진다. (n + 2n + 3n + ... + n^2)/n = (n+1)/2 = O(n)
- 재할당 전략을 사용하고 기존 배열에 데이터가 꽉찬 상태에서 데이터가 추가될 때 기존 배열의 크기만큼 배열의 크기를 늘린다면, append() 연산을 n번 진행한다고 했을 때 O(n/n) = O(1)만큼의 시간 복잡도를 가진다. 이는 resize() 연산의 시간 복잡도가 O(n)이고 이를 평균내면 O(1)이기 때문이다.
동적 배열 사용 예제
import java.util.ArrayList;
public class ArrayListTest {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
for (String s : list) {
System.out.println(s);
}
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
}
Linked List는 데이터와 다음 데이터의 메모리 주소(link)를 함께 저장하여 연속되지 않은 메모리를 사용하는 자료 구조이다.
Linked List의 특징
Linked List의 한계
따라서, Linked List는 데이터의 추가/삭제가 빈번하게 발생할 때 효과적인 자료구조이다.
Linked List 사용 예제
Linked List 데이터 추가
LinkedList<Integer> list = new LinkedList<Integer>();
list.addFirst(1);//가장 앞에 데이터 추가
list.addLast(2);//가장 뒤에 데이터 추가
list.add(3);//데이터 추가
list.add(1, 10);//index 1에 데이터 10 추가
Linked List 데이터 삭제
LinkedList<Integer> list = new LinkedList<Integer>(Arrays.asList(1,2,3,4,5));
list.removeFirst(); //가장 앞의 데이터 제거
list.removeLast(); //가장 뒤의 데이터 제거
list.remove(); //생략시 0번째 index제거
list.remove(1); //index 1 제거
list.clear(); //모든 값 제거
Linked List 크기
LinkedList<Integer> list = new LinkedList<Integer>(Arrays.asList(1,2,3));
System.out.println(list.size()); // 3
Linked List 값 출력
LinkedList<Integer> list = new LinkedList<Integer>(Arrays.asList(1,2,3));
System.out.println(list.get(0));//0번째 index 출력
for(Integer i : list) { //for문을 통한 전체출력
System.out.println(i);
}
Iterator<Integer> iter = list.iterator(); //Iterator 선언
while(iter.hasNext()){
System.out.println(iter.next());
}
Linked List 값 검색
LinkedList<Integer> list = new LinkedList<Integer>(Arrays.asList(1,2,3));
System.out.println(list.contains(1)); //list에 1이 있는지 검색 : true
System.out.println(list.indexOf(1)); //1이 있는 index반환 없으면 -1