返回

Swift算法俱乐部-堆排序

IOS

堆排序是一种有效的排序算法,利用堆的数据结构来执行排序。堆是一种部分排序的二叉树,存储在一个数组中。堆有以下特性:

  • 每个节点的值都大于或等于其子节点的值(最大堆)或小于或等于其子节点的值(最小堆)。
  • 数组中的第一个元素是堆的根节点。

堆排序算法主要分为以下步骤:

  1. 构建堆: 将未排序的数组转换为堆。
  2. 排序: 重复以下步骤,直到堆为空:
    • 交换堆顶元素和堆的最后一个元素。
    • 将最后一个元素从堆中删除。
    • 调整堆以满足堆的性质。

堆排序的时间复杂度 为O(n log n),其中n是数组的大小。

代码示例:

func heapSort(arr: inout [Int]) {
    // 构建最大堆
    buildMaxHeap(&arr)
    
    // 排序
    for i in stride(from: arr.count - 1, through: 1, by: -1) {
        // 交换堆顶元素和最后一个元素
        arr[i] = arr[0]
        arr[0] = arr[i]
        
        // 调整堆,忽略最后一个元素
        heapify(&arr, index: 0, size: i)
    }
}

func buildMaxHeap(_ arr: inout [Int]) {
    // 从最后一个非叶子节点开始
    for i in stride(from: arr.count / 2 - 1, through: 0, by: -1) {
        heapify(&arr, index: i, size: arr.count)
    }
}

func heapify(_ arr: inout [Int], index: Int, size: Int) {
    // 左子节点的索引
    let left = 2 * index + 1
    
    // 右子节点的索引
    let right = 2 * index + 2
    
    // 最大值节点的索引
    var largest = index
    
    if left < size && arr[left] > arr[index] {
        largest = left
    }
    
    if right < size && arr[right] > arr[largest] {
        largest = right
    }
    
    // 如果最大值节点不是根节点
    if largest != index {
        // 交换最大值节点和根节点
        arr[index] = arr[largest]
        arr[largest] = arr[index]
        
        // 递归调整最大值节点的子树
        heapify(&arr, index: largest, size: size)
    }
}

堆排序算法在实际应用中有着广泛的用途,如数据处理、分析和机器学习。