Skip to content

Files

Latest commit

Jul 11, 2019
358411d · Jul 11, 2019

History

History

Ordered Set

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
Jul 11, 2019
Jul 11, 2019
Nov 8, 2018

有序集(Ordered Set)

我们来看看苹果如何实现有序集

Here is the example about how it works 以下是有关其工作原理的示例:

let s = AppleOrderedSet<Int>()

s.add(1)
s.add(2)
s.add(-1)
s.add(0)
s.insert(4, at: 3)

print(s.all()) // [1, 2, -1, 4, 0]

s.set(-1, at: 0) // 已经有-1在index: 2,因此这个操作不做任何事情

print(s.all()) // [1, 2, -1, 4, 0]

s.remove(-1)

print(s.all()) // [1, 2, 4, 0]

print(s.object(at: 1)) // 2

print(s.object(at: 2)) // 4

显着的区别是数组没有排序。 插入时,数组中的元素是相同的。 将数组映像为不重复且具有 O(logn)O(1) 搜索时间。

这里的想法是使用数据结构来提供 O(1)O(logn) 时间复杂度,因此很容易考虑哈希表。

var indexOfKey: [T: Int]
var objects: [T]

indexOfKey is used to track the index of the element. objects is array holding elements. indexOfKey 用于跟踪元素的索引。 objects是数组保持元素。

我们将在这里详细介绍一些关键功能。

添加

更新indexOfKey并在objects的末尾插入元素

// O(1)
public func add(_ object: T) {
	guard indexOfKey[object] == nil else {
		return
	}

	objects.append(object)
	indexOfKey[object] = objects.count - 1
}

插入

在数组的随机位置插入将花费 O(n) 时间。

// O(n)
public func insert(_ object: T, at index: Int) {
	assert(index < objects.count, "Index should be smaller than object count")
	assert(index >= 0, "Index should be bigger than 0")

	guard indexOfKey[object] == nil else {
		return
	}

	objects.insert(object, at: index)
	indexOfKey[object] = index
	for i in index+1..<objects.count {
		indexOfKey[objects[i]] = i
	}
}

设置

如果object已存在于OrderedSet中,则什么也不做。 否则,我们需要更新indexOfkeyobjects

// O(1)
public func set(_ object: T, at index: Int) {
	assert(index < objects.count, "Index should be smaller than object count")
	assert(index >= 0, "Index should be bigger than 0")

	guard indexOfKey[object] == nil else {
		return
	}

	indexOfKey.removeValue(forKey: objects[index])
	indexOfKey[object] = index
	objects[index] = object
}

删除

删除数组中的元素将花费 O(n)。 同时,我们需要在删除元素后更新所有元素的索引。

// O(n)
public func remove(_ object: T) {
	guard let index = indexOfKey[object] else {
		return 
	}

	indexOfKey.removeValue(forKey: object)
	objects.remove(at: index)
	for i in index..<objects.count {
		indexOfKey[objects[i]] = i
	}
}

作者:Kai Chen
翻译:Andy Ron
校对:Andy Ron