Go实现单链表(并发安全)

Go数据结构:单链表

    • 单链表介绍
    • 单链表的结构
    • 后插元素
    • 前插元素
    • 指定位置插入
    • 遍历链表
    • 使用哨兵实现单链表
    • 全部代码

单链表介绍

  上个章节我们实现了并发不安全的链表, 并发不安全单链表
这次我们实现并发安全的链表,以及增加了,首尾节点,更加方便的插入和查询。
想必大家现在已经有了大概的思路了,下面的代码实现和上一章节差不多,但是更加巧妙的运用了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()
}

你可能感兴趣的:(数据结构,算法,golang)