Post

DataStructure - 원형 연결 리스트(Circular Linked List)란?

DataStructure - 원형 연결 리스트(Circular Linked List)란?

본 글은 『얄코의 가장 쉬운 자료구조와 알고리즘』을 참고하여 개인 학습 목적으로 이해한 내용을 정리한 것입니다.

원형 연결 리스트란 마지막 요소(tail)가 첫 번째 요소(head)를 가리켜서 원형같은 구조를 이루는 리스트임.

마지막 요소가 첫 번째 요소와 연결되어 있기 때문에 끊임없이 순회 가능함.

처리 성능

  • 요소 삽입: head, tail에 삽입할 경우 O(1), 특정 위치에 삽입할 경우 순회가 필요하기 때문에 O(n)
  • 요소 삭제: head, tail 요소를 삭제할 경우 O(1), 특정 위치에 요소를 삭제할 경우 순회가 필요하기 때문에 O(n)
  • 요소 탐색: 요소의 참조를 통해 순회하기 때문에 O(n)

구현 예시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
class Node{
    var data: Int
    var next: Node?
    var prev: Node?
    
    init(data: Int, next: Node? = nil, prev: Node? = nil) {
        self.data = data
        self.next = next
        self.prev = prev
    }
}

class LinkedList{
    var head: Node?
    var current: Node?
    
    public func insertAtHead(data: Int){
        var newNode = Node(data: data)
        if head == nil{
            head = newNode
            head?.next = head
            head?.prev = head
            current = head
        }else{
            var tail = head?.prev
            newNode.next = head
            newNode.prev = tail
            head?.prev = newNode
            tail?.next = newNode
            head = newNode
        }
    }
    
    public func insertAtTail(data: Int){
        var newNode = Node(data: data)
        if head == nil{
            head = newNode
            head?.next = newNode
            head?.prev = newNode
            current = newNode
        }else{
            var tail = head?.prev
            newNode.next = head
            newNode.prev = tail
            head?.prev = newNode
            tail?.next = newNode
        }
    }
    
    public func deleteAtHead(){
        if head == nil{ return }
        
        if head?.next === head{
            head = nil
            current = nil
            return
        }
        
        var tail = head?.prev
        if current === head { current = head?.next }
        head = head?.next
        head?.prev = tail
        tail?.next = head
    }
    
    public func deleteAtTail(){
        if head == nil { return }
        
        if head?.next === head{
            head = nil
            current = nil
            return
        }
        
        var tail = head?.prev
        if current === tail { current = head }
        var newTail = tail?.prev
        newTail?.next = head
        head?.prev = newTail
    }
    
    public func printList(){
        if head == nil { return }
        
        var temp = head
        repeat{
            print("\(temp!.data) -> ", terminator: "")
            temp = temp?.next
        }while temp !== head
        
        print("nil")
    }
    
    public func moveNext(){
        if current == nil { return }
        current = current?.next
    }
    
    public func movePrev(){
        if current == nil { return }
        current = current?.prev
    }
    
    public func printCurrent(){
        guard let current = current else {
            print("current : nil")
            return
        }
        
        print("current : \(current.data)")
    }
}

var list = LinkedList()
list.insertAtHead(data: 64)
list.insertAtHead(data: 33)
list.insertAtHead(data: 91)
list.insertAtHead(data: 99)
list.insertAtHead(data: 15)
list.insertAtHead(data: 53)

list.printList()

list.deleteAtTail()

list.printList()

list.current = list.head;
list.printCurrent();

for i in 0..<3{
    list.moveNext();
}

list.printCurrent();
This post is licensed under CC BY 4.0 by the author.