zoukankan      html  css  js  c++  java
  • [Swift]八大排序算法(五):插入排序

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    ➤微信公众号:山青咏芝(shanqingyongzhi)
    ➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/ 
    ➤GitHub地址:https://github.com/strengthen/LeetCode
    ➤原文地址:https://www.cnblogs.com/strengthen/p/9866551.html 
    ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
    ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

    排序分为内部排序和外部排序。

    内部排序:是指待排序列完全存放在内存中所进行的排序过程,适合不太大的元素序列。

    外部排序:指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存,需要在内存和外部存储器之间进行多次数据交换,以达到排序整个文件的目的。

    当N小于20的时候,插入排序具有最好的性能。

    当N大于20时,快速排序具有最好的性能,尽管归并排序(merge sort)和堆排序(heap sort)复杂度都为nlog2(n)。


    插入排序

    插入算法把要排序的数组分成两部分:

    第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),

    第二部分就只包含这一个元素(即待插入元素)。在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中。

    插入排序的基本思想是:

    每步将一个待排序的记录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。

    (关键码是数据元素中某个数据项的值,用它可以标示一个数据元素。通常会用记录来标示数据元素,一个记录可以有若干数据项组成。)


     ViewController.swift文件:运行时间(24.0695s)

      1 import UIKit
      2 
      3 class ViewController: UIViewController {
      4     //属性1:用来存储需要排序的数组
      5     var result : Array<Int> = Array<Int>()
      6     //属性2:统计排序花费的时间
      7     var date : Date!
      8     
      9     override func viewDidLoad() {
     10         super.viewDidLoad()
     11         // Do any additional setup after loading the view, typically from a nib.
     12         //初始化一个整形数组
     13         var array : Array<Int> = Array<Int>()
     14         //将1至100的100个整数,存入到该数组中
     15         for i in 1...100
     16         {
     17             array.append(i)
     18         }
     19         //添加一个循环语句,
     20         //用来生成一个由100个随机整数组成的数组
     21         for _ in 1...100
     22         {
     23             //首先根据数组的长度,
     24             //获得一个1至100的随机整数
     25             let temp = Int(arc4random() % UInt32(array.count))+1
     26             //根据随机值从数组中获得指定位置的整数,
     27             //并存储在用来排序的数组中
     28             let num = array[temp-1]
     29             result.append(num)
     30             //从原数组中移该随机数,以避免获得重复的数字
     31             array.remove(at: temp-1)
     32         }
     33         //添加一个循环语句,
     34         //用来生成100个自定义视图对象
     35         for i in 1...100
     36         {
     37             //初始化自定义视图对象
     38             let num = result[i-1]
     39             //并设置它的显示区域。
     40             //其中视图的高度,是当前数组中的数字的两倍大小
     41             let view = SortView(frame: CGRect(x: 10+i*3, y: 200,  2, height: num * 2))
     42             view.backgroundColor = .black
     43             //设置视图的标识值
     44             view.tag = i
     45             //并将视图添加到当前视图控制器的根视图
     46             self.view.addSubview(view)
     47         }
     48         //然后添加一个按钮
     49         //当用户点击该按钮时对数组进行排序
     50         let bt = UIButton(frame: CGRect(x: 10, y: 340,  300, height: 40))
     51         //设置背景按钮的背景颜色为橙色
     52         bt.backgroundColor = .orange
     53         //设置按钮在正常状态下的标题文字
     54         bt.setTitle("Sort", for: .normal)
     55         //给按钮对象绑定点击事件,
     56         bt.addTarget(self, action: #selector(reOrderView), for: .touchUpInside)
     57         //将按钮添加到当前视图控制器的根视图
     58         self.view.addSubview(bt)
     59     }
     60 
     61     //添加一个方法,用来响应按钮的点击事件
     62     @objc func reOrderView()
     63     {
     64         //获得当前的日期和时间
     65         date = Date()
     66         //在一个全局队列中,以异步的方式对数组进行排序
     67         //并实时调整和数组中的数值相对应的视图的位置
     68         DispatchQueue.global().async
     69         {
     70                 //调用实例方法,用来进行可视化的插入排序。
     71                 //该方法在下方的代码中实现
     72                 self.sort(items: self.result)
     73                 //获得排序后的系统时间,
     74                 //并在控制台输出两个时间的差值,
     75                 //从而获得排序所花费的大致时间。
     76                 //考虑线程休眠的影响,此数据仅做参考
     77                 let endDate = Date()
     78                 print(endDate.timeIntervalSince(self.date))
     79         }        
     80     }
     81 
     82     //添加一个方法,用来实现具体的可视化的插入排序的功能
     83     func sort(items: Array<Int>)
     84     {
     85         //获得进行排序的数组
     86         var list = items
     87         //首先将数组中的第一个元素,看成是已经完成排序的数组。
     88         //然后从第二个元素开始,通过循环语句,
     89         //将未排序的元素,
     90         //由后向前完成排序的数组进行比较和插入
     91         for i in 1..<list.count
     92         {
     93             var j = i
     94             while j > 0
     95             {
     96                 //将待排序的元素,
     97                 //由后向前,和每个已经完成排序的元素进行比较,
     98                 //当该元素小于已经完成排序的元素时,
     99                 //将该元素插入到找到的元素的前方,
    100                 //否则退出循环
    101                 if list[j] < list[j - 1]
    102                 {
    103                     //由于需要对界面元素进行调整,
    104                     //所以需要切换至主线程
    105                     weak var weak_self = self
    106                     DispatchQueue.main.async
    107                         {
    108                             //根据标识值,
    109                             //获得和需要交换顺序的数组元素相对应的视图对象
    110                             let view1 = weak_self?.view.viewWithTag(j+1)
    111                             let view2 = weak_self?.view.viewWithTag(j)
    112                              //获得两个视图对象的水平坐标X的值
    113                             let posX1 = view1?.frame.origin.x
    114                             let posX2 = view2?.frame.origin.x
    115                             //然后交换两个视图对象的水平坐标的值
    116                             //从而实现两个视图对象的位置的交
    117                             view1?.frame.origin.x = posX2!
    118                             view2?.frame.origin.x = posX1!
    119                              //记得更换两个视图对象的标识值
    120                             view1?.tag = j
    121                             view2?.tag = j+1
    122                              //交换数组中的两个元素的位置
    123                             let temp = list[j]
    124                             list[j] = list[j-1]
    125                             list[j-1] = temp
    126                             //将第二个循环语句的索引值减1,实现从后往前的遍历和比较
    127                             j = j - 1
    128                     }
    129                     //使线程休眠0.01秒,
    130                     //以方便观察排序的视觉效果
    131                     Thread.sleep(forTimeInterval: 0.01)
    132                 }
    133                 else
    134                 {
    135                     //否则退出循环
    136                     break
    137                 }
    138             }
    139         }
    140     }
    141     
    142     override func didReceiveMemoryWarning() {
    143         super.didReceiveMemoryWarning()
    144         // Dispose of any resources that can be recreated.
    145     }
    146 }

    SortView.swift文件

     1 import UIKit
     2 
     3 class SortView: UIView {
     4     //首先重写父类的初始化方法
     5     override init(frame: CGRect)
     6     {
     7         //设置自定义视图对象的显示区域
     8         super.init(frame: frame)
     9         self.frame = frame
    10     }
    11 
    12     //添加一个必须实现的初始化方法
    13     required init?(coder aDecoder: NSCoder) {
    14         fatalError("init(coder:) has not been implemented")
    15     }
    16     
    17     //重写父类的重新布局子视图方法
    18     //将在此视图中对视图进行外观设置
    19     override func layoutSubviews()
    20     {
    21         //首先获得自定义视图在界面中对Y轴坐标
    22         let y: CGFloat = 300 - frame.height
    23         //然后重新设置自定义视图的位置
    24         self.frame = frame
    25         self.frame.origin.y = y
    26         //根据自定义视图的高度,计算一个权重数值
    27         //用于生成不同的背景颜色
    28         let weight = frame.height / 200
    29         //生成不同y色相的颜色对象,从而给自定义视图设置不同的背景颜色
    30         //然后打开ViewController.swift文件
    31         let color = UIColor(hue: weight, saturation: 1, brightness: 1, alpha: 1)
    32         self.backgroundColor = color
    33     }
    34     /*
    35     // Only override draw() if you perform custom drawing.
    36     // An empty implementation adversely affects performance during animation.
    37     override func draw(_ rect: CGRect) {
    38         // Drawing code
    39     }
    40     */
    41 }
  • 相关阅读:
    hdu 1042 N!
    hdu 1002 A + B Problem II
    c++大数模板
    hdu 1004 Let the Balloon Rise
    hdu 4027 Can you answer these queries?
    poj 2823 Sliding Window
    hdu 3074 Multiply game
    hdu 1394 Minimum Inversion Number
    hdu 5199 Gunner
    九度oj 1521 二叉树的镜像
  • 原文地址:https://www.cnblogs.com/strengthen/p/9866551.html
Copyright © 2011-2022 走看看