美文网首页iOS 开发每天分享优质文章
数据结构与算法之双向链表(3.3)

数据结构与算法之双向链表(3.3)

作者: 路飞_Luck | 来源:发表于2019-05-05 23:35 被阅读47次
    目录
    • 双向链表简介
    • 双向链表重要方法讲解
    • 实战检测
    • 双向链表,单向链表性能对比
    一 双向链表简介
    双向链表.png

    双向链表-只有一个元素

    双向链表-一个元素.png
    二 核心方法代码介绍
    2.1 双向链表 node:方法
    ///  获取index位置对应的节点对象
    - (LinkNode *)node:(NSUInteger)index {
        if ([self rangeCheck:index]) {
            return nil;
        }
        
        if (index < self.size * 0.5) {
            LinkNode *node = _first;
            for (int i = 0; i < index; i++) {
                node = node.next;
            }
            return node;
        } else {
            LinkNode *node = _last;
            for (int i = self.size - 1; i > index; i--) {
                node = node.prev;
            }
            return node;
        }
    }
    
    2.2 双向链表 add:element方法
    /// 在索引为index处插入元素值为element的节点
    - (void)add:(NSUInteger)index element:(id)element {
        if (index == self.size) {   // 往最后面添加元素
            LinkNode *oldLast = _last;
            _last = [[LinkNode alloc] initWithPrev:oldLast element:element next:_first];
            if (oldLast == nil) {   // 这是链表添加的第一个元素
                _first = _last;
                _first.next = _first;
                _first.prev = _first;
            } else {    // 往一个非空链表插入新节点
                oldLast.next = _last;
                _first.prev = _last;
            }
        } else {    // 在中间插入节点
            LinkNode *next = [self node:index]; // 先获取要插入位置上的节点
            LinkNode *prev = next.prev;
            LinkNode *node = [[LinkNode alloc] initWithPrev:prev element:element next:next];
            next.prev = node;
            prev.next  = node;
            
            if (next == _first) {   // 插入到第一个位置
                _first = node;
            }
        }
        self.size++;
    }
    
    add.png
    2.3 双向链表 remove:方法
    // 删除索引为index的节点
    - (id)remove:(NSUInteger)index {
        if ([self rangeCheck:index]) {
            return nil;
        }
        return [self removeLinkNode:[self node:index]];
    }
    
    // 删除node节点
    - (id)removeLinkNode:(LinkNode *)node {
        if (self.size == 1) {
            _first = nil;
            _last = nil;
        } else {
            LinkNode *prev = node.prev;
            LinkNode *next = node.next;
            prev.next = next;
            next.prev = prev;
            
            if (node == _first) {   // idnex == 0
                _first = next;
            }
            
            if (node == _last) {    // index == size
                _last = prev;
            }
        }
        
        self.size--;
        return node.element;
    }
    
    remove.png

    更多方法介绍请看文末项目链接地址

    三 实战检测
    LinkedList *list = [[LinkedList alloc] init];
    self.list = list;
    [list add:@11];
    [list add:@22];
    [list add:@33];
    [list add:@44]; // [11, 22, 33, 44]
    
    [list add:0 element:@55];   // [55, 11, 22, 33, 44]
    [list add:2 element:@66];   // [55, 11, 66, 22, 33, 44]
    [list add:list.size  element:@77];  // [55, 11, 66, 22, 33, 44, 77]
    
    [list remove:0];    // size = 6 [11, 66, 22, 33, 44, 77]
    [list remove:2];    // size = 5 [11, 66, 33, 44, 77]
    [list remove:list.size - 1];    // size = 4 [11, 66, 33, 44]
    
    NSLog(@"%lu",(unsigned long)[list indexOf:@44]);    // 3
    NSLog(@"%lu",(unsigned long)[list indexOf:@22]);    // NSNotFound
    NSLog(@"%lu",(unsigned long)[list contains:@33]);   // true
    NSLog(@"%@",[list get:0]);  // 11
    NSLog(@"%@",[list get:1]);  // 66
    NSLog(@"%@",[list get:list.size - 1]);  // 4
    
    NSLog(@"%@",list.description);
    

    右侧注释即为打印结果

    四 性能对比
    4.1 双向链表 vs 单向链表

    粗略对比一下删除的操作数量

    • 单向链表
    单向链表.png
    • 双向链表
    双向链表.png

    操作数量缩减了近一半

    4.2 双向链表 vs 动态数组
    • 动态数组:开辟,销毁内存空间的次数相对少,但可能造成内存空间浪费(可以通过缩容解决)
    • 双向链表:开辟,销毁内存空间的次数相对多,但不会造成内存空间的浪费

    如何选择?
    1.如果频繁在尾部进行添加删除操作,动态数组双向链表均可以选择
    2.如果频繁在头部进行添加删除操作,建议选择使用双向链表
    3.如果有频繁的在任意位置进行添加删除操作,建议选择使用双向链表
    4.如果有频繁的查询操作(随机访问操作),建议选择使用动态数组

    有了双向链表,单向链表是否没有任何用处了?

    • 并非如此,在哈希表的设计中使用了单链表

    本文会持续更新中,更多精彩内容敬请期待。


    本文参考 MJ老师的 恋上数据结构与算法


    本人技术水平有限,如有错误欢迎指正。
    书写整理不易,您的打赏点赞是对我最大的支持和鼓励,欢迎点赞打赏。


    项目连接链接 - 05_DoubleLinkList

    相关文章

      网友评论

        本文标题:数据结构与算法之双向链表(3.3)

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