栈
一、概念
- 栈:限定仅在表尾进行插入和删除操作的线性表,允许插入和删除的一端为栈顶,另一端是栈底。
- 性质:栈是一种LIFO(Last In First Out)的线性表,也就是数据元素遵循后进先出的原则。
- 栈的抽象数据类型:
ADT 栈(Stack)
Data
具有线性表一样的性质。
Operation
top:获取栈顶元素
count:栈的长度
isEmpty:栈内元素是否为空
push(data):元素进栈
pop():元素出栈
removeAll():清空栈内元素
EndADT
-
栈的分类(存储结构):
① 栈的顺序存储结构:单栈、共享栈;
② 栈的链式存储结构; -
共享栈:两个顺序栈共享存储空间,栈1的栈顶在下标0处,栈2的栈顶在下标n-1处。
-
栈的顺序结构和链式结构区别:
① 顺序结构需要预先估算存储空间大小,适合数据元素变化不大的情况;
② 链式结构不需要预先估算存储空间,适合数据元素变化较大的情况; -
栈和线性表的不同之处在于,栈只有进栈和出栈操作,并且遵循后进先出的规则,也就是说数据元素顺序进栈,逆序出栈。栈可以实现回退操作,递归和四则运算等。
二、栈的操作
- s.push(item) // 在栈顶压入新元素
- s.pop() // 删除栈顶元素但不返回其值
- s.empty() // 如果栈为空返回true,否则返回false
- s.size() // 返回栈中元素的个数
- s.top() // 返回栈顶的元素,但不删除该元素
三、栈的链式结构实现
public struct Stack<T> {
private var stackData: [T] = []
public var count: Int {
return stackData.count
}
public var top: T? {
if isEmpty {
return nil
} else {
return stackData.last
}
}
public var isEmpty: Bool {
return stackData.isEmpty
}
public mutating func push(data: T) {
stackData.append(data)
}
public mutating func pop() -> T? {
if isEmpty {
return nil
} else {
return stackData.removeLast()
}
}
public mutating func removeAll() {
stackData.removeAll()
}
public func printAllData() {
for item in stackData {
print(item)
}
}
}
队列
一、概念
- 只允许在一段进行插入操作,而在另一端进行删除操作的线性表;
- 性质:先进先出;
- 队列的抽象数据类型:
ADT 队列(Queue)
Data
具有线性表一样的性质。
Operation
front:队列第一个数据
count:队列的长度
isEmpty():队列是否为空
enQueue(data):数据进队列
deQueue():数据出队列
removeAll():清空队列内的所有数据
EndADT
- 顺序队列:就是使用数组来模拟队列,但是数组的插入和删除需要移动数据,比较繁琐。
- 循环顺序队列:在顺序队列的基础上改造,使队列的队头和队尾可以在数组中循环变化,在数据插入和删除就不需要频繁移动数据了。但是顺序队列,都需要提前申请存储空间,还有溢出的可能。
- 链式队列:为了解决顺序队列的不足,引用链式队列。不需要提前申请空间,只不过会引入频繁申请和释放的操作。
- 队列有什么作用?在开发过程中,接触最多的应该是全局并发队列。为什么要用队列实现呢?在线程的优先级一样的情况下,不应该先申请系统资源的先被满足吗?这和在银行排队取钱是一个道理。
二、队列的操作
- push(item)
- q.pop()
- q.front()
- q.back()
- q.size()
- q.empty()
三、队列的链式结构实现
public struct Queue<T> {
private var queueData: [T] = []
public var front: T? {
return queueData.first
}
public var isEmpty: Bool {
return queueData.isEmpty
}
public var count: Int {
return queueData.count
}
public mutating func enQueue(_ data: T) {
queueData.append(data)
}
public mutating func deQueue() -> T? {
if isEmpty {
return nil
} else {
return queueData.removeFirst()
}
}
public mutating func removeAll() {
queueData.removeAll()
}
public func printAllData() {
for value in queueData {
print(value)
}
}
}