zoukankan      html  css  js  c++  java
  • iOS 快速排序

    一.快速排序概念及其思想

    快速排序(QuickSort),又称为交换排序,是分治算法的一种,快速排序采用分治的策略。

    1.分治法的基本思想:

    将原问题分解为若干个规模更小但结构和原问题相似的子问题。递归这些子问题,然后将这些子问题的解组合为原问题的解。

    2.快速排序的基本思想

    通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

    二.快速排序步奏解释

         设当前待排序的无序区为R[low..high],利用分治法可将快速排序的基本思想描述为:

    ①分解: 
         在R[low..high]中任选一个记录作为基准(Pivot),以此基准将当前无序区划分为左、右两个较小的子区间R[low..pivotpos-1)和R[pivotpos+1..high],并使左边子区间中所有记录的关键字均小于等于基准记录(不妨记为pivot)的关键字pivot.key,右边的子区间中所有记录的关键字均大于等于pivot.key,而基准记录pivot则位于正确的位置(pivotpos)上,它无须参加后续的排序。
      注意:
         划分的关键是要求出基准记录所在的位置pivotpos。划分的结果可以简单地表示为(注意pivot=R[pivotpos]):
         R[low..pivotpos-1].keys≤R[pivotpos].key≤R[pivotpos+1..high].keys
                      其中low≤pivotpos≤high。
    ②求解: 
         通过递归调用快速排序对左、右子区间R[low..pivotpos-1]和R[pivotpos+1..high]快速排序。

    ③组合: 
         因为当"求解"步骤中的两个递归调用结束时,其左、右两个子区间已有序。对快速排序而言,"组合"步骤无须做什么,可看作是空操作。

    简单地说:

    步奏详解

    1 ).设置两个变量i,j ,排序开始时i = 0,就j = mutableArray.count - 1;
    2 ).设置数组的第一个值为比较基准数key,key = mutableArray.count[0];
    3 ).因为设置key为数组的第一个值,所以先从数组最右边开始往前查找比key小的值。如果没有找到,j--继续往前搜索;如果找到则将mutableArray[i]和mutableArray[j]互换,并且停止往前搜索,进入第4步;
    4 ).从i位置开始往后搜索比可以大的值,如果没有找到,i++继续往后搜索;如果找到则将mutableArray[i]和mutableArray[j]互换,并且停止往后搜索;
    5 ).重复第3、4步,直到i == j(此时刚好执行完第三步或第四部),停止排序;

    假设mutableArray = [@(4),@(3),@(7),@(1),@(5),@(8)]

    下标012345
    数据 4 3 7 1 5 8

    第一步:i = 0; j = 5; key = 4;

    第二步:要找比key小的指,从右往前找,j不断递减,直到找到第一个比key小的,然后将mutableArray[i]和mutableArray[j]互换

    下标012345
    数据 1 3 7 4 5 8
    i = 0; j = 3; key = 4;

    第三步:要找比key大的指,从左往后找,i不断递增,直到找到第一个比key大的,然后将mutableArray[i]和mutableArray[j]互换

    下标012345
    数据 1 3 4 7 5 8
    i = 2; j = 3; key = 4;

    接着j--,则i==j;这样就称为一次循环
    然后将key左边,右边的值分别当做一个数组重复上面步骤

    三.任何的说法都是……,上代码

     

    - (void)viewDidLoad {
        [super viewDidLoad];
        
        NSMutableArray *arr = [[NSMutableArray alloc]initWithObjects:@(10),@(34),@(1),@(26),@(8),@(6),@(38), nil];
        [self quickSortArr:arr withLeftIndex:0 andRightIndex:arr.count -1];
        NSLog(@"%@",arr);
        
    }
    
    - (void)quickSortArr:(NSMutableArray *)array withLeftIndex:(NSInteger )leftIndex andRightIndex:(NSInteger )rightIndex{
        if (leftIndex > rightIndex) {
            return;
        }
        
        NSInteger i = leftIndex;
        NSInteger j = rightIndex;
        NSInteger key = [array[i]integerValue];
        
        while (i < j) {
            while (i < j && key <= [array[j] integerValue]) {
                j --;
            }
            array[i] = array[j];
            
            while (i < j && key >= [array[i] integerValue]) {
                i ++;
            }
            array[j] = array[i];
        }
        array[i] = @(key);
        
        //前面排序
        [self quickSortArr:array withLeftIndex:leftIndex andRightIndex:i -1];
        //后面排序
        [self quickSortArr:array withLeftIndex:i + 1 andRightIndex:rightIndex];
        
    }

     

     

    时间复杂度:
    其实对快排而言,最好的情况就是每次partition操作的元素正好插在整个子序列的中间,这样是最好的,因此最好效率是N*logN。最坏情况当然就是往两极插了,N方。

  • 相关阅读:
    小猪存钱罐
    SSL与HTTPS协议
    KVM之XFS磁盘扩容
    vue学习笔记(一)
    ant打包总结
    github上传代码总结
    java中map遍历的总结
    angularjs初学总结
    angularjs常用指令
    github上传代码总结
  • 原文地址:https://www.cnblogs.com/guohai-stronger/p/8975871.html
Copyright © 2011-2022 走看看