• golang实现常用集合原理介绍


    golang本身对常用集合的封装还是比较少的,主要有数组(切片)、双向链表、堆等。在工作中可能用到其他常用的集合,于是我自己对常用的集合进行了封装,并对原理做了简单介绍,代码库地址:https://github.com/chentaihan/container,代码都是经过测试的,欢迎下载使用,反馈的问题我会第一时间修复

     

    ArraySort排序数组

    ArraySort使用数组保存数据,新增的时候通过类似二分查找找到插入位置,插入位置后面的数据往后移动一位,插入新元素,查找就是二分查找,删除就是通过二分查找找到对应的元素,之后的元素都向前移动一位。时间复杂度如下:

    功能时间复杂度
    新增 O(n)
    删除 O(n)
    查找 O(logn)

    LinkList单链表

    通过链表头指针和链表尾两个指针将所有元素链接在一起,可以快速的在表头和表尾插入元素,删除和查找都是遍历链表,查找对应的元素,删除还需要改变指针指向。时间复杂度如下:

    功能时间复杂度
    新增 O(1)
    删除 O(n)
    查找 O(n)

    Queue循环队列

    队列先进先出,循环队列采用数组保存元素,以循环的方式在数组中添加元素,当数组写满之后自动扩容,元素个数小于1M时二倍扩容,大于等于1M时每次加1M,删除元素的时候需要将对应的位置赋值为空指针,方便被删除的元素被回收。时间复杂度如下:

    功能时间复杂度
    进队列 O(1)
    出队列 O(1)

    QueueLink链表队列

    队列先进先出,实现和单链表类似,进栈是在表尾添加元素,出栈就是表头出栈,即表头指向表头的下一个元素,相对数组实现的循环队列,链表队列不存在扩容的问题,但每个元素多了一个指针。时间复杂度如下:

    功能时间复杂度
    进队列 O(1)
    出队列 O(1)

    PriorityQueue优先级队列

    优先级队列采用小堆实现,小堆采用数组保存数据,按照完全二叉树的方式操作数据,每个节点的值都小于等于左右子节点的值,保证了每次出队的都是最小值,即按照顺序出队。

    时间复杂度如下:

    功能时间复杂度
    进队列 O(logn)
    出队列 O(logn)

    Stack栈

    栈先进后出,采用数组保存元素,每次进栈的是栈顶元素,出栈的也是栈顶元素,当数组写满之后自动扩容,元素个数小于1M时二倍扩容,大于等于1M时每次加1M。时间复杂度如下:

    功能时间复杂度
    进栈 O(1)
    出栈 O(1)

    StackLink链表栈

    队列先进先出,采用单链表保存数据,进栈是在表头添加元素,出栈就是表头出栈,即表头指向表头的下一个元素,相对数组实现的循环队列,链表队列不存在扩容的问题,但每个元素多了一个指针。时间复杂度如下:

    功能时间复杂度
    进栈 O(1)
    出栈 O(1)

    Map

    对golang的map简单封装,增加了一些方法。对于golang中map的实现原理请看我的这篇文章:https://www.cnblogs.com/hlxs/p/10408961.html,时间复杂度如下:

    功能时间复杂度
    新增 O(1)
    修改 O(1)
    查询 O(1)
    删除 O(1)

    MapSync同步map

    就是map+读写锁,时间复杂度和map一样

    LinkMap

    双向链表 + map,双向链表按照顺序保存新增的元素,可以按照添加的顺序遍历数据,增删改查时间复杂度都和map一样

    TreeMap

    通过二叉搜索树保存数据,后面会详细介绍二叉搜索树,使用二叉搜索树就不存在扩容的问题,hashmap则存在扩容的问题,时间复杂度如下:

    功能时间复杂度
    新增 O(logn)
    修改 O(logn)
    查询 O(logn)
    删除 O(logn)

    LRU

    lru的实现原理其实和LinkMap几乎一样,只不过lru在修改或是查询的时候都会将被访问的元素移到链表的表头,表尾的数据是最先被淘汰的,时间复杂度如下:

    功能时间复杂度
    新增 O(1)
    修改 O(1)
    查询 O(1)
    删除 O(1)

    BinaryTree二叉搜索树

    提供二叉搜索树的增删改查功能,删除相对复杂点,时间复杂度如下:

    功能时间复杂度
    新增 O(logn)
    修改 O(logn)
    查询 O(logn)
    删除 O(logn)

    heap大堆

    堆是对golang本身container/heap的简单封装,大堆中某个节点的值总是不大于其父节点的值;堆总是一棵完全二叉树。,时间复杂度如下:

    功能时间复杂度
    新增 O(logn)
    查询 O(n)
    删除 O(logn)

    heap小堆

    堆是对golang本身container/heap的简单封装,小堆中某个节点的值总是不小于其父节点的值;堆总是一棵完全二叉树。,时间复杂度如下:

    功能时间复杂度
    新增 O(logn)
    查询 O(n)
    删除 O(logn)

     

  • 相关阅读:
    通过串口抓取图片
    Qt也有垃圾回收(通过QScopedPointer实现),下决心在项目里使用QScopedPointer,省了太多事情了,而且更安全!!
    IOS端 margin-top 和 margin-bottom 使用负数时的区别
    使用ROME解析rss,如何获取icon图标
    SVG图片如何调整大小和颜色
    Js点击触发Css3的动画Animations、过渡Transitions效果
    如何判断是否为同一个App,Ionic3如何修改包名
    如何使用JPQL写纯SQL语句
    为何在新线程中使用注解获取不到Spring管理的Bean
    Ionic的NavController 和ModalController 的区别
  • 原文地址:https://www.cnblogs.com/hlxs/p/12737698.html
Copyright © 2020-2023  润新知