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

26
O(n²)分拣算法 由凯尔文刘写

O(n)时间复杂性不是很大的性能,但是在某些情况下,此类别中的排序算法很容易理解和有用。这些算法是空间效率;他们只需要常数 O(1)额外的存储空间。对于小型数据集,这些排序非常有利地对比更复杂的各种类型。

在本章中,您将研究以下排序算法:

  • 泡沫排序
  • 选择排序
  • 插入排序

所有这些都是 比较为基础 排序方法。它们依赖于比较方法,例如较少的操作员,以订购元素。调用此比较的次数是您如何测量排序技术的一般性能。

泡沫排序

最简单的排序之一是泡沫排序,它重复比较相邻值并在需要时互换,以执行排序。因此,该组中的较大值将“泡起来”到集合的末尾。

例子

考虑下列卡片:

执行

为本章开辟了Swift游乐场以上。在里面 来源 游乐场目录,创建一个名为的新文件 Bubblesort.swift.。在文件中写下以下内容:

public func bubbleSort<Element>(_ array: inout [Element])
    where Element: Comparable {
  // 1
  guard array.count >= 2 else {
    return
  }
  // 2
  for end in (1..<array.count).reversed() {
    var swapped = false
    // 3
    for current in 0..<end {
      if array[current] > array[current + 1] {
        array.swapAt(current, current + 1)
        swapped = true
      }
    }
    // 4
    if !swapped {
      return
    }
  }
}
example(of: "bubble sort") {
  var array = [9, 4, 10, 3]
  print("Original: \(array)")
  bubbleSort(&array)
  print("泡沫排序ed: \(array)")
}
---Example of bubble sort---
Original: [9, 4, 10, 3]
Bubble sorted: [3, 4, 9, 10]

选择排序

选择排序 follows the basic idea of bubble sort, but improves upon this algorithm by reducing the number of swapAt operations. Selection sort will only swap at the end of each pass. You’ll see how that works in the following example and implementation.

例子

假设您有以下手的手:

执行

在里面 来源 游乐场目录,创建一个名为的新文件 selectionsor.swift.。在文件中写下以下内容:

public func selectionSort<Element>(_ array: inout [Element])
    where Element: Comparable {
  guard array.count >= 2 else {
    return
  }
  // 1
  for current in 0..<(array.count - 1) {
    var lowest = current
    // 2
    for other in (current + 1)..<array.count {
      if array[lowest] > array[other] {
        lowest = other
      }
    }
    // 3
    if lowest != current {
      array.swapAt(lowest, current)
    }
  }
}
example(of: "selection sort") {
  var array = [9, 4, 10, 3]
  print("Original: \(array)")
  selectionSort(&array)
  print("选择排序ed: \(array)")
}
---Example of selection sort---
Original: [9, 4, 10, 3]
Selection sorted: [3, 4, 9, 10]

插入排序

插入排序是一种更有用的算法。像泡泡排序和选择排序一样,插入排序有一个 平均 时间复杂性 O(n)但插入排序的性能可以变化。数据已经排序越多,它需要做的工作就越少。插入排序有一个 最好的 时间复杂性 O(n)如果数据已被排序。 SWIFT标准库排序算法使用与用于小的插入排序的分类方法混合(<20个元素)未分区。

例子

插入排序的想法类似于您将如何排序卡的方式。考虑下面的手:

执行

在里面 来源 游乐场目录,创建一个名为的新文件 插入。在文件中写下以下内容:

public func insertionSort<Element>(_ array: inout [Element])
    where Element: Comparable {
  guard array.count >= 2 else {
    return
  }
  // 1
  for current in 1..<array.count {
    // 2
    for shifting in (1...current).reversed() {
      // 3
      if array[shifting] < array[shifting - 1] {
        array.swapAt(shifting, shifting - 1)
      } else {
        break
      }
    }
  }
}
example(of: "insertion sort") {
  var array = [9, 4, 10, 3]
  print("Original: \(array)")
  insertionSort(&array)
  print("插入排序ed: \(array)")
}
---Example of insertion sort---
Original: [9, 4, 10, 3]
Insertion sorted: [3, 4, 9, 10]

概括

In this section, you’ll generalize these sorting algorithms for collection types other than Array. Exactly 哪一个 但是,收集类型取决于算法:

public func bubbleSort<T>(_ collection: inout T)
    where T: MutableCollection, T.Element: Comparable {
  guard collection.count >= 2 else {
      return
  }
  for end in collection.indices.reversed() {
    var swapped = false
    var current = collection.startIndex
    while current < end {
      let next = collection.index(after: current)
      if collection[current] > collection[next] {
        collection.swapAt(current, next)
        swapped = true
      }
      current = next
    }
    if !swapped {
      return
    }
  }
}
public func selectionSort<T>(_ collection: inout T)
    where T: MutableCollection, T.Element: Comparable {
  guard collection.count >= 2 else {
    return
  }
  for current in collection.indices {
    var lowest = current
    var other = collection.index(after: current)
    while other < collection.endIndex {
      if collection[lowest] > collection[other] {
        lowest = other
      }
      other = collection.index(after: other)
    }
    if lowest != current {
      collection.swapAt(lowest, current)
    }
  }
}
public func insertionSort<T>(_ collection: inout T)
    where T: BidirectionalCollection & MutableCollection, 
          T.Element: Comparable {
  guard collection.count >= 2 else {
    return
  }
  for current in collection.indices {
    var shifting = current
    while shifting > collection.startIndex {
      let previous = collection.index(before: shifting)
      if collection[shifting] < collection[previous] {
        collection.swapAt(shifting, previous)
      } else {
        break
      }
      shifting = previous
    }
  }
}

关键点

  • n algorithms often have a bad reputation, but some of these algorithms usually have some redeeming points. insertionSort can sort in O(n)如果集合已经排序顺序并且逐渐缩放到 O(n)。
  • insertionSort 是在情况下,您的数据大多以排序顺序所知的情况下最佳排序之一。

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

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

© 2021 Razeware LLC

您可以免费读取,本章的部分显示为 混淆了 文本。解锁这本书,以及我们整个书籍和视频目录,带有Raywenderlich.com的专业订阅。

现在解锁

要突出或记笔记,您需要在订阅中拥有这本书或自行购买。