iOS算法--快速排序

会有一股神秘感。 提交于 2019-12-14 08:57:07

快速排序(举例为从小到大排列)

特性:

在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见。事实上,快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它采用的是内部循环(inner loop),这个可以在大部分的架构上很有效率地被实现出来。

时间复杂度:

最优: 每一次的flag刚好都可以平分整个数组,此时的时间复杂度为O(nlogn)

最坏: 每一次的flag刚好都是最大或者最小的数,此时的时间复杂度为O(n2)

平均: O(nlogn)

原理

每次扫描 碰到比基准值小的放到左边 碰到比基准值大的放到右边, 等左右两边的flag相遇时,将基准值赋值给当前的index对应的数据.
然后 接下来 进入递归 缩小范围
左边递归范围: left ->基准值赋值的index - 1
右边递归范围: 基准值赋值的index + 1 => right

简单来说就是 确保每次范围内的扫描结果是 左边小右边大,范围的获取是基于上次递归后的基准赋值index分割.

代码

+ (void)quickSortWithArray:(NSMutableArray<NSNumber *> *)array
                      left:(NSInteger)left
                     right:(NSInteger)right {
    
    if (left > right) {
    // 没得分区了,分区递归结束
        return;
    }
    
    NSInteger leftIndex = left;
    NSInteger rightIndex = right;
    
    定义一个基准数据
    NSInteger key = array[leftIndex].integerValue;
    
    while (leftIndex < rightIndex) {
        
        // 左边固定,从右边向左边扫描, 如果扫描的数据 < key 进行交换
        if (leftIndex < rightIndex && key <= array[rightIndex].integerValue) {
            rightIndex--;
        }
        
        if (leftIndex < rightIndex) {
            array[leftIndex] = array[rightIndex];
        }
        
        // 右边固定, 从左边向右边扫描, 如果左边的数据 <key 进行交换
        if (leftIndex < rightIndex && array[leftIndex].integerValue <= key) {
            leftIndex++;
        }
        
        if (leftIndex < rightIndex) {
            array[rightIndex] = array[leftIndex];
        }
        // 依次循环 直到此次内部排列 leftIndex == rightIndex 进入下一个递归
    }
    
    array[leftIndex] = [NSNumber numberWithInteger:key];
    
    // 递归排列leftIndex左边的顺序
    [self quickSortWithArray:array left:left right:leftIndex - 1];
    // 递归排列rightIndex右边的顺序
    [self quickSortWithArray:array left:leftIndex + 1 right:right];
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!