“这是我参与8月更文挑战的第9天,活动详情查看:8月更文挑战”
关注我,以下内容持续更新
快速排序
从本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。是冒泡排序的优化, 它们都属于交换排序,交换排序的核心是交换
基本思想:将要排序的序列以枢纽值为界分割成独立的两部分,枢纽值左边的元素都比右边的元素小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列.在快速排序的过程中,每一轮循环都要选一个元素作为枢纽值,用这个枢纽值将序列分为两部分,选取枢纽值的方法有很多,这里我们采用三数取中法,也就是把头中尾三个元素进行排序,将中间值作为枢纽值
代码思路: 先采用三数取中法,找出枢纽值,将头中尾三个位置的数进行比较,最大值放到尾部位置,最小值放在头部位置,将枢纽值与右边数第二个位置的值进行交换,这时候枢纽值就右边数第二个位置.然后left指针从左边第一个位置开始往右走,遇到比枢纽值大的就停止,right指针从枢纽值左边的位置开始往左走,遇到比枢纽值小的就停止,然后判断两个指针没有碰头即left<right,就交换2个位置的元素,交换之后两个指针继续走循环此操作,直到两个指针碰头即left=right,此时left(此时left=right)位置左边的元素都比右边的元素小,然后把枢纽值插入到left位置,这一轮循环就实现了枢纽值左边的值都比右边的值小
//快速排序
-(void)quitSort:(NSMutableArray*)arr{
[self recusiveQuit:arr left:0 right:(int)arr.count-1];
}
-(void)recusiveQuit:(NSMutableArray*)arr left:(int)left right:(int)right{
//递归结束条件
if (left>=right) {
return;
}
int pivot = [self selectPivot:arr left:left right:right];
//因为第一个元素比枢纽值小,所以i从左边第二个元素开始移动
//枢纽值放在右边第二个位置,所以/j从左边第三个元素开始移动
int i = left;//i从左边第二个元素开始移动,后边用++i
int j = right-1;//j从右边第三个元素开始移动,后边用--j
while (i<j) {//当走到同一个位置,就退出循环,//将枢纽放在倒数第二个位置
while ([arr[++i] intValue] < pivot) { }
while ([arr[--j] intValue] > pivot) {}
if (i<j) {//如果没有碰头
[self swapArray:arr index1:i index2:j];
}
}
//将枢纽放在正确的位置
[self swapArray:arr index1:i index2:right-1];
//递归调用左边
[self recusiveQuit:arr left:left right:i-1];
//递归调用右边
[self recusiveQuit:arr left:i+1 right:right];
}
//三位取中法找出枢纽值,将最大值放在尾部,最小值放在头部,枢纽值与尾部第二个位置进行交换
-(int)selectPivot:(NSMutableArray*)arr left:(int)left right:(int)right{
int center = (left+right)/2;
if ([arr[left] intValue] > [arr[center] intValue]){
[self swapArray:arr index1:left index2:center];
}
if ([arr[center] intValue] > [arr[right] intValue]){
[self swapArray:arr index1:center index2:right];
}
if ([arr[left] intValue] > [arr[center] intValue]){
[self swapArray:arr index1:left index2:center];
}
[self swapArray:arr index1:center index2:right-1];
return [arr[right-1] intValue];//返回枢纽值
}