排序

demo截图

--------------------------ViewController.m--------------------------

#import "ViewController.h"

#import "NSString+Compare.h"
#import "NSNumber+Compare.h"

@interface ViewController ()

@property (nonatomic, strong) NSArray *arr;
@property (nonatomic, strong) NSMutableArray *mutArr;
@property (nonatomic, strong) NSArray *strArr;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.arr = @[@3, @6, @0, @9, @1];
    self.mutArr = [NSMutableArray arrayWithObjects:@3, @6, @0, @9, @1, nil];
    self.strArr = [NSArray arrayWithObjects:@"Dr", @"Rfgh", @"A", @"Vjkk", @"B", nil];
    
//    [self maopao1];
//    [self maopao2];
//    [self maopao3];
//    [self maopao4];
//    [self maopao5];
//    [self maopao6];
//    [self maopao7];
    
    /*
    [self quickStart:0 end:(int)self.mutArr.count - 1];
    NSLog(@"mutArr = %@", self.mutArr);
    */
    
//    [self insert];
//    [self shell];
//    [self descriptors];
//    [self selector];
    [self comparator];
}

#pragma mark --------------- 冒泡排序 ---------------------

// 从最前面的两个元素开始比较
- (void)maopao1
{
    for (int i = 0; i < self.mutArr.count - 1; i++)
    {
        for (int j = 0; j < self.mutArr.count - 1 - i; j++)
        {
            if (self.mutArr[j] > self.mutArr[j+1])
            {
                /*
                id temp = self.mutArr[j];
                self.mutArr[j] = self.mutArr[j+1];
                self.mutArr[j+1] = temp;
                */
                
                // 交换两个对应下标的值
                [self.mutArr exchangeObjectAtIndex:j withObjectAtIndex:j+1];
            }
        }
    }
    NSLog(@"mutArr = %@", self.mutArr);
}
// 从最后的两个元素开始比较
- (void)maopao2
{
    for (int i = 0; i < self.mutArr.count - 1; i++)
    {
        for (int j = (int)self.mutArr.count - 1; j > i; j--)
        {
            if (self.mutArr[j] > self.mutArr[j-1])
            {
                [self.mutArr exchangeObjectAtIndex:j withObjectAtIndex:j-1];
            }
        }
    }
    NSLog(@"mutArr = %@", self.mutArr);
}
// 第一个元素依次和后面的元素比较(从前往后)
- (void)maopao3
{
    for (int i = 0; i < self.mutArr.count - 1; i++)
    {
        for (int j = i + 1; j < self.mutArr.count; j++)
        {
            if (self.mutArr[i] > self.mutArr[j])
            {
                [self.mutArr exchangeObjectAtIndex:i withObjectAtIndex:j];
            }
        }
    }
    NSLog(@"mutArr = %@", self.mutArr);
}
// 第一个元素依次和后面的元素比较(从后往前)
- (void)maopao4
{
    for (int i = 0; i < self.mutArr.count - 1; i++)
    {
        for (int j = (int)self.mutArr.count - 1; j > i; j--)
        {
            if (self.mutArr[i] > self.mutArr[j])
            {
                [self.mutArr exchangeObjectAtIndex:i withObjectAtIndex:j];
            }
        }
    }
    NSLog(@"mutArr = %@", self.mutArr);
}
// 优化,用一个标志位来避免不必要的循环,已经有序的话就不用继续循环了
- (void)maopao5
{
    for (int i = 0; i < self.mutArr.count - 1; i++)
    {
        BOOL flag = NO;
        for (int j = 0; j < self.mutArr.count - 1 - i; j++)
        {
            if (self.mutArr[j] > self.mutArr[j+1])
            {
                // 交换两个对应下标的值
                [self.mutArr exchangeObjectAtIndex:j withObjectAtIndex:j+1];
                flag = YES;
            }
        }
        // 上一个循环比较结束而没有发生交换,但是每两个相邻元素都比较过了,说明已经有序
        if (!flag)
        {
            // 跳出循环
            break;
        }
    }
    NSLog(@"mutArr = %@", self.mutArr);
}
// 优化,省下许多无用的交换
- (void)maopao6
{
    for (int i = 0; i < self.mutArr.count - 1; i++)
    {
        int min = i;
        for (int j = i + 1; j < self.mutArr.count; j++)
        {
            if (self.mutArr[min] > self.mutArr[j])
            {
                // min总是指向最小元素
                min = j;
            }
        }
        // 当min不等于i时才交换值,否则self.mutArr[i]即为最小
        if (i != min)
        {
            [self.mutArr exchangeObjectAtIndex:i withObjectAtIndex:min];
        }
    }
    NSLog(@"mutArr = %@", self.mutArr);
}
// 优化,记录下每趟比较交换值的位置,该位置之后都是有序的,以后就不用比较了
- (void)maopao7
{
    int exchange = (int)self.mutArr.count - 1;
    while (exchange)
    {
        // 记录下发生数据交换的位置
        int bound = exchange;
        // 设置初始值
        exchange = 0;
        for (int i = 0; i < bound; i++)
        {
            if (self.mutArr[i] > self.mutArr[i+1])
            {
                [self.mutArr exchangeObjectAtIndex:i withObjectAtIndex:i+1];
                
                exchange = i;
            }
        }
    }
    NSLog(@"mutArr = %@", self.mutArr);
}

#pragma mark --------------------- 快速法 -----------------------

// 用到两个参数:数组起始元素下标i,要排序数组结束元素下标j。首先选一个数组元素(一般为中间元素)作为参照,把比它小的元素放到它的左边,比它大的放在右边。然后运用递归,在将它左,右两个子数组排序,最后完成整个数组的排序。
- (void)quickStart:(int)i end:(int)j
{
    int m = i;
    int n = j;
    NSNumber *k = self.mutArr[(i+j)/2];
    do
    {
        while (self.mutArr[m] < k && m < j)
        {
            m++;
        }
        while (self.mutArr[n] > k && n > i)
        {
            n--;
        }
        if (m <= n)
        {
            [self.mutArr exchangeObjectAtIndex:m withObjectAtIndex:n];
            m++;
            n--;
        }
    } while (m <= n);
    
    if (m < j)
    {
        [self quickStart:m end:j];
    }
    if (n > i)
    {
        [self quickStart:i end:n];
    }
}

#pragma mark --------------------- 插入法 -----------------------

- (void)insert
{
    NSNumber *temp;
    int i, j;
    // 从第二个元素开始插入
    for (i = 1; i < self.mutArr.count; i++)
    {
        // temp为要插入的元素
        temp = self.mutArr[i];
        j = i - 1;
        while (j >= 0 && temp > self.mutArr[j])
        {
            // 数组元素向后移
            self.mutArr[j+1] = self.mutArr[j];
            j--;
        }
        // 插入
        self.mutArr[j+1] = temp;
    }
    NSLog(@"mutArr = %@", self.mutArr);
}

#pragma mark --------------------- shell法 -----------------------

// 首先把相距k(k>=1)的那几个元素排好序,再缩小k值(一般取其一半),再排序,直到k=1时完成排序
- (void)shell
{
    NSNumber *temp;
    int i,j;
    int k = (int)self.mutArr.count / 2;
    while (k >= 1)
    {
        for (i = k; i < self.mutArr.count; i++)
        {
            temp = self.mutArr[i];
            j = i - k;
            while (j >= 0 && temp < self.mutArr[j])
            {
                self.mutArr[j+k] = self.mutArr[j];
                j-=k;
            }
            self.mutArr[j+k] = temp;
        }
        // k = k / 2
        k/=2;
    }
    NSLog(@"mutArr = %@", self.mutArr);
}

#pragma mark --------------- UsingDescriptors -----------------

- (void)descriptors
{
    /*
     NSSortDescriptor(排序描述)
     它由以下参数组成:
     键:对于一个给定的集合,对应值的键位将对集合中的每个对象进行排序;
     升序:指定一个集合是否按照升序(YES)还是降序(NO)进行排序的布尔值.
     */
     // @"self":这里代表的是可以直接进行排序,如果对一个类的属性进行排序,那么我们就直接@"属性名"即可,后边YES代表的是升序,NO代表的是降序
     NSSortDescriptor *arraySortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"self" ascending:YES];
     
     // sortedArrayUsingDescriptors:方法的返回值是NSArray
     NSArray *sortedArr = [self.arr sortedArrayUsingDescriptors:[NSArray arrayWithObjects:arraySortDescriptor, nil]];
     NSLog(@"sortedArr = %@", sortedArr);
     
     // sortUsingDescriptors:方法是对自身进行排序操作,返回值为空
     [self.mutArr sortUsingDescriptors:[NSArray arrayWithObjects:arraySortDescriptor, nil]];
     NSLog(@"mutArr = %@", self.mutArr);
}

#pragma mark ---------------- UsingSelector -------------------

- (void)selector
{
    /*
    // compare:默认是指一个升序的排序
    // sortedArrayUsingSelector:方法的返回值是NSArray
    NSArray *sortedArr = [self.arr sortedArrayUsingSelector:@selector(compare:)];
    NSLog(@"sortedArr = %@", sortedArr);
    
    // sortUsingSelector:方法是对自身进行排序操作,返回值为空
    [self.mutArr sortUsingSelector:@selector(compare:)];
    NSLog(@"mutArr = %@", self.mutArr);
    */
    
    // 方法选择器里的方法也可以自定义
    // 对于可变数组,如果数组元素是字符串,则数组调用sortUsingSelector:方法,对其自身进行排序操作
    NSArray *strArr = [self.strArr sortedArrayUsingSelector:@selector(compareByString:)];
    NSLog(@"strArr = %@", strArr);
    
    NSArray *numArr = [self.arr sortedArrayUsingSelector:@selector(compareByNum:)];
    NSLog(@"numArr = %@", numArr);
    
    [self.mutArr sortUsingSelector:@selector(compareByNum:)];
    NSLog(@"mutArr = %@", self.mutArr);
}

#pragma mark ---------------- UsingComparator -----------------

- (void)comparator
{
    // 对不可变数组也是用这个方法
    NSArray *sortedArr = [self.arr sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2)
    {
        if (obj1 > obj2)
        {
            return NSOrderedDescending;
        }
        else
        {
            return NSOrderedAscending;
        }
    }];
    NSLog(@"sortedArr = %@", sortedArr);
     
    
    // 如果数组元素是字符串
    NSArray *sortedStrArr = [self.strArr sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2)
    {
        // 交换obj1和obj2的位置可以改变升降序
        return [obj1 compare:obj2 options:NSNumericSearch];
    }];
    NSLog(@"sortedStrArr = %@", sortedStrArr);
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
@end

--------------------------NSString+Compare.h--------------------------

#import <Foundation/Foundation.h>

@interface NSString (Compare)

- (NSComparisonResult) compareByString:(NSString *)str;

@end

--------------------------NSString+Compare.m--------------------------

#import "NSString+Compare.h"

@implementation NSString (Compare)

- (NSComparisonResult) compareByString:(NSString *)str
{
    // compare 默认是升序排序,但是如果想要降序那么加 - (负号)
    return [self compare:str];
//    return -[self compare:str];
}

@end

--------------------------NSNumber+Compare.h--------------------------

#import <Foundation/Foundation.h>

@interface NSNumber (Compare)

- (NSComparisonResult) compareByNum:(NSNumber *)num;

@end

--------------------------NSNumber+Compare.m--------------------------

#import "NSNumber+Compare.h"

@implementation NSNumber (Compare)

// 降序
- (NSComparisonResult) compareByNum:(NSNumber *)num
{
    if(self > num)
    {
        return NSOrderedAscending;
    }
    else if(self < num)
    {
        return NSOrderedDescending;
    }
    return NSOrderedSame;
}

@end

推荐阅读更多精彩内容

  • 一、数组排序 简单排序(sortedArrayUsingSelector:)如果只是对字符串的排序,可以利用sor...
    奋斗的蜗牛阅读 1,518评论 0 2
  • 排序规则描述类: NSSortDescriptor NSSortDescriptor来指定排序规则, 对集合等进行...
    SkyMing一C阅读 4,419评论 3 9
  • 1.使用NSSortDescriptor对象进行数组排序 //创建一个数组NSArray *array = @[@...
    toobai阅读 1,252评论 0 0
  • 又到了开学的日子,女儿开学后要去高中部上课,从地铁口出来要走20多分钟,于是女儿决定骑共享单车,鉴于之前...
    桂花树下阅读 73评论 0 0
  • 这只暴烈的二手猫 是我从伯父家的玻璃钢架下救活过来的 当时它正嗥叫于丧母之痛 这个出生还不到三个月的小家伙 眼睛还...
    隔着玻璃亲嘴阅读 75评论 4 4