首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >golang实现循环单链代码示例

golang实现循环单链代码示例

作者头像
公众号-利志分享
发布2022-04-25 08:51:55
发布2022-04-25 08:51:55
41800
代码可运行
举报
文章被收录于专栏:利志分享利志分享
运行总次数:0
代码可运行

最近我从阅读golang的源码,了解了channel的底层实现,用了一个循环队列,和双端链表。golang的map使用bucket存储key和value使用了链表,发现golang的底层实现还是比较有意思的。所以我学着用golang实现一个循环单链的代码示例,下面我们来看一下循环单链的实现,循环单链实现了,插入数据,删除某个节点数据,翻转数据,获取长度等功能,代码大家就直接对着源码看看吧,我就没有对代码进行分段讲解了,最后面我们贴一下这个代码运行的结果。

代码语言:javascript
代码运行次数:0
运行
复制
package main

import "fmt"

//定义节点的数据结构
type Node struct {
  data interface{}
  next *Node
}

//单链的数据结构
type OneCycleList struct {
  size int
  head *Node
}

//获取链表的头部
func (o *OneCycleList) GetHead() *Node {
  return o.head
}

//获取长度
func (o *OneCycleList) GetSize() int {
  return o.size
}

//获取节点装的数据
func (o *Node) GetData() interface{} {
  return o.data
}

//获取下一个节点的地址
func (o *Node) GetNext() *Node {
  return o.next
}

//添加链表数据
func (o *OneCycleList) Append(data interface{}) bool {
  node := Node{}
  //添加data数据
  node.data = data
  if o.GetSize() == 0 {
    o.head = &node
  } else {
    item := o.GetHead()
    //找到链表尾部,当当前的这个链表的头部 == next下一个链表地址的时候
    //循环链表的最后一个next指向第一个的head 是相等的
    for ; item.next != o.GetHead(); item = item.next {
    }
    //这里是把数据挂到链表的next
    item.next = &node
  }
  node.next = o.head
  o.size++
  return true
}

//基于某个node进行,插入节点数据
func (o *OneCycleList) InsertNext(elment *Node, data interface{}) bool {
  if elment == nil {
    return false
  }
  //处理新节点数据装载到链表中
  node := Node{}
  node.data = data
  node.next = elment.next
  elment.next = &node
  o.size++
  return true
}

//删除某个节点的数据,并返回该数据
func (o *OneCycleList) Remove(elment *Node) interface{} {
  if elment == nil {
    return nil
  }
  item := o.GetHead()
  //找到elment的前一个节点
  for ; item.next != elment; item = item.next {
  }
  //将elment的前面一个节点的next指向当前elment的next,这里就删除了当前的节点elment了
  item.next = elment.next
  o.size--
  return elment.GetData()
}

//调整所有的节点进行转向
func Reverse(head *Node, o *OneCycleList) *OneCycleList {
  if head.next == o.head {
    o.head = head
    return o
  }
  p := Reverse(head.next, o)
  head.next.next = head
  head.next = p.head
  return p
}

func main() {
  a := OneCycleList{}
  //处理好初始化
  a.Append(3)
  a.Append(4)
  a.Append(8)
  //基于3后面的节点追加数据 9
  a.InsertNext(a.head, 9)
  temp := a.head
  fmt.Println("下面是循环打印-------------------")
  //循环打印链表数据
  for {
    if temp == nil {
      break
    }
    fmt.Print(temp.data, "\n")
    if temp.next == a.head {
      break
    }
    temp = temp.next
  }
  //单向循环链表翻转
  b := Reverse(a.head, &a)
  fmt.Println("翻转之后打印结果-------------------")
  temp2 := b.head
  for {
    if temp2 == nil {
      break
    }
    fmt.Print(temp2.data, "\n")
    if temp2.next == b.head {
      break
    }
    temp2 = temp2.next
  }
  fmt.Println("下面删除一个节点当前节点返回值-------------------")
  //下面删除一个节点
  fmt.Println(b.Remove(b.head.next))
  fmt.Println("下面删除一个节点后打印数据-------------------")
  temp3 := b.head
  for {
    if temp3 == nil {
      break
    }
    fmt.Print(temp3.data, "\n")
    if temp3.next == b.head {
      break
    }
    temp3 = temp3.next
  }
}

下面是代码运行的结果:

代码语言:javascript
代码运行次数:0
运行
复制
下面是循环打印-------------------
3
9
4
8
翻转之后打印结果-------------------
8
4
9
3
下面删除一个节点当前节点返回值-------------------
4
下面删除一个节点后打印数据-------------------
8
9
3

好了,这次我简单讲述循环单链,后面我golang源码研究,根据重点再把循环队列和双端链表实现分享给大家。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-09-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 利志分享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档