Swift队列数据结构实现

时间:2020-02-23 14:44:03  来源:igfitidea点击:

在本教程中,我们将使用Swift讨论和实现数据结构队列。
我们将分别使用Array和LinkedList创建Swift队列。

Swift队列数据结构

队列是一种数据结构,您可以其中从一端插入新数据,而从另一端删除数据。
这意味着它的工作方式类似于FIFO –先进先出。

入队操作用于在开头插入元素。

出队操作用于从末端删除元素。

在下一节中,我们将使用数组创建队列结构。

在XCode中打开您的Swift Playground,让我们开始编码。

队列–入队,出队

以下是我们的队列的代码:

struct Queue{
  
  var items:[String] = []
  
  mutating func enqueue(element: String)
  {
      items.append(element)
  }
  
  mutating func dequeue() -> String?
  {
      
      if items.isEmpty {
          return nil
      }
      else{
          let tempElement = items.first
          items.remove(at: 0)
          return tempElement
      }
  }
  
}

队列是一个字符串数组。

enqueue方法将一个字符串附加到最后一个字符串。

出队方法删除第一个字符串。

在出队函数中,我们返回一个可选类型,因为数组可以为空,在这种情况下,将以软件包在可选中的形式返回" nil"。

以下是上述队列中操作的输出。

我们可以创建一个通用Swift Queue以便将其用于所有类型。

下图通过使用通用类型T代替String重构了上面的代码。

在下一节中,我们将使用LinkedList代替Array创建一个Swift队列。

使用LinkedList的Swift队列

首先创建一个包含LinkedList数据结构的类:

public class LinkedList<T> { 
  var data: T
  var next: LinkedList?
  public init(data: T){
      self.data = data
  }
}

该类由数据和对LinkedList的下一个Node的引用组成。

由于LinkedList的每个元素通常称为Node,因此我们可以使用typealias将上述类类型重命名为Node。

public class Queue<T> {
  typealias LLNode = LinkedList<T>
  var head: LLNode!
  public var isEmpty: Bool { return head == nil }
  var first: LLNode? { return head }
  var last: LLNode? {
      if var node = self.head {
          while case let next? = node.next {
              node = next
          }
          return node
      } else {
          return nil
      }
  }

  func enqueue(key: T) {
      let nextItem = LLNode(data: key)
      if let lastNode = last {
          lastNode.next = nextItem
      } else {
          head = nextItem
      }
  }
  func dequeue() -> T? {
      if self.head?.data == nil { return nil  }
      if let nextItem = self.head?.next {
          head = nextItem
      } else {
          head = nil
      }
      return head?.data
  }
}

" first"节点指向与头部相同的参考。
它表示队列中存在的LinkedList的第一个节点。

在入队功能中,我们通过将头设置为下一个Node直到下一个为nil,直到LinkedList的末尾。
这是在if let中完成的。

在出队中,我们通过将head设置为下一个节点来删除第一个Node的引用。

" while case let"与Swift中的" if let"类似,不同之处在于它在循环中使用。

双端队列

双端队列使您可以在队列的两端添加和删除元素。
这意味着除了入队,出队功能之外,您还需要添加两个附加的equeueFront和dequeueBack函数。

以下代码显示了使用数组的双头队列结构。

public struct Deque<T> {
  private var items = [T]()
  
  mutating func enqueue(element: T) {
      items.append(element)
  }
  
  mutating func enqueueFront(element: T) {
      items.insert(element, at: 0)
  }
  
  mutating func dequeue() -> T?{
      if items.isEmpty {
          return nil
      } else {
          return items.removeFirst()
      }
  }
  
  mutating func dequeueBack() -> T? {
      if items.isEmpty {
          return nil
      } else {
          return items.removeLast()
      }
  }
}

在上图中,enqueueFront将新元素添加到当前元素之前。
deuqueBack()从队列中删除最后一个元素。