ios开发——常用经典算法OC篇&冒泡/快速
冒泡排序与快速排序
1、序言
ios开发中涉及到算法的地方还真不多,除非你的应用程序真的非常大,或者你想你的应用程序性能非常好才会去想到关于算法方面的性能优化,而在ios开发中真的能用得到的也就是关于排序的,当然如果你是做游戏的话那么你可能会涉及到不少的算法或者优化问题,但是这不是本篇文章讨论的范围。
后面的文章中,我将会给大家详细介绍八大算法。
2、冒泡排序
2.1 引出
前面的两篇博客里讲的插入排序是基于“逐个记录插入”,选择排序是基于“选择”,那么冒泡排序其实是基于“交换”。每次从第一个记录开始,一、二两个记录比较,大的往后放,二三两个记录比较...依次类推,这就是一趟冒泡排序。每一趟冒泡排序后,无序序列中值最大的记录冒到序列末尾,所以称之为冒泡排序。
2.2 代码
//冒泡排序
void bubbleSort(int *a,int n)
{
int i,j;
;i<n;i++)
;j<n-i+;j++){
]<a[j]){
a[j]=a[j]+a[j+];
a[j+]=a[j]-a[j+];
a[j]=a[j]-a[j+];
}
}
}
冒泡排序算法:
冒泡排序代码
static void Main(string[] args)
{
////五次比较
; i <= ; i++)
{
List<int> list = new List<int>();
//插入2k个随机数到数组中
; j < ; j++)
{
Thread.Sleep();
list.Add(, ));
}
Console.WriteLine("\n第" + i + "次比较:");
Stopwatch watch = new Stopwatch();
watch.Start();
var result = list.OrderBy(single => single).ToList();
watch.Stop();
Console.WriteLine("\n快速排序耗费时间:" + watch.ElapsedMilliseconds);
Console.WriteLine().ToList()));
watch.Start();
result = BubbleSort(list);
watch.Stop();
Console.WriteLine("\n冒泡排序耗费时间:" + watch.ElapsedMilliseconds);
Console.WriteLine().ToList()));
Console.ReadKey();
}
}
//冒泡排序算法
private static List<int> BubbleSort(List<int> list)
{
int temp;
//第一层循环: 表明要比较的次数,比如list.count个数,肯定要比较count-1次
; i < list.Count - ;i++ )
{
//list.count-1:取数据最后一个数下标,47
//j>i: 从后往前的的下标一定大于从前往后的下标,否则就超越了。
; j > i;j-- )
{
//如果前面一个数大于后面一个数则交换
] > list[j])
{
temp = list[j - ];
list[j - ] = list[j];
list[j] = temp;
}
}
}
return list;
}
2.3 效率分析
相对于简单选择排序,冒泡排序交换次数明显更多。它是通过不断地交换把最大的数冒出来。冒泡排序平均时间和最坏情况下(逆序)时间为o(n^2)。最佳情况下虽然不用交换,但比较的次数没有减少,时间复杂度仍为o(n^2)。此外冒泡排序是稳定的。
3、快速排序
3.1 引出
快速排序是冒泡排序的一种改进,冒泡排序排完一趟是最大值冒出来了,那么可不可以先选定一个值,然后扫描待排序序列,把小于该值的记录和大于该值的记录分成两个单独的序列,然后分别对这两个序列进行上述操作。这就是快速排序,我们把选定的那个值称为枢纽值,如果枢纽值为序列中的最大值,那么一趟快速排序就变成了一趟冒泡排序。
3.2 代码
两种版本,第一种是参考《数据结构》,在网上这种写法很流行。第二种是参考《算法导论》,实现起来较复杂。
//快速排序(两端交替着向中间扫描)
void quickSort1(int *a,int low,int high)
{
int pivotkey=a[low];//以a[low]为枢纽值
int i=low,j=high;
if(low>=high)
return;
//一趟快速排序
while(i<j){//双向扫描
while(i < j && a[j] >= pivotkey)
j--;
a[i]=a[j];
while(i < j && a[i] <= pivotkey)
i++;
a[j]=a[i];
}
a[i]=pivotkey;//放置枢纽值
//分别对左边、右边排序
quickSort1(a,low,i-);
quickSort1(a,i+,high);
}
//快速排序(以最后一个记录的值为枢纽值,单向扫描数组)
void quickSort2(int *a,int low,int high)
{
int pivotkey=a[high];//以a[high]为枢纽值
,temp,j;
if(low>=high)
return;
//一趟快速排序
for(j=low;j<high;j++){
if(a[j]<=pivotkey){
i++;
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
i++;
//放置枢纽值
temp=a[i];
a[i]=pivotkey;
a[high]=temp;
//分别对左边、右边排序
quickSort2(a,low,i-);
quickSort2(a,i+,high);
}
快速排序算法:
快速排序法
static void Main(string[] args)
{
//5次比较
; i <= ; i++)
{
List<int> list = new List<int>();
//插入200个随机数到数组中
; j < ; j++)
{
Thread.Sleep();
list.Add(, ));
}
Console.WriteLine("\n第" + i + "次比较:");
Stopwatch watch = new Stopwatch();
watch.Start();
var result = list.OrderBy(single => single).ToList();
watch.Stop();
Console.WriteLine("\n系统定义的快速排序耗费时间:" + watch.ElapsedMilliseconds);
Console.WriteLine().ToList()));
watch.Start();
, list.Count - );
watch.Stop();
Console.WriteLine("\n俺自己写的快速排序耗费时间:" + watch.ElapsedMilliseconds);
Console.WriteLine().ToList()));
Console.ReadKey();
}
}
public class QuickSortClass
{
///<summary>
////// 分割函数
///</summary>
//////<param name="list">待排序的数组</param>
///<param name="left">数组的左下标</param>
//////<param name="right"></param>
///<returns></returns>
public int Division(List<int> list, int left, int right)
{
//首先挑选一个基准元素
int baseNum = list[left];
while (left < right)
{
//从数组的右端开始向前找,一直找到比base小的数字为止(包括base同等数)
while (left < right && list[right] >= baseNum)
right = right - ;
//最终找到了比baseNum小的元素,要做的事情就是此元素放到base的位置
list[left] = list[right];
//从数组的左端开始向后找,一直找到比base大的数字为止(包括base同等数)
while (left < right && list[left] <= baseNum)
left = left + ;
//最终找到了比baseNum大的元素,要做的事情就是将此元素放到最后的位置
list[right] = list[left];
}
//最后就是把baseNum放到该left的位置
list[left] = baseNum;
//最终,我们发现left位置的左侧数值部分比left小,left位置右侧数值比left大
//至此,我们完成了第一篇排序
return left;
}
public void QuickSort(List<int> list, int left, int right)
{
//左下标一定小于右下标,否则就超越了
if (left < right)
{
//对数组进行分割,取出下次分割的基准标号
int i = Division(list, left, right);
//对“基准标号“左侧的一组数值进行递归的切割,以至于将这些数值完整的排序
QuickSort(list, left, i - );
//对“基准标号“右侧的一组数值进行递归的切割,以至于将这些数值完整的排序
QuickSort(list, i + , right);
}
}
}
3.3 效率分析
快速排序时间与划分是否对称有关。快速排序的平均时间复杂度为o(n*logn),至于为什么是o(n*logn),请参考《算法导论》第7章,书中用递归树的方法阐述了快速排序平均时间。且常数因子很小,所以就平均时间而言,快速排序是很好的内部排序方法。最佳情况下(每次划分都对称)时间复杂度o(n*logn)。最坏情况下(每次划分都不对称,如输入的序列有序或者逆序时)时间复杂度为o(n^2),所以在待排序序列有序或逆序时不宜选用快速排序。此外,快速排序是不稳定的。
最佳情况下,每次划分都是对称的,由于枢纽值不再考虑,所以得到的两个子问题的大小不可能大于n/2,同时一趟快速排序时间为o(n),所以运行时间递归表达式:
T(n)<=2T(n/2)+o(n)。这个递归式的解法请参考下一篇博客中归并排序效率分析。其解为T(n)=o(n*logn)。
最坏情况下,每次划分都很不对称,T(n)=T(n-1)+o(n),可以用递归树来解,第i层的代价为n-i+1.总共有n层。把每一层代价加起来有n-1个n相加。所以这个递归式的解为T(n)=o(n^2),此时就是冒泡排序。
ios开发——常用经典算法OC篇&冒泡/快速的更多相关文章
- iOS开发——高级技术精选OC篇&Runtime之字典转模型实战
Runtime之字典转模型实战 如果您还不知道什么是runtime,那么请先看看这几篇文章: http://www.cnblogs.com/iCocos/p/4734687.html http://w ...
- iOS开发--JS调用原生OC篇
JS调用原生OC篇 方式一(反正我不用) 第一种方式是用JS发起一个假的URL请求,然后利用UIWebView的代理方法拦截这次请求,然后再做相应的处理. 我写了一个简单的HTML网页和一个btn点击 ...
- iOS开发——网络使用技术OC篇&网络爬虫-使用正则表达式抓取网络数据
网络爬虫-使用正则表达式抓取网络数据 关于网络数据抓取不仅仅在iOS开发中有,其他开发中也有,也叫网络爬虫,大致分为两种方式实现 1:正则表达 2:利用其他语言的工具包:java/Python 先来看 ...
- iOS开发——高级UI之OC篇&UIdatePicker&UIPickerView简单使用
UIdatePicker&UIPickerView简单使用 /***************************************************************** ...
- iOS开发-常用第三方开源框架介绍
iOS开发-常用第三方开源框架介绍 图像: 1.图片浏览控件MWPhotoBrowser 实现了一个照片浏览器类似 iOS 自带的相册应用,可显示来自手机的图片或者是网络图片,可自动从网 ...
- IOS开发常用设计模式
IOS开发常用设计模式 说起设计模式,感觉自己把握不了笔头,所以单拿出iOS开发中的几种常用设计模式谈一下. 单例模式(Singleton) 概念:整个应用或系统只能有该类的一个实例 在iOS开发我们 ...
- javascript常用经典算法实例详解
javascript常用经典算法实例详解 这篇文章主要介绍了javascript常用算法,结合实例形式较为详细的分析总结了JavaScript中常见的各种排序算法以及堆.栈.链表等数据结构的相关实现与 ...
- iOS开发--常用技巧 (MJRefresh详解)
iOS开发--常用技巧 (MJRefresh详解) https://github.com/CoderMJLee/MJRefresh 下拉刷新01-默认 self.tableView.head ...
- iOS开发常用第三方库
UI 动画 网络相关 Model 其他 数据库 缓存处理 PDF 图像浏览及处理 摄像照相视频音频处理 响应式框架 消息相关 版本新API的Demo 代码安全与密码 测试及调试 AppleWatch ...
随机推荐
- 正在连接...ORA-12541: TNS: 无监听程序
明明已经在Net Configuration Assistant中配置过监听程序并启动过.但在测试本地网络服务名配置中扔提示以上错误"正在连接...ORA-12541: TNS: 无监听程序 ...
- [Everyday Mathematics]20150115
试计算积分 $$\bex \int_{-\pi}^\pi \frac{\sin nx}{(1+2^x)\sin x}\rd x, \eex$$ 其中 $n$ 是自然数.
- 打印Ibatis最终的SQL语句
在项目开发时都大家都希望将SQL在后台打印出来,以帮助开发以及后续的bug修改.如果用JDBC那么可以方便的打印,可使用ibatis就不知道怎么办了,最近在网上找了一段log4j的配置可以很保姆的处理 ...
- The Bookcase
题意: 有n本宽w高h的书,向三层书架上放,每层不能为空,求占用的整体的最小面积(总高度*三层中最宽的) 分析: 不太好想,dp[i][j]表示第一层宽度为i第二层为j放的最小高度 dp[i][j]= ...
- codeforces 675C Money Transfers map
上面是官方题解,写的很好,然后就A了,就是找到前缀和相等的最多区间,这样就可以减去更多的1 然后肯定很多人肯定很奇怪为什么从1开始数,其实从2开始也一样,因为是个环,从哪里开始记录前缀和都一样 我们的 ...
- CMDB反思2
当云灭掉CMDB http://blog.vsharing.com/xqscool/A1193910.html 虽然之前也思考过当运维底层都被替换为云时,现有的传统运维可能就消失了,其所依赖的ITIL ...
- kmeans算法的matlab实践
把图像中所有的像素点进行RGB聚类分析,然后输出看结果 img = imread('qq.png'); %取出R矩阵,并将这个R矩阵拉成一列 imgR = img(:,:,1); imgR = img ...
- 怎么对HTML 5的特性做检测?
原译文地址:http://www.ido321.com/1116.html 原文:Detect HTML5 Features 译文:HTML5特性检测 译者:dwqs 随 着HTML 5的流行,现在H ...
- 常用的正则表达式归纳—JavaScript正则表达式
来源:http://www.ido321.com/856.html 1.正则优先级 首先看一下正则表达式的优先级,下表从最高优先级到最低优先级列出各种正则表达式操作符的优先权顺序: 2.常用的正则表达 ...
- 如何用chrome修改js代码,跳过网站等待时间
用chrome修改js代码 By Z.H. Fu 切问录 [maplewizard.github.io](http://maplewizard.github.io ) 网页中大部分的限制都是由js编写 ...