美文网首页
浅谈动态数组&数据结构(object-C)

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

作者: topCui | 来源:发表于2019-04-25 15:08 被阅读0次

什么是数据结构?

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

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

实现代码如下:

#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)

    什么是数据结构? 接下来我们手写一个动态数组 首先动态数组的接口设计如下: 实现代码如下: #import ...

  • 5 数组 Swift/Object-C ——《Swift3.0从

    5 数组 Swift/Object-C ——《Swift3.0从入门到出家》 数组 Swift中数组是一种数据结构...

  • ArrayList和LinkList的区别

    ArrayList:是Array的数据结构,Array是动态数组,是对List接口的实现,他是数组队列,相当于动态...

  • 8.LinkedList

    ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。LinkedList不支...

  • 2020-07-16

    1、看完谷粒商城31 2、恋上数据结构之动态数组

  • Redis源码

    一、Redis数据结构: SDS SDS(动态字符串)包含字符数组buf[],字符数组现有长度len,字符数组分配...

  • 数据结构与算法二(动态数组)

    目录一、什么是数据结构?二、线性表2.1 数组(Array)2.2 动态数组(Dynamic Array)接口设计...

  • ArrayList and LinkedList

    ArrayList and LinkedList ArrayList是实现了基于动态数组的数据结构,LinkedL...

  • ARTS-第二周

    Algorithm 从基础开始手写动态数组 git代码地址 数组定义:数组(Array)是一种线性表数据结构。它用...

  • 链表

    数组和链表的对比 前面提到的动态数组,栈和队列,底层依托的都是静态的数组这节涉及到的链表才是真正的动态数据结构 数...

网友评论

      本文标题:浅谈动态数组&数据结构(object-C)

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