本篇文章我们用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)
}
}

Go组件库总结之介入式链表的更多相关文章

  1. 免费开源的 .NET 分布式组件库 Exceptionless Foundatio

    前言 在互联网时代,分布式应用.系统变得越来越多,我们在使用 .Net 技术构建分布式系统的时候,需要使用到一些组件或者是助手库来帮助我们提高生产力以及应用程序解耦,但是纵观.Net圈,能够符合要求的 ...

  2. RSuite 一个基于 React.js 的 Web 组件库

    RSuite http://rsuite.github.io RSuite 是一个基于 React.js 开发的 Web 组件库,参考 Bootstrap 设计,提供其中常用组件,支持响应式布局. 我 ...

  3. C++侵入式链表

    C++标准模板库中的list是非侵入式的链表,当我们通过对象来删除容器中的对象时,需要从头到尾查找一次得到iterator,最后通过iterator来删除对象.这样删除容器中的对象时比较缓慢,所以就实 ...

  4. Web移动端的常用组件库

    normalize http://necolas.github.io/normalize.css/ 最受欢迎的css reset 保留有用的默认值,这个区别于其他的CSS resets 标准化大范围的 ...

  5. 16款优秀的Vue UI组件库推荐

    16款优秀的Vue UI组件库推荐 Vue 是一个轻巧.高性能.可组件化的MVVM库,API简洁明了,上手快.从Vue推出以来,得到众多Web开发者的认可.在公司的Web前端项目开发中,多个项目采用基 ...

  6. Vue2.0+组件库总结

    转自:https://blog.csdn.net/lishanleilixin/article/details/84025459 UI组件 element - 饿了么出品的Vue2的web UI工具套 ...

  7. 转:Vue2.0+组件库总结

    UI组件 element - 饿了么出品的Vue2的web UI工具套件 Vux - 基于Vue和WeUI的组件库 mint-ui - Vue 2的移动UI元素 iview - 基于 Vuejs 的开 ...

  8. 前端组件库 - 搭建web app常用的样式/组件等收集列表(移动优先)

    0. 前端自动化(Workflow) 前端构建工具 Webpack - module bundler Yeoman - a set of tools for automating developmen ...

  9. 七个不可错过的React组件库与开发框架

    React是如今最火爆的前端技术,而React最棒的一个特点就是有大量功能丰富的组件库和开发框架可用.从按钮到卷轴到工具条,应有尽有,而且这些组件可以各行其是,也可以组装成复杂的UI,你也可以把UI分 ...

  10. [转载]前端——实用UI组件库

    https://www.cnblogs.com/xuepei/p/7920888.html Angular UI 组件 ngx-bootstrap 是一套Bootstrap 组件 官网:https:/ ...

随机推荐

  1. P19_数据绑定

    数据绑定 数据绑定的基本原则 在 data 中定义数据 在 WXML 中使用数据 在 data 中定义页面的数据 在页面对应的 .js 文件中,把数据定义到 data 对象中即可: Mustache ...

  2. TIM + DMA + ADC

    #include "public.h" #define FFT_POINT (256) static uint16_t _DmaBuffer[FFT_POINT]; static ...

  3. Java开发环境配置(win7-64bit)

    Java开发环境配置(win7-64bit) java Java开发环境配置(win7-64bit) Java开发环境配置(win7-64bit) 1.概述 2.文本用到的工具 3.环境变量配置 4. ...

  4. Blender如何设置模型中心点

    推荐:将 NSDT场景编辑器 加入你的3D开发工具链. 在使用Blender建模的时候,有时候会导入一些从别的地方**过来的模型,这时候就会遇到一个问题,模型放到场景中时与鼠标放置的位置有一定的偏差, ...

  5. Echarts —自定义label标签的样式(formatter,rich,添加图标等操作)

    最近公司项目中在使用 Echarts 绘制图表时,由于默认的 label 标签不能满足设计稿需求,所以研究了对 label标签进行格式化的方案,了解到可以使用 formatter 内容格式器对标签内容 ...

  6. Docker和Kubernetes网络模型

    Docker网络模型 Bridge模式(默认) Docker程序启动后会创建一个bridge0网桥,并分配一个IP,可以想象成一个虚拟的交换机,创建的容器实例都会通过虚拟网卡veth pair设备连接 ...

  7. SAP GGB1替换 发现没有替换的字段 解决

    需求 替代凭证中的付款方式为默认值 GGB1替代 如上图所示 并没有我们想到替换的zschl字段 这就需要我们去维护一张配置表 将这个字段放出来 sm30--VWTYGB01 将对应字段的勾去掉即可, ...

  8. windows与linux下的路径区别

    windows与linux下的路径区别windows用的是"\",linux用的是"/"这一点要特别清楚,, ps:在PHP windows也可以用/表示路径 ...

  9. vue 退出登录页面跳转 浏览器localStorage中的值没有改变

    vuex中的loginout方法actions:{ loginout(data:string){ return new Promise(((resolve, reject)=>{ setTime ...

  10. CloudFlare Workers部署Pixiv图片反代

    CloudFlare Workers部署Pixiv图片反代 众所周知,pixiv的图片伺服器网域为i.pximg.net,因为有盗连保护,只要Referer是空值或不是来自pixiv的网域就会返回40 ...