标签:要求 第一步 并且 个数 利用 oid 结果 有序 序列
一.快速排序概念及其思想
快速排序(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)]
下标 | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
数据 | 4 | 3 | 7 | 1 | 5 | 8 |
第一步:i = 0; j = 5; key = 4;
第二步:要找比key小的指,从右往前找,j不断递减,直到找到第一个比key小的,然后将mutableArray[i]和mutableArray[j]互换
下标 | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
数据 | 1 | 3 | 7 | 4 | 5 | 8 |
i = 0; j = 3; key = 4;
第三步:要找比key大的指,从左往后找,i不断递增,直到找到第一个比key大的,然后将mutableArray[i]和mutableArray[j]互换
下标 | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
数据 | 1 | 3 | 4 | 7 | 5 | 8 |
i = 2; j = 3; key = 4;
接着j--,则i==j;这样就称为一次循环
然后将key左边,右边的值分别当做一个数组重复上面步骤
三.任何的说法都是……,上代码
#import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; NSMutableArray *arr = [[NSMutableArray alloc]initWithObjects:@(100), @(1),@(8),@(5),@(9),@(4),@(3),@(7),nil]; [self quickSortArray:arr withLeftIndex:0 andRightIndex:arr.count -1]; NSLog(@"%@",arr); } - (void)quickSortArray:(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) { /**** 首先从右边j开始查找比基准数小的值 ***/ while (i < j && [array[j]integerValue] > key) { j--; } //如果比基数小,则将查找到的小值重新调换到i的位置 array[i] = array[j]; /**当在右边查找到一个比基准数小的值时,就从i开始往后找就从i开始往后找比基数大的值*/ while (i < j && [array[i]integerValue]) { i++; } //如果比基准数大,则将查找到的大值调换到j的位置 array[j] = array[i]; } array[i] = @(key); //排序基准数左边的 [self quickSortArray:array withLeftIndex:leftIndex andRightIndex:i - 1]; //排序基准数右边的 [self quickSortArray:array withLeftIndex:i + 1 andRightIndex:rightIndex]; }
时间复杂度:
其实对快排而言,最好的情况就是每次partition操作的元素正好插在整个子序列的中间,这样是最好的,因此最好效率是N*logN。最坏情况当然就是往两极插了,N方。
标签:要求 第一步 并且 个数 利用 oid 结果 有序 序列
原文地址:https://www.cnblogs.com/guohai-stronger/p/8975871.html