OC 双向链表的实现

#import

@interface DNode : NSObject

@property (assign, nonatomic) int  data;
@property (strong, nonatomic)DNode *prev;
@property (strong, nonatomic)DNode *next;
@property (nonatomic, strong) NSString *key;
@property (nonatomic, strong) NSString *value;

- (instancetype)initWithKey:(NSString *)key
                      value:(NSString *)value;

+ (instancetype)nodeWithKey:(NSString *)key
                      value:(NSString *)value;
@end

 

 

#import "DNode.h"

@implementation DNode

- (id)initWithData:(int)data
{
    self = [super init];
    if (self) {
        self.data = data;
        self.next = nil;
        self.prev = nil;
    }
    return self;
}


- (instancetype)initWithKey:(NSString *)key
                      value:(NSString *)value
{
    if (self = [super init]) {
        _key = key;
        _value = value;
    }
    return self;
}

+ (instancetype)nodeWithKey:(NSString *)key
                      value:(NSString *)value
{
    return [[[self class] alloc] initWithKey:key value:value];
}
#pragma mark - NSCopying
- (id)copyWithZone:(nullable NSZone *)zone
{
    DNode *newNode = [[DNode allocWithZone:zone] init];
    newNode.key = self.key;
    newNode.value = self.value;
    newNode.prev = self.prev;
    newNode.next = self.next;
    return newNode;
}
@end

 

 

#import
#import "DNode.h"

@interface DoubleLink : NSObject

// 表头
@property (strong, nonatomic) DNode *headNode;
// 表尾
@property (nonatomic, strong) DNode *tailNode;
// 存放元素
@property (nonatomic, strong) NSMutableDictionary *innerMap;

- (void)insertNodeAtHead:(DNode *)node;
- (void)insertNode:(DNode *)node;
- (void)insertNode:(DNode *)newNode beforeNodeForKey:(NSString *)key;
- (void)insertNode:(DNode *)newNode afterNodeForKey:(NSString *)key;
- (void)bringNodeToHead:(DNode *)node;

- (void)readAllNode;
- (void)removeNodeForKey:(NSString *)key;
- (void)removeTailNode;

- (NSInteger)length;
- (BOOL)isEmpty;

- (DNode *)nodeForKey:(NSString *)key;
- (DNode *)headNode;
- (DNode *)tailNode;

@end

 

 

#import "DoubleLink.h"

@implementation DoubleLink

- (instancetype)init
{
    self = [super init];
    if (self) {
        
        _innerMap = [NSMutableDictionary new];
    }
    return self;
}

#pragma mark - public 头插法
- (void)insertNodeAtHead:(DNode *)node
{
    if (!node || node.key.length == 0) {
        return;
    }
    
    if ([self isNodeExists:node]) {
        return;
    }
    
    _innerMap[node.key] = node;
    
    if (_headNode) {
        node.next = _headNode;
        _headNode.prev = node;
        _headNode = node;
    } else {
        _headNode = _tailNode = node;
    }
}
#pragma mark - public 尾插法
- (void)insertNode:(DNode *)node
{
    if (!node || node.key.length == 0) {
        return;
    }
    
    if ([self isNodeExists:node]) {
        return;
    }
    
    if (!_headNode && !_tailNode) {
        _headNode = _tailNode = node;
        return;
    }
    
    _innerMap[node.key] = node;
    
    _tailNode.next = node;
    node.prev = _tailNode;
    _tailNode = node;
}

- (void)insertNode:(DNode *)newNode beforeNodeForKey:(NSString *)key
{
    if (key.length == 0 || !newNode || newNode.key.length == 0) {
        return;
    }
    
    if ([self isNodeExists:newNode]) {
        return;
    }
    
    if (!_headNode && !_tailNode) {
        _headNode = _tailNode = newNode;
        return;
    }
    
    DNode *node = _innerMap[key];
    if (node) {
        _innerMap[newNode.key] = newNode;
        if (node.prev) {
            node.prev.next = newNode;
            newNode.prev = node.prev;
        } else {
            _headNode = newNode;
        }
        node.prev = newNode;
        newNode.next = node;
    } else {
        [self insertNode:newNode]; //insert to tail
    }
    
}

- (void)insertNode:(DNode *)newNode afterNodeForKey:(NSString *)key
{
    if (key.length == 0 || !newNode || newNode.key.length == 0) {
        return;
    }
    
    if ([self isNodeExists:newNode]) {
        return;
    }
    
    if (!_headNode && !_tailNode) {
        _headNode = _tailNode = newNode;
        return;
    }
    
    DNode *node = _innerMap[key];
    if (node) {
        _innerMap[newNode.key] = newNode;
        if (node.next) {
            newNode.next = node.next;
            node.next.prev = newNode;
        } else {
            _tailNode = newNode;
        }
        newNode.prev = node;
        node.next = newNode;
    } else {
        [self insertNode:newNode]; //insert to tail
    }
}

- (void)bringNodeToHead:(DNode *)node
{
    if (!node) {
        return;
    }
    if (!_headNode && !_tailNode) {
        _headNode = _tailNode = node;
        return;
    }
    
    if ([_headNode isEqual:node]) {
        return;
    }
    
    if ([_tailNode isEqual:node]) {
        _tailNode = node.prev;
        _tailNode.next = nil;
    } else {
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }
    
    _headNode.prev = node;
    node.next = _headNode;
    node.prev = nil;
    _headNode = node;
}

- (void)removeNodeForKey:(NSString *)key
{
    if (key.length == 0) {
        return;
    }
    
    DNode *node = _innerMap[key];
    if (!node) {
        return;
    }
    
    [_innerMap removeObjectForKey:key];
    
    if ([_headNode isEqual:node]) {
        _headNode = node.next;
    } else if ([_tailNode isEqual:node]) {
        _tailNode = node.prev;
    }
    
    node.prev.next = node.next;
    node.next.prev = node.prev;
    
}

- (void)removeTailNode
{
    if (!_tailNode || _tailNode.key.length == 0) {
        return;
    }
    
    [_innerMap removeObjectForKey:_tailNode.key];
    if (_headNode == _tailNode) {
        _headNode = _tailNode = nil;
        return;
    }
    
    _tailNode = _tailNode.prev;
    _tailNode.next = nil;
}
- (DNode *)nodeForKey:(NSString *)key
{
    if (key.length == 0) {
        return nil;
    }
    DNode *node = _innerMap[key];
    return node;
}

- (DNode *)headNode
{
    return _headNode;
}

- (DNode *)tailNode
{
    return _tailNode;
}

- (void)readAllNode
{
    DNode *node = _headNode;
    while (node) {
        NSLog(@"node key -- %@, node value -- %@", node.key, node.value);
        node = node.next;
    }
}
- (NSInteger)length
{
    NSInteger _len = 0;
    for (DNode *node = _headNode; node; node = node.next) {
        _len ++;
    }
    return _len;
}

- (BOOL)isEmpty
{
    return _headNode == nil;
}

#pragma mark - private
- (BOOL)isNodeExists:(DNode *)node
{
    DNode *tmpNode = _headNode;
    while (tmpNode) {
        if ([tmpNode isEqual:node]) {
            return YES;
        }
        tmpNode = tmpNode.next;
    }
    return false;
}
@end

你可能感兴趣的:(OC 双向链表的实现)