• 李皮皮皮皮皮
    2018-08-29
    1.list可以作为queue和
    stack的基础数据结构
    2.ring可以用来保存固定数量的元素,例如保存最近100条日志,用户最近10次操作
    3.heap可以用来排序。游戏编程中是一种高效的定时器实现方案
    
     63
  • 陌上人 .
    2018-11-28
    老师,之后的课可不可以多加一些图形解释,原理性的知识只用文字确实有些晦涩难懂
     1
     40
  • louis
    2019-04-23
    郝老师,这里不太理解什么叫“自己生成的Element类型值”?把自己生成的Element类型值传给链表——这个能不能再通俗点描述?

    作者回复: 比如你用 list.New 函数创建了一个 List 类型的双向链表,然后通过它的一些方法往里面塞了一些元素。可以往里面塞的元素的方法有 PushFront、PushBack、InsertAfter、InsertBefore 等。

    但是你发现没有,这些方法接受的新元素的类型都是 interface{} 的。也就是说,这个 List 类型的链表只接受 interface{} 类型的新元素值。

    而当新元素值进入链表之后,链表会把它们再包装成 list.Element 类型的值。你看,那些往里塞元素值的方法返回的都是被包装后的 *list.Element 类型的元素值。

    当你像我这样浏览了 container/list.List 类型的相关 API 之后,就应该可以明白我问这个问题的背景了。

    这个 List 类型只会接受 interface{} 类型的新元素值,并且只会吐出 *list.Element 类型的已有元素值。显然,任何移动已有元素值或者删除已有元素值的方法,都只会接受该链表自己吐出来的“Element 值”。因此,对于我们自己生成的“Element 值”,这个链表的任何方法都是不会接受的。

    当然了,如果你之前完全没用过 List 类型,可能会觉得这个问题有些突兀。但是当你看完下面的详细解释之后,我相信你就会有所了解了。

    我们这个专栏的一个风格就是:“先抛出问题,然后再解释前因后果”。目的就是,逼迫大家在碰到问题之后自己先去了解背景并试着找找答案,然后再回来看我的答案。这样的话,你对这些知识点的记忆会更牢固,不容易忘。

    我非常希望这个专栏能成为大家的“枕边书”,而不是听听音频就放在一边的那种。所以才有了这样的结构设计。如果你们能在今后碰到问题时想起这个专栏,到这里翻一翻并能找到答案的线索,那我就太高兴了。

    
     19
  • Err
    2018-10-23
    我觉得写一个实际的例子能帮助更好理解
    
     17
  • melon
    2018-08-29
    list的一个典型应用场景是构造FIFO队列;ring的一个典型应用场景是构造定长环回队列,比如网页上的轮播;heap的一个典型应用场景是构造优先级队列。
    
     17
  • 会网络的老鼠
    2018-08-30
    现在大家写golang程序,一般用什么IDE?
     2
     7
  • fliter
    2018-08-29
    为什么不把list像slice,map一样作为一种不需要import其他包就能使用的数据类型?是因为使用场景较后两者比较少吗

    作者回复: 这需要一个过程,之前list也不是标准库中的一员。况且也没必要把太多的东西多做到语言里,这样反倒不利于后面的扩展。

    
     7
  • 后端进阶
    2018-09-06
    前面的网友,goland了解一下,超赞的ide
    
     5
  • 云学
    2018-08-31
    在内存上,和ring的区别是list多了一个特殊表头节点,充当哨兵
    
     5
  • 李斌
    2018-10-30
    用 vscode 就蛮好的,我之前是八年 vim 党,写 golang 时硬生生地被掰成 vscode

    作者回复: 嗯,也算是与时俱进吧,未来有脑机接口了,也就用不着这些了。

     1
     3
  • Zer0
    2019-08-06
    不能把自己生成的Element传给List主要是因为Element的list成员是不开放的,我们不能操作,而在List上操作Element的时候是会判断Element的list成员是否是自己。是这样吗?

    作者回复: ✅

    
     2
  • Geek_a8be59
    2019-06-26
    您好 能否出一个list 链表生成的一个图解,现在我看源码用图去模拟生成 一直搞混掉,特别是在初始化的时候prev和next都指向自身的root 这个很迷糊
    比如:
        c.PushBack("123")
        c.PushFront("456")
        c.PushFront("789")
    根据个人图解应该是789-》456-》nil,为什么能遍历出来很不清楚。能否有一个从初始化到最后生成的样例看一下 万分感谢
    展开

    作者回复: 按照你这三行代码,应该是 789 -> 456 -> 123 啊,你那个“789-》456-》ni”是怎么出来的?

    这个链表里所谓的 root 就是用来表示链表两端的尽头的。所以,这个链表的末端实际上并不是 nil ,而是 root。只是在 Element 的 Next 方法中,如果发现它的 next 字段的值等于 root,就会返回 nil 而已。

    明白了吗?

     1
     2
  • jackstraw
    2019-07-09
    我尝试打印了 “var l = list.New()” 与 “var l list.List”两种方式的l类型,发现是不一样的,但是下面的操作却都是可以的
    func main() {
        //l := list.New()
        var l list.List
        e4 := l.PushBack(4)
        e1 := l.PushFront(1)
        l.InsertBefore(3, e4)
        l.InsertAfter(2, e1)
        //travel(l)
        travel(&l)
    }
    展开

    作者回复: 当然不一样,list.New 返回的是指针值。另外你可以再看看讲结构体和方法那篇文章。

    
     1
  • Sky
    2019-06-12
    这一讲没有实例代码

    作者回复: 建议大家在阅读这一篇文章时对照着 container 包的文档看。对这几个类型的 API 有一定了解之后,使用就是水到渠成的事情了。

    自己先试一试,如果有具体的问题,可以来这里问。

    
     1
  • 缘木求鱼
    2018-10-21
    又比如,在用于删除元素、移动元素,以及一些用于插入元素的方法中,只要判断一下传入的元素中指向所属链表的指针,是否与当前链表的指针相等就可以了。 这里传入的元素的所属链表指针是如何赋值的
    
     1
  • jc9090kkk
    2019-12-26
    从这一章开始听的有点云里雾里的,我之前看过go的一些基础教程,并没有看到有书中笼统地介绍container包的概念和使用场景,有哪本书中是提到了container包的使用的吗?
    
    
  • 李小锋
    2019-12-20
    func flist(){
        link := list.New()
        for i:=1; i< 11; i++ {
            link.PushBack(i)
        }
        for p:= link.Front(); p!=link.Back(); p=p.Next(){
            fmt.Println("Number", p.Value)
        }
    }
    #链表的常用方法
    func (e *Element) Next() *Element
    func (e *Element) Prev() *Element
    func (l *List) Init() *List
     New() *List { return new(List).Init() }
     func (l *List) Len() int { return l.len }
     func (l *List) Front() *Element
     func (l *List) Back() *Element
     func (l *List) Remove(e *Element) interface{}
     func (l *List) PushFront(v interface{}) *Element
     func (l *List) PushBack(v interface{}) *Element
     func (l *List) InsertBefore(v interface{}, mark *Element) *Element
     func (l *List) InsertAfter(v interface{}, mark *Element) *Element
     func (l *List) MoveToFront(e *Element)
     func (l *List) MoveToBack(e *Element)
     func (l *List) MoveBefore(e, mark *Element)
     func (l *List) MoveAfter(e, mark *Element)
     func (l *List) PushBackList(other *List)
     func (l *List) PushFrontList(other *List)
    展开
    
    
  • 窝窝头
    2019-05-05
    1.list作为队列,先进后出,ring可以应用于循环选择场景,对一些长时间占用资源的程序或者请求等对象进行处理
    2.heap还可以做排序,或者字符编码之类的
    
    
  • 兔子高
    2018-09-05
    你好,有个问题想问一下,你在文中有说每次判断链表是否初始化很浪费性能,但是你后面又说每次判断链表的长度或者它是否为空,问题如下
    1.如何判断是否初始化
    2.判断初始化和判断为空的区别
    3.判断链表长度和是否为空比判断是否初始化更节约性能是吗?性能大概会节约多少倍呢?
    麻烦解答一下,谢谢

    作者回复: 我这些是对照list源码说的,你可以去看一看list的源码,这些问题就都迎刃而解了。

    
    
  • xlh
    2018-08-29
    Slice 缩容策略是什么
    
    
我们在线,来聊聊吧