浅谈动态数组&数据结构(object-C)

什么是数据结构?





接下来我们手写一个动态数组

首先动态数组的接口设计如下:


实现代码如下:

#import

                    //修饰属性的类型,如果一个类属性的类型并不确定,那么就可以通过创建对象的时候来控制类的类型

@interface ArrayList  <__covariant objectType> : NSObject

//元素数量

@property (readonly) NSUInteger count;

@property (nullable, nonatomic, readonly) id firstObject;

@property (nullable, nonatomic, readonly) id lastObject;

/**

默认初始化

@return 实例对象

*/

+ (instancetype)arrary;

/**

类方法初始化

@param numItems 初始数量

@return 实例对象

*/

+ (instancetype)arrayWithCapacity:(NSUInteger)numItems;

/**

对象方法初始化

@param numItems 初始数量

@return 实例对象

*/

- (instancetype)initWithCapacity:(NSUInteger)numItems;

/**

取某个位置的元素

@param numItems 参数

*/

- (objectType)objectAtIndex:(NSUInteger)numItems;

/**

查看某个元素的下标

@param anObject 某个元素

@return index

*/

- (objectType)indexOfobject:(objectType)anObject;

/**

是否包含某个元素

@param anObject 某个元素

@return 是否包含

*/

- (BOOL)containsObject:(objectType)anObject;

/**

添加元素

@param anObject 要添加的元素

*/

- (void)addObject:(objectType)anObject;

/**

插入某个元素

@param anObject 某个元素

@param index 要插入的下标

*/

- (void)insertObject:(objectType)anObject atIndex:(NSUInteger)index;

/**

替换某个位置的元素

@param index 要替换的位置

@param anObject 要替换的参数元素

*/

- (void)replaceObjectAtIndex:(objectType)index withObject:(objectType)anObject;

/**

删除所有元素

*/

- (void)removeAllObjects;

/**

删除最后一个元素

*/

- (void)removeLastObjects;

/**

删除某个下标的元素

@param index index

*/

- (void)removeObjectAtIndex:(NSUInteger)index;

/**

删除某个元素

@param anObject 某个元素

*/

- (void)removeObject:(objectType)anObject;

@end

#import "ArrayList.h"

static const int DEFAULT_CAPACITY = 10;

static const int ELEMENT_NOT_FOUND = -1;

typedef void* AnyObject;

@interface ArrayList  ()

{

    AnyObject *_array; ///<本来是想用 objectType ,但是calloc的去接收的时候会出野指针错误,另外作用域只到interface>

    NSInteger _size;

    NSInteger _capacity;

}

@end

@implementation ArrayList

/**

默认初始化

@return 实例对象

*/

+ (instancetype)arrary{

  return  [[self alloc] initWithCapacity:DEFAULT_CAPACITY];

}

/**

类方法初始化

@param numItems 初始数量

@return 实例对象

*/

+ (instancetype)arrayWithCapacity:(NSUInteger)numItems{

    return  [[self alloc] initWithCapacity:numItems];

}

/**

对象方法初始化

@param numItems 初始数量

@return 实例对象

*/

- (instancetype)initWithCapacity:(NSUInteger)numItems{

    _capacity = numItems < DEFAULT_CAPACITY ? DEFAULT_CAPACITY : numItems;

    _array = (calloc(numItems, sizeof(AnyObject)));

    _size = 0;

    return self;

}

/**

取某个位置的元素

@param numItems 参数

*/

- (AnyObject)objectAtIndex:(NSUInteger )numItems{

    if (numItems >= _size) {

        @throw [NSException exceptionWithName:@"Array is out of bounds" reason:@"out of bounds" userInfo:nil];

        return nil;

    }

    return _array[numItems];

}

/**

查看某个元素的下标

@param anObject 某个元素

@return index

*/

- (AnyObject)indexOfobject:(id)anObject{

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

        if ([anObject isEqual:anObject]){

            return i;

        }

    }

    return ELEMENT_NOT_FOUND;

}

/**

是否包含某个元素

@param anObject 某个元素

@return 是否包含

*/

- (BOOL)containsObject:(AnyObject)anObject{

    return [self indexOfobject:(__bridge id)(anObject)] != ELEMENT_NOT_FOUND;

}

/**

添加元素

@param anObject 要添加的元素

*/

- (void)addObject:(id)anObject{

    [self insertObject:(anObject) atIndex:_size];

}

- (NSUInteger)count{

    return _size;

}

- (void)insertObject:(id)anObject atIndex:(NSUInteger)index{

        [self ensureCapacity:_size + 1];

        ///交换索引位置

        if (self.count > 0 ) {

            for(NSInteger i = _size - 1 ; i >= index ; i--)

            _array[i + 1] = _array[i];

        }

        self->_array[index] = (__bridge_retained AnyObject)(anObject);

        _size++;

}

/**

替换某个位置的元素

@param index 要替换的位置

@param anObject 要替换的参数元素

*/

- (void)replaceObjectAtIndex:(NSInteger)index withObject:(AnyObject)anObject{

    _array[index] = anObject;

}

/**

删除所有元素

*/

- (void)removeAllObjects{

    for (int i = 0; i < _size - 1; i++) {

        _array[i] = NULL;

    }

    [self resetArray];

}

/**

数组重置

*/

- (void) resetArray {

    _size = 0;

//    if (_array != NULL)

//    _array[_size] = NULL;

//    free(_array);

//    _capacity = DEFAULT_CAPACITY;

//    _array = calloc(_capacity, sizeof(AnyObject));

}

- (void)removeObjectAtIndex:(NSUInteger)index{

    if (index >= _size) {

        @throw [NSException exceptionWithName:@"Array is out of bounds" reason:@"out of bounds" userInfo:nil];

    }

    for (int i = index + 1; i < _size; i++) {

      _array[i -1 ] = _array[i];

    }

    _size--;

    _array[_size] = NULL;

    if (_size == _capacity / 2) {

        NSInteger newCapacity = _capacity / 2;

        AnyObject *newArr = (calloc(newCapacity , sizeof(AnyObject)));

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

            newArr[i] = _array[i];

        }

        _array = newArr;

        _capacity = newCapacity;

        NSLog(@"新容量 %zd",newCapacity);

    }

}

/**

删除某个元素

@param anObject 某个元素

*/

- (void)removeObject:(id)anObject{

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

        if ([anObject  isEqual:(__bridge id)(_array[i])]) {

            [self removeObjectAtIndex:i];

        }

    }

}

/**

扩容

*/

- (void)ensureCapacity:(NSInteger)capacity{

    if (capacity <= _capacity) {

        return;

    }

    NSInteger newCapacity = _capacity + (_capacity >> 1);

    AnyObject *newArr = (calloc(newCapacity , sizeof(AnyObject)));

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

        newArr[i] = _array[i];

    }

    _array = newArr;

    _capacity = newCapacity;

    NSLog(@"新容量 %zd",newCapacity);

}

- (NSString *)description {

    NSMutableString *string = [NSMutableString stringWithFormat:@"\nArrayList %p : [ \n" ,self];

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

        AnyObject obj = _array[i];

        [string appendFormat:@"%@",(__bridge id)obj];

        if (i<_size-1) {

            [string appendString:@" , \n"];

        }

    }

    [string appendString:@"\n]\n"];

    return string;

}

@end



在写动态数组的过程中发现几个问题。

1.范型作用域只有@interface

2.free()函数并没有将数组中的元素释放。。。

3.扩容realloc是一个提高性能的方向,malloc,calloc,realloc都能实现这个功能。。

你可能感兴趣的:(浅谈动态数组&数据结构(object-C))