iPhone挿入ソート

アルゴリズムを目で見て考える、まずは挿入ソート。という感じでiPhoneアプリのサンプルコードを描いてみます。

動かすとこんな感じです

サンプルコード

#import “ViewController.h”

@interface ViewController ()

@property (nonatomic, strong) NSMutableArray *numbers;

@property (nonatomic, strong) NSMutableArray *labels;

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    [self createNumbers];

    [self showNumbers];

    [self createButtons];

}

– (void)createNumbers

{

    NSMutableArray *seed = [[@”1 2 3 4 5 6 7 8 9″ componentsSeparatedByString:@” “] mutableCopy];

    self.numbers = [NSMutableArray array];

    for (int i=0; i<5; i++) {

        NSString *s = [seed objectAtIndex:arc4random() % (seed.count)];

        [seed removeObject:s];

        [self.numbers addObject:@(s.intValue)];

    }

}

– (void)showNumbers

{

    self.labels = [NSMutableArray array];

    

    for (int i=0; i<self.numbers.count; i++ ) {

        float x = i * 50 + 40;

        float y = 100;

        

        NSNumber *number =self.numbers[i];

        UILabel *numLabel = [[UILabel alloc] initWithFrame:CGRectMake(x, y, 40, 40)];

        numLabel.text = [@(number.intValue) stringValue];

        numLabel.font = [UIFont fontWithName:@”AmericanTypewriter” size:30];

        numLabel.textColor = [UIColor blueColor];

        numLabel.textAlignment = NSTextAlignmentCenter;

        numLabel.layer.borderColor = [UIColor blueColor].CGColor;

        numLabel.layer.borderWidth = 2;

        [self.view addSubview:numLabel];

        

        numLabel.tag = i + 1;

        

        [self.labels addObject:numLabel];

    }

}

– (void)createButtons

{

    UIButton *startButton = [UIButton buttonWithType:UIButtonTypeSystem];

    [startButton setTitle:@”start” forState:UIControlStateNormal];

    [startButton sizeToFit];

    startButton.center = CGPointMake(240, 400);

    [self.view addSubview:startButton];

    

    [startButton addTarget:self action:@selector(startSort) forControlEvents:UIControlEventTouchUpInside];

    

    UIButton *ansButton = [UIButton buttonWithType:UIButtonTypeSystem];

    [ansButton setTitle:@”answer” forState:UIControlStateNormal];

    [ansButton sizeToFit];

    ansButton.center = CGPointMake(80, 400);

    [self.view addSubview:ansButton];

    

    [ansButton addTarget:self action:@selector(showAnswer) forControlEvents:UIControlEventTouchUpInside];

}

– (void)startSort

{

    [self sortAtIndex:1];

}

– (void)sortAtIndex:(int)j

{

    UILabel *number = (UILabel*)[self.view viewWithTag:j];

    

    [UIView animateWithDuration:0.5 animations:^{

        number.center = CGPointMake(300, 250);

    } completion:^(BOOL finished) {

        

        int i=j-2;

        while (i >= 0 && [[self.labels[i] text] intValue] > [number.text intValue])

        {

            UILabel *l = (UILabel*)self.labels[i];

            [UIView animateWithDuration:0.5 animations:^{

                l.center = CGPointMake(l.center.x, l.center.y + 50);

            } completion:^(BOOL finished) {

                [UIView animateWithDuration:0.5 animations:^{

                    l.center = CGPointMake(l.center.x + 50, l.center.y50);

                }];

            }];

            self.labels[i+1] = self.labels[i];

            i = i – 1;

        }

        self.labels[i+1] = number;

        

        [UIView animateWithDuration:0.5 animations:^{

            if (i == j-2) {

                number.center = CGPointMake(j * 50 + 10, 250);

            } else {

                number.center = CGPointMake((i+2) * 50 + 10, 250);

            }

        }];

        

    }];

    

    if (j < self.numbers.count) {

        double delayInSeconds = 1.2;

        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));

        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){

            [self sortAtIndex:j+1];

        });

    }

}

– (void)showAnswer

{

    UILabel *answerLabel = [[UILabel alloc] init];

    answerLabel.text = [[self insertionSort:self.numbers] componentsJoinedByString:@””];

    [answerLabel sizeToFit];

    answerLabel.center = CGPointMake(160, 350);

    [self.view addSubview:answerLabel];

    

    [self performSelector:@selector(reset) withObject:nil afterDelay:3.0];

}

– (void)reset

{

    [self.view.subviews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

        [obj removeFromSuperview];

    }];

    

    

    [self createNumbers];

    [self showNumbers];

    [self createButtons];

}

– (NSArray*)insertionSort:(NSArray*)array

{

    NSMutableArray *a = [array mutableCopy];

    for (int j=1; j < a.count; j++) {

        NSNumber *key = a[j];

        

        int i = j-1;

        while (i >= 0 && [a[i] intValue] > [key intValue]) {

            a[i + 1] = a[i];

            i = i – 1;

        }

        a[i + 1] = key;

    }

    

    return a;

}

@end