IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Swift实现排序算法 -> 正文阅读

[数据结构与算法]Swift实现排序算法

目录

快速排序

归并排序

堆排序

基础知识:

堆的性质:

实现步骤

1、维护堆节点方法

2、建堆

3、排序堆

4、整合


快速排序

时间复杂度O( Nlog2N))

1、选择基准点P,大的放在右边,小的放在左边。

2、递归调用左边,右边


func quickSorted (_ nums: inout [Int], _ left: Int, _ right: Int) {
   if left >= right {
        return ;
    }
    var l = left
    var r = right
    let pivot = nums[l]
    while l < r {
        while nums[r] >= pivot && l < r {//以l为基准点就要先从r处先遍历
            r -= 1
        }
        nums[l] = nums[r]//l的位置付给了pivot,所有可以把r的值放在l了
        while nums[l] <= pivot && l < r {
             l += 1
        }
        nums[r] = nums[l]//同理可以把l的位置放在r处,因为r的数字已经放在上一个了处
    }

    // 此时 l 等于中间位置 (可能等于 r)
    nums[l] = pivot //pivot的位置已经a安排好了
    quickSorted(&nums, left, l - 1)
    quickSorted(&nums, l + 1, right)
    
}

归并排序

时间复杂度O( N logN)

先分治,再合并

 func mergeSorted(_ nums: inout [Int]) { //先分治,再合并
        let length = nums.count - 1
        var temp = Array<Int>(repeating: 0, count: nums.count) //临时数组
        mergePass(&nums, &temp, 0, length)
    }

    //分治
    func mergePass(_ nums: inout [Int], _ temp: inout [Int], _ left: Int , _ right: Int) {
        if left < right  { //元素数据大于 1
            let mid = (right + left) / 2
            print ("left == :\(left), mid = \(mid), right = \(right) ")

            //递归划分左半区
            mergePass(&nums, &temp, left, mid)
            //递归划分右半区
            mergePass(&nums, &temp, mid + 1, right)
            
            merge(&nums, &temp, left, mid, right)
        }
    }

    //合并已经排序的部分
    func merge(_ nums: inout [Int],  _ temp: inout [Int], _ left:Int, _ mid: Int, _ right: Int ) {
        var lP = left //左半区为合并的元素
        var rP = mid + 1  //右半区为合并的第一个元素
        var pos = left  //临时数组的元素下标

        //合并
        while lP <= mid && rP <= right  {
            if nums[lP] < nums[rP] {
                temp[pos] = nums[lP]
                pos += 1
                lP += 1
            } else {
               temp[pos] = nums[rP]
                pos += 1
                rP += 1
            }
        }
        // 合并剩余部分
        while lP <= mid {
            temp[pos] = nums[lP]
            pos += 1
            lP += 1
        }
        while rP <= right {
           temp[pos] = nums[rP]
           pos += 1
           rP += 1
        }
       
        //将排序好的序列复制回原数组
        var left = left
        while left <= right {
            nums[left] = temp[left]
            left += 1
        }

    }


堆排序

时间复杂度O( N logN)不稳定。

基础知识:

堆:一种特殊的树。 大顶堆: 根节点比 左右子节点大。 小顶堆: 根节点比 左右子节点小

堆的性质:

??????????????1、下标为i 的节点的父节点的下标为:(i-1)/2

? ? ? ? ? ? ? 2、下标为i 的父亲节点,左孩子下标为 i*2 + 1

? ? ? ? ? ? ? 3、下标为i 的父亲节点,左孩子下标为 i*2 + 2

实现步骤

? ? ? ? ?1、实现堆节点调整 O(logN)

? ? ? ? ? 2、 建堆? 时间复杂度:O(n)

? ? ? ? ? 3、 移除第一个元素。然后调整堆。

? ? ? ? ? 4、 递归3 完成

1、维护堆节点方法

????????思路 :1、找到维护点的左右子节点。把最大的放在根节点。

? ? ? ? ? ? ? ? ? ? ??2、 如果根与子节点有交互,则需要递归交换,子节点的所有子节点

 //维护堆节点 :nums:堆数组(需要维护), l:堆数组的长度, n:维护的节点在堆数组中的下标. O(logN)
    func heapVerify(_ nums: inout [Int], _ l: Int, _ n: Int) { ///
        var largest = n
        let lSon = 2*n + 1 //堆的子节点在数组中的位置和父亲节点在数组中位置的关系
        let rSon = 2*n + 2
        
        //两次比较找出最大的 三者中最大的数字位置,放在Largest
        if lSon < l && nums[largest] < nums[lSon]  {
            largest = lSon
        }
        if rSon < l && nums[largest] < nums [rSon] {
            largest = rSon
        }
        
        if largest != n {
            nums.swapAt(largest, n)
            heapVerify(&nums, l, largest) //因为交换后的s位置已经放在了 largest里了
        }
    }

2、建堆

    func buildHeap(_ nums: inout [Int]) {
        let n = nums.count 
        var i = n/2 - 1 //从堆的最后一个有子节点的元素开始。即数组最后一个元素n-1 => 的父节点为:((n-1)-1)/2
        while i >= 0 {
            heapVerify(&nums, n, i)
            i -= 1
        }
        print("建堆为:\(nums)")
    }

3、排序堆

    //排序堆
    func sortHeap(_ nums: inout [Int] ) {
        var i = nums.count - 1
        while i > 0 {
            nums.swapAt(i, 0) //大顶堆最大元素在堆顶。把最大元素移到堆尾部
            heapVerify(&nums, i, 0)  //维护堆除去堆底(最大)元素后的,堆顶元素的性质
            i -= 1
        }
    }
    

4、整合

其实2、3 可以放在一起。

 func heapSorted(_ nums: inout [Int]) {
        buildHeap(&nums)
        sortHeap(&nums)
    }

总结

? ? ? ? 面试中考到的频率还是比较高的,也是easy的算法题。以上三种排序必须毫无卡顿,毫无差错的撸出来才行。每天没事的时候写一下练个手,可以看最快多长时间写完成。与君共勉

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-21 21:17:10  更:2022-03-21 21:19:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/9 1:44:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码