• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

[Swift]八大排序算法(五):插入排序

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

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

热烈欢迎,请直接点击!!!

进入博主App Store主页,下载使用各个作品!!!

注:博主将坚持每月上线一个新app!!!

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

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

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

当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, width: 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, width: 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 }

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
SwiftWKWebView网页无法显示问题发布时间:2022-07-13
下一篇:
Swift实战之2048小游戏发布时间:2022-07-13
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap