[Swift]八大排序算法(八):基数排序

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

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

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

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

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

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


基数排序

基数排序(Radix Sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份信息,将要排序的元素分配至某些“桶”中,藉以达到排序的作用。

基数排序法是属于稳定性的排序,其时间复杂度为O(nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。

基本思想:

将整数按位数切割成不同的数字,然后按每个位数分别比较。

具体做法:

将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。

然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。


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

  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.radixSort(list: &self.result)
 73             //获得排序后的系统时间,
 74             //并在控制台输出两个时间的差值,
 75             //从而获得排序所花费的大致时间。
 76             //考虑线程休眠的影响,此数据仅做参考
 77             let endDate = Date()
 78             print(endDate.timeIntervalSince(self.date))
 79         }
 80     }
 81 
 82      //添加一个方法,用来实现具体的可视化的基数排序的功能
 83     private func radixSort(list: inout Array<Int>)
 84     {
 85         //首先初始化一个二维数组,作为10个空桶
 86         //每个空桶作为子数组,
 87         //分别存储位数为0至9的所有元素
 88         var bucket: Array<Array<Int>> = []
 89         //通过一循环语句,
 90         //往二维数组中添加10个空数组
 91         for _ in 0..<10
 92         {
 93             bucket.append([])
 94         }
 95         //接着来获得数组中的所有元素的最大值,
 96         //从而获得位数最多的元素。
 97         //例如数组中的最大值为1234
 98         //那么它的位数为4,并且也是数组中所有元素最大的位数。
 99         var maxNumber = list[0]
100         //通过循环语句,获得数组中元素的最大值
101         for item in list
102         {
103             if maxNumber < item
104             {
105                 maxNumber = item
106             }
107         }
108         //将该元素转换为字符串,
109         //从而通过字符串的长度,
110         //获得该元素的位数。
111         let maxLength = "\(maxNumber)".count
112         //添加一个循环语句,循环区间为1到最大位数。
113         //该循环语句用来进行基数排序
114         for digit in 1...maxLength
115         {
116             //通过一个实例方法,获得指定位数的值,并添加到对应的桶数组中。
117             //例如当digit的值为1时,表示获得个位数的值,
118             //并存储在对应的桶(子数组)中
119             for item in list
120             {
121                 let baseNumber = fetchBaseNumber(number: item, digit: digit)
122                 bucket[baseNumber].append(item)
123             }
124             //到此完成了入桶操作,接着进行出桶操作。
125             //即将所有桶中的数据全部取出,并依次放在数组中。
126             //首先初始化一个整形变量,作为索引值。
127             var index = 0
128             //添加一个循环语句,对十个桶进行遍历
129             for i in 0..<bucket.count
130             {
131                 //添加另一个循环语句,进行出桶的操作,
132                 //直到桶的数据为空。
133                 while !bucket[i].isEmpty
134                 {
135                     //将桶中的第一个元素删除
136                     //并将返回的被删除的元素,
137                     //存入数组中指定的索引位置。
138                     list[index] = bucket[i].remove(at: 0)
139                     //接着同步更新界面中对应的视图对象的高度
140                     self.udpateView(j: index, height: list[index])
141                     index += 1
142                 }
143             }
144         }
145     }
146 
147     //添加一个方法,用来获得指定位数的值,
148     //例如获取某个数字的个位、十位、千位等的值
149     func fetchBaseNumber(number: Int, digit: Int) -> Int
150     {
151         //在此将数字转换为字符串的方式
152         //来获得指定位数的值
153         if digit > 0 && digit <= "\(number)".count
154         {
155             //初始化一个整形数组,用来存储数字的每个位数的值
156             var numbersArray: Array<Int> = []
157             //通过一个循环语句,将数字的每个位数,
158             //添加到整形数组中
159             for char in "\(number)".characters
160             {
161                 numbersArray.append(Int("\(char)")!)
162             }
163             //最后根据位数,获取并返回数组中的值
164             return numbersArray[numbersArray.count - digit]
165         }
166         //采用0作为默认值
167         return 0
168     }
169 
170     //添加一个方法,用来更新视图的高度
171     func udpateView(j: Int, height: Int)
172     {
173         //由于需要对界面元素进行调整,
174         //所以需要切换至主线程
175         weak var weak_self = self
176         DispatchQueue.main.async
177         {
178             //根据标识值,
179             //获得和需要交换顺序的数组元素相对应的视图对象
180             //并设置它的新的高度
181             let view = weak_self?.view.viewWithTag(j+1)
182             view?.frame.size.height = CGFloat(height*2)
183         }
184         //使线程休眠0.01秒,
185         //以方便观察排序的视觉效果
186         Thread.sleep(forTimeInterval: 0.01)
187     }
188 
189     override func didReceiveMemoryWarning() {
190         super.didReceiveMemoryWarning()
191         // Dispose of any resources that can be recreated.
192     }
193 }

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 }

 

转载于:https://www.cnblogs.com/strengthen/p/9866566.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/412989.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

推一波JAVA学习公众号

大家好&#xff0c;我是烤鸭&#xff0c;今天不水了。分享一波java学习公众号。从基础到架构都有&#xff0c;另外说一句&#xff0c;注意身体吧。另外说一句&#xff0c;本文不定时更新。1. JAVA思维导图2. 程序员小灰可爱的小仓鼠3. 码农每日一题4. JAVA后端技…

二叉树的三种遍历(递归与非递归) + 层次遍历

<转载于 >>> > 二叉树是一种非常重要的数据结构&#xff0c;很多其他数据机构都是基于二叉树的基础演变过来的。二叉树有前、中、后三种遍历方式&#xff0c;因为树的本身就是用递归定义的&#xff0c;因此采用递归的方法实现三种遍历&#xff0c;不仅代码简洁…

springboot使用mongodb

大家好&#xff0c;我是烤鸭&#xff1a;这是一篇关于springboot项目中使用mongodb。 环境&#xff1a;jdk 1.8springboot 1.5.6.RELEASEmaven 3.5 1. mongodb在springboot中的配置springboot集成这个三方插件就是简单&#xff0c;只需要引入依赖&#xff0c;在properties或者…

eclipse搜索框太小

解决方式&#xff1a; Window>Preferences>DevStyle>Inline Search 把 use the inline search 取消勾选

fileinput 加 ftp 加 nginx 加 SpringBoot上传文件

亲测可用 准备linux服务器 https://www.cnblogs.com/shuaifing/p/8268949.html 搭建ftp https://www.cnblogs.com/shuaifing/p/8260532.html Springboot整合fileinput 上传文件https://www.cnblogs.com/shuaifing/p/8274906.html 页面 引入 jquery boostrap fileinput.min.js…

Centos7安装Hadoop教程

一&#xff1a;安装SSH 1&#xff0c;执行下面的命令安装ssh yum install openssh-clients yum install openssh-server 2&#xff0c;执行如下命令测试一下 SSH 是否可用&#xff08;SSH首次登陆提示 yes/no 信息&#xff0c;输入 yes 即可&#xff0c;然后按照提示输入 root…

elasticsearch 6.x (一) 部署 windows入门 spingboot连接

大家好&#xff0c;我是烤鸭&#xff1a;今天分享的是 elasticsearch 6.x 部署 windows服务器。环境&#xff1a;win10elasticsearch-6.2.4springboot 2.0.0.RELEASE1. 官网下载elasticsearch这个是最新版本的es下载地址。https://www.elastic.co/downloads/elasticsearch选择z…

Programming Assignment 5: Burrows–Wheeler Data Compression

Programming Assignment 5: Burrows–Wheeler Data Compression 1. 题目阅读 实现Burrows-Wheeler数据压缩算法。这个革命性的算法产生了gzip和pkzip&#xff0c;并且相对容易实现&#xff0c;还不受任何专利保护。它构成了unix压缩实用程序bzip2的基础。 这个算法由以下三种算…

elasticsearch 6.x (二) linux部署 kibana x-pack 安装

大家好&#xff0c;我是烤鸭&#xff1a; 环境&#xff1a;linux Cent OS 7.3elasticsearch-6.2.4 1. 下载elasticsearch https://www.elastic.co/downloads/elasticsearch 上面的网址直接下载的话&#xff0c;实在太慢了。官方还提供了另一种方式。 https://www.elastic.co…

Kali Linux ——在无网络情况下安装无线网卡驱动

1、背景&#xff1a; 今日刚刚开始学习kali linux&#xff0c;众所周知&#xff0c;安装完成后&#xff0c;系统是没有无线网卡驱动的&#xff0c;这就对学生党造成相当的困扰&#xff1a;校园网要连接有线是需要认证客户端的&#xff0c;而认证客户端只有windows端&#xff0c…

HADOOP_HOME and hadoop.home.dir are unset 报错处理

一般是windows才会出现这个问题 请看下面的解决方案&#xff1a; 第一步&#xff1a;下载winutils-master.zip Gitee地址&#xff1a;https://gitee.com/nkuhyx/winutils.git 蓝奏云&#xff1a;https://www.lanzoux.com/i55ccnc Github地址&#xff1a;https://github.com/cda…

elasticsearch 6.x (三) linux 集群多节点部署

大家好&#xff0c;我是烤鸭&#xff1a;关于集群内单个节点部署&#xff0c;请参考上一篇文章。elasticsearch 6.x linux部署(二) kibana x-pack 安装环境&#xff1a;linux Cent OS 7.3elasticsearch-6.2.41. 下载多个es安装每个安装步骤都是一样的。2. 修改配置文件(重…

springboot-devtools idea或eclipse 热加载

大家好&#xff0c;我是烤鸭&#xff1a;今天分享一下springboot项目的热加载。第二种方式在eclipse和idea中都可以。虽然会有一些小坑。 方式有两种&#xff1a; 1. springloaded(无效) <!-- https://mvnrepository.com/artifact/org.springframework/springloaded -->…

springboot mybatis 热加载mapper.xml文件(最简单)

大家好&#xff0c;我是烤鸭: 今天介绍一下springboot mybatis 热加载mapper.xml文件。 本来不打算写的&#xff0c;看到网上比较流行的方式都比较麻烦&#xff0c;想着简化一下。 网上流行的版本。 https://www.cnblogs.com/oskyhg/p/8587701.html 总结一下需要&#xff1a;my…

vue cli vue 3.x

vue cli & vue 3.x https://cli.vuejs.org/dev-guide/ui-api.html#ui-api https://cli.vuejs.org/zh/guide/#cli vue cli & how to select the option in cmd ? vue cli & 选中 option a select all & i select all 1,2,3,4,5,6,7,8,9,0 分别对应 order 转载…

jenkins svn/git sonarqube scanner 代码集成测试

大家好&#xff0c;我是烤鸭&#xff1a;今天分享一个代码检测工具sonar&#xff0c;在jenkins集成的时候使用。 环境:sonarqube 7.1jenkins 2.12xsonarqube scanner &#xff08;官网最新版3.2.0.1227&#xff09;1. jenkins svn/git 搭建项目https://blog.csdn.net/Angry…

射频与微波测量之S参数

转自&#xff1a;https://www.cnblogs.com/lyh523329053/p/9128577.html S参数 S散射也叫散射参数。是微波传输中的一组重要参数。由于我们很难在高频率时测量电流或电压&#xff0c;因此我们要测量散射参数或 S 参数。这些参数用来表征RF 元件或网络的电气属性或性能&#xff…

JAVA构造对象的几种方式(构建器、构造器)

大家好&#xff0c;我是烤鸭&#xff1a;今天说一下初始化对象的几种方式&#xff1a;1. 多参数构造器2. 构建器3. 构造器后 get/set方法举个例子:这里有个机构entity&#xff0c;提供一个默认构造器 package com.xxx.xxx.modules.sys.entity;/*** 机构Entity* versi…

Django框架(十二)-- Djang与Ajax

一、什么是Ajax AJAX&#xff08;Asynchronous Javascript And XML&#xff09;翻译成中文就是“异步Javascript和XML”。即使用Javascript语言与服务器进行异步交互&#xff0c;传输的数据为XML&#xff08;当然&#xff0c;传输的数据不只是XML,现在更多使用json数据&#xf…

javascript 将table导出 Excel ,可跨行跨列

原文地址&#xff1a;https://www.cnblogs.com/hailexuexi/p/10795887.html <script language"JavaScript" type"text/javascript">//jQuery HTML导出Excel文件(兼容IE及所有浏览器)function HtmlExportToExcel(tableid,file_name) {var filename fi…