排序
2016-08-27 本文已影响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