-
Notifications
You must be signed in to change notification settings - Fork 48
/
SinglyLinkedList.swift
181 lines (158 loc) · 4.43 KB
/
SinglyLinkedList.swift
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
//
// SinglyLinkedList.swift
// LinkedList
//
// Created by ggl on 2019/3/28.
// Copyright © 2019年 ggl. All rights reserved.
// 单链表
import Foundation
class Node: Equatable {
var data: Int = 0
var next: Node?
init(data: Int, next: Node?) {
self.data = data
self.next = next
}
static func == (lhs: Node, rhs: Node) -> Bool {
if lhs.data == rhs.data {
return true
}
return false
}
}
class SinglyLinkedList {
var head: Node?
/// 添加结点
///
/// - Parameter node: 新节点
func addNode(_ data: Int) {
let node = Node(data: data, next: nil)
guard let tailNode = tailNode() else {
head = node
return
}
tailNode.next = node
}
@discardableResult
func deleteNode(_ data: Int) -> Bool {
// 链表是单向的,所以需要始终有一个前向指针
var curNode = head
var preNode = head
// 链表是否为空
if curNode == nil {
return false
}
// 链表头结点是否等于指定的结点
if curNode!.data == data {
head = curNode?.next
return true
}
while curNode!.next != nil {
preNode = curNode
curNode = curNode?.next
// 比对结点的数据是否相同
if curNode!.data == data {
preNode?.next = curNode?.next
return true
}
}
return false
}
/// 获取链表的最后一个结点
///
/// - Returns: 尾结点
func tailNode() -> Node? {
guard var tailNode = head else {
return nil
}
while tailNode.next != nil {
tailNode = tailNode.next!
}
return tailNode
}
/// 链表反转
func reverse() {
if head == nil || head?.next == nil {
return
}
// pre指针指向前一个结点、cur指针指向当前需要反转的结点
var pre = head
var cur = head?.next
head?.next = nil
while cur != nil {
let next = cur?.next
cur?.next = pre
// 进行下次循环
pre = cur
cur = next
}
head = pre
}
/// 递归反转
@discardableResult
func reverse(_ node: Node?) -> Node? {
if node == nil || node?.next == nil {
return node
}
// 注意,始终返回尾结点
let newHead = reverse(node?.next)
// 防止形成环,例如1 -> 2 -> 3 <- 4 <- 5,当前 node 为 2,需要反转链表
node?.next?.next = node
node?.next = nil
return newHead
}
/// 求链表的中间结点(快慢指针)
///
/// - Returns: 链表的中间结点
func middleNode() -> Node? {
if head == nil || head?.next == nil {
return nil
}
var slow = head
var fast = head
while fast?.next != nil && fast?.next?.next != nil {
slow = slow?.next
fast = fast?.next?.next
}
return slow
}
/// 求链表倒数第K个结点(K大于等于1)(使用快慢指针)
///
/// - Parameter lastK: 倒数第几个位置
/// - Returns: 倒数第K个结点
func lastKNode(lastK: Int) -> Node? {
if head == nil || lastK < 1 {
return nil
}
// 使用快、慢指针来解决
var slow = head
var fast = head
// 快指针先走K步
for _ in 0..<lastK-1 {
fast = fast?.next
}
// 如果快指针走出去了,则表示K值过大,返回nil
if fast == nil {
return nil
}
// 快慢指针一起走,快指针走到头后慢指针位置则为倒数第K个结点
while fast?.next != nil {
slow = slow?.next
fast = fast?.next
}
return slow
}
/// 打印链表
func print() {
var curNode = head
while curNode != nil {
if curNode?.next == nil {
Swift.print(curNode!.data)
break
} else {
Swift.print(curNode!.data, terminator: " -> ")
curNode = curNode?.next
}
}
}
}