iOS.& Swift Books 数据结构& Algorithms in Swift

3
SWIFT标准库 由凯尔文刘写

SWIFT标准库 是包含Swift语言的核心组件的框架。内部,您将找到各种工具和类型,以帮助构建您的Swift应用程序。在开始构建自己的自定义数据结构之前,了解Swift标准库已经提供的主要数据结构非常重要。

In this chapter, you’ll focus on the three main data structures that the standard library provides right out of the box: 大批 , 字典 , and .

大批

阵列是一个通用的通用容器,用于存储有序的元素集合,它通常在各种迅速的程序中使用。您可以使用使用创建数组 数组文字 ,这是一个逗号分隔的值列表,围绕方括号包围。例如:

let people = ["Brian", "Stanley", "Ringo"]

Swift defines arrays using protocols. Each of these protocols layers more capabilities on the array. For example, an 大批 is a Sequence, which means that you can iterate through it 至少 once. It is also a Collection, which means it can be traversed multiple times, non-destructively, and it can be accessed using a subscript operator. An array is also a RandomAccessCollection, which makes guarantees about efficiency.

这 Swift 大批 is known as a 通用集合,因为它可以使用任何类型。实际上,大多数SWIFT标准库都是用通用代码构建的。

与任何数据结构一样,您应该了解某些值得注意的特征。其中的第一个是概念 命令 .

命令

数组中的元素明确 订购 . Using the above people array as an example, "Brian" comes before "Stanley".

All elements in an array have a corresponding zero-based, integer index. For example, the people array from the above example has three indices, one corresponding to each element. You can retrieve the value of an element in the array by writing the following:

people[0] // "Brian"
people[1] // "Stanley"
people[2] // "Ringo"

命令 is defined by the array data structure and should not be taken for granted. Some data structures, such as 字典 , have a weaker concept of order.

随机访问

随机访问 is a trait that data structures can claim if they can handle element retrieval in a constant amount of time. For example, getting "Ringo" from the people array takes constant time. Again, this performance should not be taken for granted. Other data structures such as linked lists and trees do not have constant time access.

阵列性能

除了一个随机访问收集之外,还有其他表现形式,您是开发人员的感兴趣,特别是数据结构票价如何增加所需的数据,所以需要成长的数据?对于阵列,这在两个因素时变化。

插入位置

第一个因素是您选择在数组内插入新元素的因子。为数组添加元素的最有效场景是在数组结束时将其附加:

people.append("Charles")
print(people) // prints ["Brian", "Stanley", "Ringo", "Charles"]

Inserting "Charles" using the append method will place the string at the end of the array. This is a 常数时间 操作,意味着执行此操作所需的时间保持不管阵列多大程度。但是,可能会有一个需要在特定位置中插入元素的时间,例如在数组的中间。

为了帮助说明为什么如此,请考虑以下类比。你站在剧院。有人新的是加入阵容。什么是将人们添加到阵容的最简单的地方?最后,当然!

如果新人试图将自己插入中间,他必须说服一半的阵容来洗牌腾出空间。

如果他是 可怕 粗鲁,他试着在线的头部插入自己。这是最糟糕的情况,因为阵容中的每个人都需要在前面洗回到这个新人的房间!

这正是阵列的工作原理。从阵列结束时将新元素从数组中插入,将返回返回的元素以向新元素腾出空间:

people.insert("Andy", at: 0)
// ["Andy", "Brian", "Stanley", "Ringo", "Charles"]

要精确, 每一个 元素必须按一个索引向后转换,这需要 n steps. If the number of elements in the array doubles, the time required for this insert operation will also double.

如果在集合前的插入元素是程序的常用操作,则可能需要考虑使用不同的数据结构来保存数据。

确定插入速度的第二个因素是数组的 容量 。在罩下方,Swift阵列以预定量的空间分配给其元素。如果您尝试将新元素添加到已最大容量的数组中,则该数组必须重组为更多元素为更多空间进行重组。这是通过在内存中的新增和更大容器中复制数组的所有当前元素来完成的。但是,这是成本的;必须访问和复制数组的每个元素。

这意味着即使在最后,也可以采取任何插入 n 如果制作副本,则完成步骤。但是,标准库采用了一种最小化此复制所需次数的策略。每次运行存储并需要复制时,它会加倍容量。

字典

字典是包含的另一个通用集合 核心价值 对。例如,这是包含用户名和分数的字典:

var scores: [String: Int] = ["Eric": 9, "Mark": 12, "Wayne": 1]

Dictionaries don’t have any guarantees of order, nor can you insert at a specific index. They also put a requirement on the Key type that it be Hashable. Fortunately almost all of the standard types are already Hashable and in the more recent versions of Swift, adopting the Hashable protocol is now trivial. You can add a new entry to the dictionary with the following syntax:

scores["Andrew"] = 0

这在字典中创建了一个新的键值对:

["Eric": 9, "Mark": 12, "Andrew": 0, "Wayne": 1]

"Andrew" key is inserted somewhere into dictionary. Dictionaries are unordered, so you can’t guarantee where new entries will be put.

It is possible to traverse through the key-values of a dictionary multiple times as the Collection protocol affords. This order, while not defined, will be the same every time it is traversed until the collection is changed (mutated).

缺乏明确的订购劣势来自一些救赎的特征。

与阵列不同,字典不需要担心元素转移。插入字典始终需要恒定的时间。

查找操作也取得恒定的时间,它比在阵列中找到特定元素,这明显快于,该元素需要从数组的开头到插入点的散步。

一组是容纳唯一值的容器。想象一下,它是一个允许您将物品插入其中的包,但拒绝已插入的项目:

var bag: Set<String> = ["Candy", "Juice", "Gummy"]
bag.insert("Candy")
print(bag) // prints ["Candy", "Juice", "Gummy"]

由于设置强制执行唯一性,因此它们借给了各种有趣的应用程序,例如在一个值集中查找重复元素:

let values: [String] = [...]
var bag: Set<String> = []
for value in values {
  if bag.contains(value) {
    // bag already has it, therefore it is a duplicate
  }
  bag.insert(value)
}

您将不会像数组和字典一样使用套件,但它仍然足够常见,以保持工具界中的重要数据结构。虽然有一个警告 - 类似于词典,集合中的值没有订单的概念。当您使用集合汇总数据时,请记住这一点。

关键点

  • 每个数据结构都具有优缺点。知道它们是编写表演软件的关键。
  • Functions such as insert(at:) for 大批 have performance characteristics that can cripple performance when used haphazardly. If you find yourself needing to use insert(at:) frequently with indices near the beginning of the array, you may want to consider a different data structure such as the linked list.
  • 字典 交易远离维护其元素顺序以快速插入和搜索的能力。
  • guarantees uniqueness in a collection of values. is optimized for speed and abandons the ability to retain the order of the elements.

有一个技术问题?想报告一个错误吗? 您可以向官方书籍论坛中的书籍作者提出问题和报告错误 这里 .

有反馈分享在线阅读体验吗? 如果您有关于UI,UX,突出显示或我们在线阅读器的其他功能的反馈,您可以将其发送到设计团队,其中表格如下所示:

© 2021 Razeware LLC