본문 바로가기

CS/자료구조

자료 구조 - 배열, 연결 리스트

C언어로 쉽게 풀어쓴 자료구조를 읽으며 정리


배열

  • 인덱스와 요소 쌍의 집합
  • 메모리의 연속된 위치에 구현된다.
  • 크기 5인 배열 A가 있을 때 메모리 주소는 아래와 같다.
Element Memory Address
A[0] base * 1 * sizeof(type of Element)
A[1] base * 2 * sizeof(type of Element)
A[2] base * 3 * sizeof(type of Element)
A[3] base * 4 * sizeof(type of Element)
A[4] base * 5 * sizeof(type of Element)

 

 

함수의 매개 변수로서의 배열

  • C언어에서 함수의 매개 변수로 배열을 전달하는 것은, 배열의 포인터가 전달되는 것과 같다.
  • Swift 역시 배열 자체가 아닌 배열의 참조가 전달된다.
  • Swift에서의 배열은 Value 타입이다. 즉 배열을 변수에 할당하거나 메서드에 전달할 때 배열의 복사본이 전달된다.
  • Swift는 Copy-On-Write 방식을 사용한다. (복사는 배열이 수정될 때만 발생된다)

장점

  • Random Access
  • 인덱스로 특정 요소에 접근 시간 복잡도는 O(1)

단점

  • 삽입, 삭제 시간 복잡도는 O(n)

Swift에서 삽입 삭제 메서드

  • append(_:) : 평균 O(1), 최악 O(n)
  • insert(_:at:) : i가 중간 위치라면 O(1), 맨 끝이라면 append와 동일
  • removeLast() : 항상 O(1)
  • remove(at:) : 문서에는 O(n)으로만 나와있는데, 마지막 위치라면 O(1)이 될 것임.

마지막 위치의 삽입에서도 최악의 경우 O(n)의 시간 복잡도가 걸리는 이유

 

Swift 배열은 동적 배열이다.

 

배열은 일정 크기만큼 메모리를 할당한 다음, 그 크기가 초과되면 메모리 크기를 두 배로 늘린다. 배열의 크기와 저장 용량(capacity)가 동일해진 경우 현재 용량의 두 배 크기의 새로운 메모리 블록을 할당할 것이다.이 과정에서 기존 메모리 블록의 모든 요소들이 새로운 메모리 블록으로 복사되므로 O(n)의 시간 복잡도가 소요된다.

 

var greeting = "Hello, playground"

var array = [Int]()
for i in 1...8 {
    array.append(i)
    print("Array count: \(array.count), capacity: \(array.capacity)")
}

array.append(9) // This will trigger a reallocation
print("After appending 9, count: \(array.count), capacity: \(array.capacity)")

//Array count: 1, capacity: 2
//Array count: 2, capacity: 2
//Array count: 3, capacity: 4
//Array count: 4, capacity: 4
//Array count: 5, capacity: 8
//Array count: 6, capacity: 8
//Array count: 7, capacity: 8
//Array count: 8, capacity: 8
//After appending 9, count: 9, capacity: 16

 

연결 리스트

각 요소(Element)와 링크의 쌍인 노드에 분산 저장하는 자료구조이다.

  • 배열과 다르게 메모리 내 노드의 물리적인 순서와 논리적인 순서가 일치하지 않는다.
  • 연속적인 메모리 공간이 없어도 데이터 저장이 가능
  • 링크를 위한 추가 공간 필요
  • 트리 구조의 근간이 되는 자료구조

 

시간 복잡도

  • 탐색 - 시간 복잡도 O(n)
  • 삽입,삭제 - 시간 복잡도 O(1)

 

n의 크기가 아주 크고, 삽입, 삭제가 빈번하게 일어나는 케이스에 대해 연결 리스트를 고려해보면 좋겠으나

앞으로 연결 리스트를 고려해볼만한 상황이 생길지 잘 모르겠다.

 

단순 연결 리스트

 

  • 노드 당 하나의 링크 필드
  • 마지막 노드의 링크 필드 값은 Null
  • 삽입과 삭제는 단순히 노드의 링크를 변경해주면 된다.

 

원형 연결 리스트

  • 마지막 노드의 링크 필드 값이 첫 번째 노드가 된다.
  • 임의의 하나의 노드에서 어떠한 노드로도 갈 수 있다.
  • 헤드가 마지막 노드를 가리키게 하면 처음이나 마지막 노드 삽입 연산이 유리해진다.

이중 연결 리스트

 

  • 각 노드가 선행/후행 노드 두 개의 링크를 가져 양방향 탐색이 가능하다.
  • 추가적인 공간 필요

 

연결 리스트 swift 구현은 생략

'CS > 자료구조' 카테고리의 다른 글

자료구조 - Heap (2) 정렬  (2) 2024.09.16
자료구조 - Heap (1) 기본  (3) 2024.09.02
자료구조 - 트리  (0) 2024.08.24
자료구조 - 스택, 큐, 덱  (0) 2024.08.17
자료 구조 - 순환 (Recursion)  (0) 2024.08.12