排序算法(OC实现)

排序的分类:

交换类排序:冒泡排序、快速排序
插入类排序:直接插入排序、希尔排序
选择类排序:简单选择排序、堆排序

交换类排序

冒泡排序

时间复杂度:最好(有序情况下)O(n),平均(逆序情况下)O(n^2)
空间复杂度:O(1)
算法思想:(从小到大,从前往后)
第一个记录和第二个记录比较,如果第一个大,则二者交换,否则不交换;然后第二个记录和第三个记录比较,如果第二大,则二者交换,否则不交换……
这里写图片描述
代码:(这里是创建了NSMutableArray的分类,下同)

#import "NSMutableArray+Sort.h"

@implementation NSMutableArray (Sort)

/** 冒泡排序
 *  isAsc YES 表示升序(下同)
 */
- (void)sortedArrayWithBubleASC:(BOOL)isAsc{
    NSInteger len = self.count;
    for (NSInteger i=len-1; i>0; --i) {
        BOOL flag = NO;
        for (NSInteger j = 0; j < i; ++j) {
            if ((isAsc && self[j] > self[j+1]) || (!isAsc && self[j] < self[j+1])) {
                [self swapIndex1:j index2:j+1];
                flag = YES;
            }
        }
        if (!flag) {
            break;
        }
    }
}

/** 交换2个值 */
- (void)swapIndex1:(NSInteger)index1 index2:(NSInteger)index2{
    id temp = self[index1];
    self[index1] = self[index2];
    self[index2] = temp;
}
@end

快速排序:

时间复杂度:最好(越接近无序,算法越高效)O(n),最坏(越接近有序,算法越低效)O(n^2),平均O(nlogn)
空间复杂度:O(logn)
这里写图片描述
代码:

/** 快速排序 */
- (void)sortedArrayWithQuickLow:(NSInteger)low high:(NSInteger)high ASC:(BOOL)isAsc{
    NSInteger i = low, j = high;
    if (i < j) {
        id temp = self[i];
        while (i < j){
            while (i < j && ((self[j] > temp && isAsc) || (self[j] < temp && !isAsc))) --j;
            if(i<j) {self[i] = self[j]; ++i;}
            while (i < j && ((self[i] < temp && isAsc) || (self[i] > temp && !isAsc))) ++i;
            if(i<j) {self[j] = self[i]; --j;}
        }
        self[i] = temp;
        [self sortedArrayWithQuickLow:0 high:i-1 ASC:isAsc];
        [self sortedArrayWithQuickLow:i+1 high:high ASC:isAsc];
    }
}

选择类排序

堆排序

时间复杂度:O(nlogn)(最好,最坏都是这个)
空间复杂度:O(1)
可以把堆看为一颗完全二叉树,若父亲结点大于孩子结点,则这样的堆叫做大顶堆;若父亲结点小于孩子结点的值,则这样的堆叫做小顶堆。

/** 堆排序 */
- (void)sortedWithHeap:(BOOL)isAsc{
    for (NSInteger i = self.count/2 - 1; i>=0; --i) {
        [self siftWithLow:i high:self.count asc:isAsc];
    }
    for (NSInteger i = self.count - 1; i>=1; --i) {
        id temp = self[0];
        self[0] = self[i];
        self[i] = temp;
        [self siftWithLow:0 high:i asc:isAsc];
    }
}

- (void)siftWithLow:(NSInteger)low high:(NSInteger)high asc:(BOOL)isAsc{
    NSInteger left = 2 * low + 1;
    NSInteger right = left + 1;
    NSInteger lastIndex = low;
    //左子节点大的情况
    if (left < high && ((self[left] > self[lastIndex] && isAsc) || (self[left] < self[lastIndex] && !isAsc))) lastIndex = left;
    //右子节点大的情况
    if (right < high && ((self[right] > self[lastIndex] && isAsc) || (self[right] < self[lastIndex] && !isAsc))) lastIndex = right;
    //节点改变
    if (lastIndex != low) {
        //较大的节点值将交换到其所在节点的父节点
        id temp = self[low];
        self[low] = self[lastIndex];
        self[lastIndex] = temp;
        //递归遍历
        [self siftWithLow:lastIndex high:high asc:isAsc];
    }
}

简单选择排序

时间复杂度:O(n^2 )
空间复杂度:O(1)
思想:从头至尾顺序扫描序列,找出最小的一个记录,和第一个记录交换,接着从剩下的记录中继续这种选择和交换,最终使序列有序。

/** 简单选择排序 */
- (void)sortedWithSelect:(BOOL)isAsc{
    for (int i = 0; i < self.count; ++i) {
        int k = i;
        //这个循环是从无序序列中挑出一个最小的元素
        for (int j = i+1; j<self.count; ++j) {
            if ((self[k] > self[j] && isAsc) || (self[k] < self[j] && !isAsc)) {
                k = j;
            }
        }
        [self swapIndex1:i index2:k];
    }
}

插入类排序:

直接插入排序

时间复杂度: O(n^2)
空间复杂度:O(1)
稳定性:稳定

代码:

/** 直接插入排序 */
- (void)sortedWithInsert:(BOOL)isAsc{
    for (int i = 1; i<self.count; ++i) {
        id temp = self[i];
        int j = i - 1;
        for (; j >= 0 && ((temp < self[j] && isAsc) || ((temp > self[j] && !isAsc))); --j) {
            self[j+1] = self[j];
        }
        self[j+1] = temp;
    }
}

希尔排序(缩小增量排序)

时间复杂度:平均O(nlogn)
空间复杂度:O(1)
稳定性:不稳定
这里写图片描述

/** 希尔排序 */
- (void)sortedWithShellStep:(int)step asc:(BOOL)isAsc{
    for (int i = 0; i < self.count; ++i) {
        id temp = self[i];
        int j = i - step;
        for (; j >= 0 && ((temp < self[j] && isAsc) || ((temp > self[j] && !isAsc))); j -= step) {
            self[j+step] = self[j];
        }
        self[j+step] = temp;
    }
}

总结:

时间复杂度:“快些以nlogn的速度归队”(快:快速排序,些:希尔排序,归:归并排序,队:堆排序)
空间复杂度:快速排序为O(logn),其他的都是O(1)
稳定性:“心情不稳定快些选好友聊天”(快:快速排序,些:希尔排序,选:直接选择排序,堆:堆排序)
这里写图片描述

完整的DEMO见:GitHub地址

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值