单链表是我们日常开发中经常会用到的一种数据结构,它是用节点来存储信息和指向下一个节点的指针。下面我们来看一下如何用 Swift 实现一个单链表的数据结构。
定义节点类
首先,定义一个链表节点类 ListNode,它包含节点的值以及指向下一个节点的引用。
class ListNode<T> {
var value: T
var next: ListNode?
init(value: T) {
self.value = value
self.next = nil
}
}
在这个 ListNode 类中:
- value 存储节点的值。
- next 是一个指向下一个节点的可选类型,默认情况下为 nil。
定义链表类
然后,定义一个链表类 LinkedList,用于管理链表的操作,如添加、删除和遍历节点。
class LinkedList<T> {
private var head: ListNode<T>?
// 检查链表是否为空
var isEmpty: Bool {
return head == nil
}
// 返回链表的第一个节点
var first: ListNode<T>? {
return head
}
// 添加元素到链表的尾部
func append(value: T) {
let newNode = ListNode(value: value)
if let lastNode = getLastNode() {
lastNode.next = newNode
} else {
head = newNode
}
}
// 获取链表的最后一个节点
private func getLastNode() -> ListNode<T>? {
var node = head
while node?.next != nil {
node = node?.next
}
return node
}
// 删除指定值的节点
func remove(value: T) {
var previousNode: ListNode<T>?
var currentNode = head
while currentNode != nil {
if currentNode?.value == value {
if previousNode == nil {
// 如果要删除的是头节点
head = currentNode?.next
} else {
// 让前一个节点指向当前节点的下一个节点
previousNode?.next = currentNode?.next
}
break
}
previousNode = currentNode
currentNode = currentNode?.next
}
}
// 打印链表中的所有值
func printList() {
var node = head
while node != nil {
print(node!.value, terminator: " -> ")
node = node?.next
}
print("nil")
}
}
在这个 LinkedList 类中,我们定义了一些常用的链表操作接口:
- isEmpty:检查链表是否为空。
- first:获取链表的第一个节点。
- append(value:):在链表的尾部添加一个新节点。
- getLastNode():获取链表的最后一个节点,供内部使用。
- remove(value:):删除第一个匹配给定值的节点。
- printList():遍历链表并打印每个节点的值。
使用链表
下面是一个示例,展示如何创建链表、添加节点、删除节点并打印链表。
let list = LinkedList<Int>()
list.append(value: 1)
list.append(value: 2)
list.append(value: 3)
list.printList() // 输出: 1 -> 2 -> 3 -> nil
list.remove(value: 2)
list.printList() // 输出: 1 -> 3 -> nil