//链表
//并发安全单链表
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) DeleteNode(client_id string) bool {
if List.Size == 0 {
return false
}
List.mutex.Lock()
defer List.mutex.Unlock()
var prev *SingleNode = nil
current := List.Head
for current != nil {
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并进行比对,但感觉对链表的删除仍有侵入,能否在DeleteNode定义个回调函数,通过回调函数进行对比?
golang删除链表节点如何做到不侵入
- 写回答
- 好问题 0 提建议
- 关注问题
- 邀请回答
-
2条回答 默认 最新
阿里嘎多学长 2025-10-18 17:06关注阿里嘎多学长整理AIGC生成,因移动端显示问题导致当前答案未能完全显示,请使用PC端查看更加详细的解答过程
解决方案
删除链表节点不侵入的关键是找到要删除的节点的前一个节点,然后将前一个节点的
Next指针指向要删除的节点的下一个节点。代码示例
func deleteNode(head *SingleNode, data interface{}) *SingleNode { // 找到要删除的节点 node := head for node != nil && node.Data != data { node = node.Next } // 如果找到了要删除的节点 if node != nil { // 如果要删除的节点是头节点 if node == head { head = node.Next } else { // 找到要删除的节点的前一个节点 prev := head for prev.Next != node { prev = prev.Next } // 将前一个节点的 Next 指针指向要删除的节点的下一个节点 prev.Next = node.Next } } return head }注意
- 这个函数会返回链表的新头节点,如果链表中没有找到要删除的节点,则返回原来的链表头节点。
- 如果链表中有多个节点的值相同,这个函数会删除第一个遇到的节点。
解决 无用评论 打赏 举报