Go实现双向链表的示例代码

2020-01-28 14:04:59刘景俊

从链表左边取出一个节点


// 从链表左边取出一个节点
func (l *List) LPop() (node *ListNode) {

  // 数据为空
  if l.len == 0 {

    return
  }

  node = l.head

  if node.next == nil {
    // 链表未空
    l.head = nil
    l.tail = nil
  } else {
    l.head = node.next
  }
  l.len = l.len - 1

  return
}

通过索引查找节点

通过索引查找节点,如果索引是负数则从表尾开始查找。

自然数和负数索引分别通过两种方式查找节点,找到指定索引或者是链表全部查找完则查找完成。


// 通过索引查找节点
// 查不到节点则返回空
func (l *List) Index(index int) (node *ListNode) {

  // 索引为负数则表尾开始查找
  if index < 0 {
    index = (-index) - 1
    node = l.tail
    for true {
      // 未找到
      if node == nil {

        return
      }

      // 查到数据
      if index == 0 {

        return
      }

      node = node.prev
      index--
    }
  } else {
    node = l.head
    for ; index > 0 && node != nil; index-- {
      node = node.next
    }
  }

  return
}

返回指定区间的元素


// 返回指定区间的元素
func (l *List) Range(start, stop int) (nodes []*ListNode) {
  nodes = make([]*ListNode, 0)

  // 转为自然数
  if start < 0 {
    start = l.len + start
    if start < 0 {
      start = 0
    }
  }

  if stop < 0 {
    stop = l.len + stop
    if stop < 0 {
      stop = 0
    }
  }

  // 区间个数
  rangeLen := stop - start + 1
  if rangeLen < 0 {

    return
  }

  startNode := l.Index(start)
  for i := 0; i < rangeLen; i++ {
    if startNode == nil {
      break
    }

    nodes = append(nodes, startNode)
    startNode = startNode.next
  }

  return
}

4、总结

到这里关于链表的使用已经结束,介绍链表是有哪些(单向链表,双向链表以及循环链表),也介绍了链表的应用场景(Redis 列表使用的是链表作为底层实现),最后用 Go 实现了双向链表,演示了链表在 Go 语言中是怎么使用的,大家可以在项目中更具实际的情况去使用。

5、参考文献

维基百科 链表

github redis

项目地址:go 实现队列

https://github.com/link1st/link1st/tree/master/linked

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持易采站长站。