单链表介绍
上个章节我们实现了并发不安全的链表, 并发不安全单链表
这次我们实现并发安全的链表,以及增加了,首尾节点
,更加方便的插入和查询。
想必大家现在已经有了大概的思路了,下面的代码实现和上一章节差不多,但是更加巧妙的运用了head,tail指针,具体的思想可以把代码debug下了解他的思路
使用哨兵实现单链表,可以用更少的代码实现,我就写了一个前插和后插,其他的可以自己研究下
单链表的结构
// SingleNode 并发安全单链表
type SingleNode struct {
Data any
Next *SingleNode
}
type SingleList struct {
mutex *sync.RWMutex
Head *SingleNode
Tail *SingleNode
Size uint
}
func NewList() *SingleList {
return &SingleList{
Size: 0,
Head: nil,
Tail: nil,
mutex: new(sync.RWMutex),
}
}
后插元素
// Append 后插元素
func (List *SingleList) Append(node *SingleNode) bool {
if node == nil {
return false
}
List.mutex.Lock()
defer List.mutex.Unlock()
if List.Size == 0 {
List.Head = node
List.Tail = node
List.Size = 1
return true
}
tail := List.Tail
tail.Next = node
List.Tail = node
List.Size += 1
return true
}
前插元素
// AddElem 前插元素
func (List *SingleList) AddElem(node *SingleNode) bool {
if node == nil {
return false
}
if List.Size == 0 {
List.Head = node
List.Tail = node
List.Size = 1
return true
}
node.Next = List.Head
List.Head = node
List.Size++
return true
}
指定位置插入
// Insert 指定位置插入
func (List *SingleList) Insert(index uint, node *SingleNode) bool {
if node == nil || index > List.Size {
return false
}
List.mutex.Lock()
defer List.mutex.Unlock()
if index == 0 {
node.Next = List.Head
List.Head = node
List.Size++
return true
}
pre := List.Head
var count uint
for count = 1; count < index; count++ {
pre = pre.Next
}
next := pre.Next
pre.Next = node
node.Next = next
List.Size++
return true
}
遍历链表
func (list *SingleList) Display() {
if list == nil {
fmt.Println("this single list is nil")
return
}
list.mutex.RLock()
defer list.mutex.RUnlock()
fmt.Printf("this single list size is %d \n", list.Size)
ptr := list.Head
var i uint
for i = 0; i < list.Size; i++ {
fmt.Printf("No%3d data is %v\n", i+1, ptr.Data)
ptr = ptr.Next
}
}
使用哨兵实现单链表
// SingleNodeS 使用哨兵实现单链表
type SingleNodeS struct {
Data any
next, pre *SingleNodeS
ListS *SingleListS
}
type SingleListS struct {
mutex *sync.RWMutex
root SingleNodeS
Size uint
}
func (l *SingleListS) Init() *SingleListS {
l.root.next = &l.root
l.root.pre = &l.root
l.Size = 0
return l
}
func (l *SingleListS) inset(e, root *SingleNodeS) {
e.next = root.next
root.next = e
e.next.pre = e
e.ListS = l
l.Size++
}
func NewSingleNodes() *SingleListS {
return new(SingleListS).Init()
}
func (l *SingleListS) PushBack(v any) {
l.inset(&SingleNodeS{Data: v}, l.root.pre)
}
func (l *SingleListS) FrontBack(v any) {
l.inset(&SingleNodeS{Data: v}, &l.root)
}
全部代码
// SingleNode 并发安全单链表
type SingleNode struct {
Data any
Next *SingleNode
}
type SingleList struct {
mutex *sync.RWMutex
Head *SingleNode
Tail *SingleNode
Size uint
}
// Append 后插元素
func (List *SingleList) Append(node *SingleNode) bool {
if node == nil {
return false
}
List.mutex.Lock()
defer List.mutex.Unlock()
if List.Size == 0 {
List.Head = node
List.Tail = node
List.Size = 1
return true
}
tail := List.Tail
tail.Next = node
List.Tail = node
List.Size += 1
return true
}
// AddElem 前插元素
func (List *SingleList) AddElem(node *SingleNode) bool {
if node == nil {
return false
}
if List.Size == 0 {
List.Head = node
List.Tail = node
List.Size = 1
return true
}
node.Next = List.Head
List.Head = node
List.Size++
return true
}
// Insert 指定位置插入
func (List *SingleList) Insert(index uint, node *SingleNode) bool {
if node == nil || index > List.Size {
return false
}
List.mutex.Lock()
defer List.mutex.Unlock()
if index == 0 {
node.Next = List.Head
List.Head = node
List.Size++
return true
}
pre := List.Head
var count uint
for count = 1; count < index; count++ {
pre = pre.Next
}
next := pre.Next
pre.Next = node
node.Next = next
List.Size++
return true
}
func NewList() *SingleList {
return &SingleList{
Size: 0,
Head: nil,
Tail: nil,
mutex: new(sync.RWMutex),
}
}
// Display 输出链表
func (list *SingleList) Display() {
if list == nil {
fmt.Println("this single list is nil")
return
}
list.mutex.RLock()
defer list.mutex.RUnlock()
fmt.Printf("this single list size is %d \n", list.Size)
ptr := list.Head
var i uint
for i = 0; i < list.Size; i++ {
fmt.Printf("No%3d data is %v\n", i+1, ptr.Data)
ptr = ptr.Next
}
}
func main() {
list := NewList()
a := &SingleNode{
Data: 4,
}
b := &SingleNode{
Data: 41,
}
c := &SingleNode{
Data: 42,
}
d := &SingleNode{
Data: 414,
}
de := &SingleNode{
Data: 4124,
}
list.AddElem(a)
list.AddElem(b)
list.AddElem(c)
list.Append(de)
list.AddElem(d)
//
//Link := NewLinkList()
//Link.AppendElemBack(3)
//Link.AppendElemBack(4)
//Link.AppendElemBack("5")
//Link.AppendElemBack(5)
//Link.AppendElemBack(553)
//Link.AppendElemBack(5)
//Link.AppendElemBack(5)
//Link.AppendElemBack(553)
//Link.AppendElemBack(5)
//Link.RemoveElemAll(5)
//Link.ShowList()
//Link.InsertForwardElem(2, 8)
//Link.ShowList()
}