//链表
//并发安全单链表
type SingleNode struct {
Data interface{}
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),
}
}
//后插元素
func (List *SingleList) LastAppend(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
}
// 删除链表中的指定值节点
func (List *SingleList) DelLinkedNode(f func(data interface) bool) bool {
if list.Size == 0 {
return false
}
List.Mutex.Lock()
defer List.Mutex.Unlock()
var prev *SingleNode = nil
current := List.Head
for current != nil {
f()
/*conn, ok := current.Data.(ChatWebSocketConn)
if ok && conn.client_id == client_id {
if prev == nil {
List.Head = current.Next
} else {
prev.Next = current.Next
}
List.Size--
if List.Size == 0 {
List.Tail = nil
}
return true
}*/
prev = current
current = current.Next
}
return false
}
//链表使用
//建立账号和连接的绑定关系,并作为链表的一个节点
item := ChatWebSocketConn{
user_conn : tools.WebSocketConnMapOnce.ConnMap[client_id],
client_id : *client_id,
user_type : (*user_info).Flag,
user_id : (*user_info).Id,
user_nickname : (*user_info).NickName,
}
linked_node := tools.SingleNode{Data:item}
linked_list.LastAppend(&linked_node)
//ChatWebSocketConn定义
type ChatWebSocketConn struct{
user_conn *tools.WebSocketConn //已建立的客户端连接,lu_guild_account_list表id
client_id string //生成的唯一id,标识一个客户端
user_type int //用户类型,1:会员 2:主播
user_id int64 //用户id
user_nickname string //用户昵称
}
我在实现单链表的删除节点功能,函数定义DeleteNode,添加节点是通过LastAppend将ChatWebSocketConn做为一个Node节点添加进去的,删除的时候需要遍历该节点存储的client_id并进行比对,但感觉对链表的删除仍有侵入,我在DelLinkedNode定义了一个回调函数,我想通过回调函数对存储的值就行对比,根据返回值觉得链表的Next指向,应该怎么完善这个回调函数
golang链表节点删除通过回调函数的方式
- 写回答
- 好问题 0 提建议
- 关注问题
- 邀请回答
-
2条回答 默认 最新
关注让 “紫雾凌寒” 来帮你回答,本回答结合 DeepSeek
如果还有问题,请评论或点击头像私信,如果有帮助到您, 请关注、采纳、点赞
- 关键点分析:
- 要实现通过回调函数删除链表节点,需要在链表结构体中添加相关方法,能够遍历链表并根据回调函数的条件来决定是否删除节点。
- 由于是并发安全的单链表,在进行删除操作时要注意锁的使用,避免并发冲突。 - 解决方案:
- 首先完善链表结构体定义:
//并发安全单链表 type SingleNode struct { Data interface{} Next *SingleNode } type SingleList struct { head *SingleNode lock sync.Mutex }- 然后添加删除节点的方法:
package main import ( "fmt" "sync" ) //并发安全单链表 type SingleNode struct { Data interface{} Next *SingleNode } type SingleList struct { head *SingleNode lock sync.Mutex } // 添加节点到链表尾部 func (sl *SingleList) Append(data interface{}) { newNode := &SingleNode{Data: data} sl.lock.Lock() defer sl.lock.Unlock() if sl.head == nil { sl.head = newNode } else { current := sl.head for current.Next != nil { current = current.Next } current.Next = newNode } } // 通过回调函数删除节点 func (sl *SingleList) DeleteByCallback(callback func(interface{}) bool) { sl.lock.Lock() defer sl.lock.Unlock() current := sl.head var prev *SingleNode while current != nil { if callback(current.Data) { if prev == nil { sl.head = current.Next } else { prev.Next = current.Next } } else { prev = current } current = current.Next } }- 代码示例说明:
-SingleList结构体包含一个指向链表头节点的指针head和一个互斥锁lock,用于并发安全。
-Append方法用于向链表尾部添加节点,添加时先加锁,操作完成后解锁。
-DeleteByCallback方法通过遍历链表,对每个节点的数据应用回调函数callback。如果回调函数返回true,则删除该节点。删除时需要考虑当前节点是否为头节点,如果是则更新头节点;否则更新前一个节点的Next指针。 - 多种解决方案及优缺点:
- 方案一:使用递归- 优点:代码结构简洁,对于一些简单的链表操作逻辑清晰。
- 缺点:递归深度过大时可能导致栈溢出,并且递归调用会增加额外的开销。
- 方案二:使用迭代(如上述代码)
- 优点:性能较好,不会出现栈溢出问题,适用于大多数情况。
- 缺点:代码相对递归来说不够简洁,逻辑上可能稍复杂一些。
- 总结:
通过在并发安全的单链表结构体中添加DeleteByCallback方法,利用回调函数来灵活地删除链表节点。这种方式可以根据不同的业务需求定制删除条件,同时通过互斥锁保证了并发操作的安全性。迭代的实现方式在性能和稳定性上表现较好,是一种常用的链表节点删除实现策略。
请注意,上述代码中
while循环在Go语言中可以使用for循环替代,并且代码中SingleLi未完成定义,这里按照补充完整链表结构体的思路进行了完善。如果有其他特殊需求,请根据实际情况调整。希望以上解答对您有所帮助。如果您有任何疑问,欢迎在评论区提出。
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报- 关键点分析: