IOS数组排序整理
说起ios的排序,方法有很多种,最近正好有时间,做了一次整理,顺便测试了一下各种排序方法的效率,有不对的地方,望大家指正
测试的排序方法主要有以下几种:
- 插入排序(自己实现)
- 快速排序(自己实现)
- swift array.sorted(by: {(Any, Any) -> Bool})
- oc nsarray sortedArray(comparator: {Any, Any)->ComparisonResult})
- oc nsarray sortedArray(using: [NSSortDescriptor]);
插入排序
插入排序逻辑很简单,在数据结构算法分析的相关书籍里一般都被拿来作为排序的典型案例。其基本思想是:遍历数组,将每个元素插入到它之前大小正确的位置,比它大的元素后移一位。 插入排序利用了该元素之前的所有元素都是被排序过这个事实。插入排序和冒泡、希尔一样,平均时间复杂度都是O(N^2)
func insertionSort(cArr:[Int])->[Int]
{
var arr = cArr;
let arrLen = arr.count;
for p in 1..<arrLen
{
let tmp = arr[p];
for j in (0...p).reversed()
{
if(j-1 > -1 && arr[j-1] > tmp)
{
arr[j] = arr[j-1];
}
else
{
arr[j] = tmp;
break;
}
}
}
return arr;
}
快速排序
快速排序被认为是效率最好的排序方法之一,其核心思想和并归排序一样,都是分置算法的一种实现,平均时间复杂度为O(NlogN)
func qSort( arr:inout [Int], left:Int, right:Int)
{
if(right - left > 2)
{
let pivotIndex = Int((right - left)/2 + left);
let pivotValue = arr[pivotIndex];
arr[pivotIndex] = arr[right];
arr[right] = pivotValue;
var i:Int = left;
var j:Int = right - 1;
while(true)
{
while(arr[i] < pivotValue && i < right)
{
i += 1;
}
while (arr[j] > pivotValue && j > left)
{
j -= 1;
}
if(i < j)
{
let tmpIValue = arr[i];
arr[i] = arr[j];
arr[j] = tmpIValue;
i += 1;
j -= 1;
}
else
{
break;
}
}
let tmpIValue = arr[i];
arr[i] = arr[right];
arr[right] = tmpIValue;
qSort(arr: &arr, left: left, right: i - 1);
qSort(arr: &arr, left: i + 1, right: right);
}
else if(right - left > 0)
{
if(arr[left] > arr[right])
{
let tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
}
}
}
func quickSort(cArr:[Int])->[Int]
{
var arr = cArr;
qSort(arr: &arr, left: 0, right: arr.count - 1);
return arr;
}
swift array排序
结构太简单,直接上代码
func swiftBlockSort(arr:[Int])->[Int]
{
let result = arr.sorted(by: {(a, b)->Bool in return a < b;});
return result;
}
NSArray sortedArray comparator
这种排序需要向函数中传入一个Comparator,它是一个闭包{(Any, Any) -> ComparisonResul}
func ocComparatorSort(arr:NSArray)->[Any]
{
let result = arr.sortedArray(comparator: {
(x, y) -> ComparisonResult in
let a:Int = x as! Int;
let b:Int = y as! Int;
if(a < b)
{
return ComparisonResult.orderedAscending;
}
else if(b < a)
{
return ComparisonResult.orderedDescending;
}
return ComparisonResult.orderedSame;
})
return result;
}
NSArray sortedArray NSSortDescriptor
NSArray提供的另一种排序方法是通过NSSortDiscriptor
func ocDescriptorSort(arr:NSArray)->[Any]
{
let sortDescriptor:NSSortDescriptor = NSSortDescriptor(key: nil, ascending: true);
let result = arr.sortedArray(using: [sortDescriptor]);
return result;
}
效率测试
var srcArr:[Int] = [];
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let num:Int = 10000;
for _ in 0...num
{
srcArr.append(Int(arc4random())%num);
}
}
首先初始化一个10000个数的数组,然后分别运用上面的各种排序方法进行测试
instrument time profiler结果如下:
Weight Self Weight Symbol Name
206.00 ms 23.7% 0 s @objc ViewController.ocCompareSort(AnyObject) -> ()
189.00 ms 21.7% 0 s @objc ViewController.onDescriptorSort(AnyObject) -> ()
164.00 ms 18.9% 0 s @objc ViewController.insertSort(AnyObject) -> ()
60.00 ms 6.9% 0 s @objc ViewController.swiftBlockSort(AnyObject) -> ()
48.00 ms 5.5% 0 s @objc ViewController.quickSort(AnyObject) -> ()
经过多次测试,结果基本都差不多
快速排序 和 swift array排序在一个水平线上,而NSArray sortedArray comparator、NSArray sortedArray NSSortDescriptor、插入排序在同一个档次,基本上都是前两种排序的3倍时间(难道Apple对swift的优化做的这么好了?)