排序

作者: 永恒守护__刘鹏辉 | 来源:发表于2016-08-27 17:40 被阅读24次
    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
    

    相关文章

      网友评论

          本文标题:排序

          本文链接:https://www.haomeiwen.com/subject/siktettx.html