首页 > 其他分享 >Go组件库总结之介入式链表

Go组件库总结之介入式链表

时间:2023-02-27 13:44:37浏览次数:67  
标签:head nil List Element 链表 组件 tail func Go

本篇文章我们用Go封装一个介入式的双向链表,目的是将链表的实现和具体元素解耦。文章参考自:https://github.com/brewlin/net-protocol

1.元素的接口

type Element interface {
    Next() Element
    Prev() Element
    SetNext(Element)
    SetPrev(Element)
}

2.链表的封装

type List struct {
    head Element
    tail Element
}

3.链表的操作

// Reset 清空List
func (l *List) Reset() {
    l.head = nil
    l.tail = nil
}

// Empty 判断List是否为空
func (l *List) Empty() bool {
    return l.head == nil
}

// Front 返回第一个元素
func (l *List) Front() Element {
    return l.head
}

// Back 返回最后一个元素
func (l *List) Back() Element {
    return l.tail
}

// PushFront 插入元素到列头
func (l *List) PushFront(e Element) {
    e.SetNext(l.head)
    e.SetPrev(nil)

    if l.head != nil {
        l.head.SetPrev(e)
    } else {
        l.tail = e
    }

    l.head = e
}

// PushBack 插入元素到列尾
func (l *List) PushBack(e Element) {
    e.SetNext(nil)
    e.SetPrev(l.tail)

    if l.tail != nil {
        l.tail.SetNext(e)
    } else {
        l.head = e
    }

    l.tail = e
}

// PushBackList 插入一个list到列尾,并清空这个list
func (l *List) PushBackList(m *List) {
    if l.head == nil {
        l.head = m.head
        l.tail = m.tail
    } else if m.head != nil {
        l.tail.SetNext(m.head)
        m.head.SetPrev(l.tail)

        l.tail = m.tail
    }

    m.head = nil
    m.tail = nil
}

// InsertAfter 在b后插入e
func (l *List) InsertAfter(b, e Element) {
    a := b.Next()
    e.SetNext(a)
    e.SetPrev(b)
    b.SetNext(e)

    if a != nil {
        a.SetPrev(e)
    } else {
        l.tail = e
    }
}

// InsertBefore 在a前插入e
func (l *List) InsertBefore(a, e Element) {
    b := a.Prev()
    e.SetNext(a)
    e.SetPrev(b)
    a.SetPrev(e)

    if b != nil {
        b.SetNext(e)
    } else {
        l.head = e
    }
}

// Remove 移除e
func (l *List) Remove(e Element) {
    prev := e.Prev()
    next := e.Next()

    if prev != nil {
        prev.SetNext(next)
    } else {
        l.head = next
    }

    if next != nil {
        next.SetPrev(prev)
    } else {
        l.tail = prev
    }
}

4.元素接口的实现

type Entry struct {
    next Element
    prev Element
}

func (e *Entry) Next() Element {
    return e.next
}

func (e *Entry) Prev() Element {
    return e.prev
}

func (e *Entry) SetNext(elem Element) {
    e.next = elem
}

func (e *Entry) SetPrev(elem Element) {
    e.prev = elem
}

5.使用示例

我们只需在结构体中用匿名字段继承Entry,就可以将其作为链表上的元素进行插入删除操作。

type Card struct {
    Entry
    num int
}

func main() {
    var list List
    for i := 0; i < 10; i++ {
        list.PushBack(&Card{num:i})
    }

    for !list.Empty() {
        e := list.Front()
        fmt.Println(e.(*Card).num)
        list.Remove(e)
    }
}

标签:head,nil,List,Element,链表,组件,tail,func,Go
From: https://www.cnblogs.com/qxcheng/p/17159382.html

相关文章

  • vue源码分析-动态组件
    前面花了两节的内容介绍了组件,从组件的原理讲到组件的应用,包括异步组件和函数式组件的实现和使用场景。众所周知,组件是贯穿整个Vue设计理念的东西,并且也是指导我们开发的......
  • 彻底搞懂React-hook链表构建原理
    写在前面的小结每一个hook函数都有对应的hook对象保存状态信息useContext是唯一一个不需要添加到hook链表的hook函数只有useEffect、useLayoutEffect以及us......
  • python+playwright 学习-14.导航page.goto(url) 详解
    前言Playwright可以导航到URL并处理由页面交互引起的导航。本篇涵盖了等待页面导航和加载完成的常见场景。导航生命周期导航从更改页面URL或通过与页面交互(例如,单......
  • #甘特图# DHTMLXGantt 组件笔记
    配置配置缩放单位gantt.config.scale,示例gantt.config.scale=[{unit:"day",step:1,format:"%d%M"}]需要注意的是,当显示比较小的刻度如天、小时甚至时分钟......
  • 力扣简876 链表的中间节点
    只要一个一步一步走另一个指针两步两步走然后快的走到终点慢的就是中点//只有两种情况一种中间节点有一个一种有两个分开讨论一下publicstaticListNodemiddleNo......
  • 组件内路由守卫
    简介:作用:给组件设置权限beforeRouteEnter(to,from,next){通过路由规则,进入该组件时被调用},beforeRouteLeave(to,from,next){通过路由规则,离开该组件时被调用},......
  • 调用兄弟组件的方法
    调用兄弟组件的方法使用场景:在第一个子组件中点击列表的信息时,第二个子组件执行查询接口。使用方法:在第一个子组件执行点击事件时,通过子传父方法传第二个子组件需要的值......
  • go语言中 json的omitempty标签导致protocbuf忽略默认值属性的问题
    解决方法:在生成protocol文件后,执行如下命令,去除omitempty标签即可。Get-ChildItem-Path"C:\path\to\directory"-Recurse-Filter"*.pb.go"|ForEach-Object{$......
  • Spring Boot 实现日志链路追踪,无需引入组件,让日志定位更方便!
    来源:blog.csdn.net/qq_35387940/article/details/125062368前言从文章标题就知道,这篇文章是介绍些什么。这是我一位朋友的问题反馈:好像是的,确实这种现象是普遍存在的......
  • 联邦学习论文阅读笔记11 FGFL: A blockchain-based fair incentive governor for Fede
    面对的问题:激励分配不均、攻击者欺骗 方法:提出FGFL模型。1)设计了时间衰减SLM算法度量工作者声誉;2)设计了基于梯度相似度的轻量级方法度量工作者贡献;3)提出了一种公平的激......