showliuzp 2025-10-21 13:39 采纳率: 84.3%
浏览 2
已结题

golang链表查找封装通用方法


//聊天数据结构定义
//聊天websocket连接数据结构定义
type chat_websocket_conn 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                  //用户昵称
}
 
 
//链表定义
package tools
 
import (
    "sync"
    "fmt"
    )
 
//并发安全单链表
type SingleNode struct {
    Data interface{}
    Next *SingleNode
}

type SingleList struct {
    Mutex *sync.RWMutex //读写锁

    Head  *SingleNode   //头节点
    Tail  *SingleNode   //尾节点

    Size  uint          //总数
}

func NewLinkedList() *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 {
        if f(current.Data){
            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
    }

    prev = nil

    return false
}

//查找链表中是否有指定值节点,通过回调函数实现无侵入查找
func (List *SingleList) FindLinkedNode(f func(data interface{}) bool) bool {
    if List.Size == 0 {
        return false
    }

    List.Mutex.Lock()

    defer List.Mutex.Unlock()

    current := List.Head

    var count uint = 0
    for current != nil {
        if !f(current.Data){
            count++
        }

        current = current.Next
    }

    if count >= List.Size{
        return false
    }

    return true
}

//查找链表中是否有指定值节点,有则返回
func (List *SingleList) FindLinkedNodeDetail(f func(data interface{}) bool) interface{} {
    if List.Size == 0 {
        return nil
    }

    List.Mutex.Lock()

    defer List.Mutex.Unlock()

    current := List.Head

    for current != nil {
        if f(current.Data){
            return current.Data
        }

        current = current.Next
    }

    return nil
}

 
//查找每个主播|会员的链表节点是否存在,根据生成的clientid
//作为回调函数传入链表,通过闭包函数实现无侵入校验
func find_linked_node_clientid(client_id *string) func(interface{}) bool {
    return func(data interface{}) bool {
        //强制类型转换
        conn, ok := data.(chat_websocket_conn)
        if ok && conn.client_id == *client_id {
            return true
        }
 
        return false
    }
}
 
 
//查找每个主播|会员的链表节点是否存在,根据生成的clientid
//作为回调函数传入链表,通过闭包函数实现无侵入校验
func find_linked_node_userid(user_id int64) func(interface{}) bool {
    return func(data interface{}) bool{
        //强制类型转换
        conn, ok := data.(chat_websocket_conn)
        if ok && conn.user_id == user_id {
            return true
        }
 
        return false
    }
}
 
 
//调用:
tools.NewLinkedList().FindLinkedNode(find_linked_node_userid(client_id))
tools.NewLinkedList().FindLinkedNode(find_linked_node_clientid(user_id))
find_linked_node_userid、find_linked_node_clientid为回调的闭包函数,仅仅是 if ok && conn.client_id == *client_id/ if ok && conn.user_id == user_id ,这里不一样,逻辑都是一样的,我想把他们封装成通用的,应该怎么封装?
  • 写回答

3条回答 默认 最新

  • 紫雾凌寒 新星创作者: 人工智能技术领域 2025-10-21 13:45
    关注

    让 “紫雾凌寒” 来帮你回答,本回答结合 DeepSeek

    如果还有问题,请评论或点击头像私信,如果有帮助到您, 请关注、采纳、点赞

    1. 关键点分析:
      - 目前仅给出了一个结构体定义chat_websocket_conn,其中包含一个指向tools.WebSoc类型的指针user_conn。要封装链表查找通用方法,需要确定链表的节点结构以及查找的依据。这里没有明确链表相关信息,但假设链表节点结构与chat_websocket_conn有关,比如链表节点包含chat_websocket_conn类型的数据。
      - 查找方法可能基于user_conn指针或者chat_websocket_conn结构体的其他属性来进行。
    2. 解决方案:
      - 假设链表节点结构如下:
    type ListNode struct {
        Data chat_websocket_conn
        Next *ListNode
    }
    
    • 封装的查找方法示例:
    // 根据user_conn指针查找链表节点
    func FindNodeByUserConn(head *ListNode, target *tools.WebSoc) *ListNode {
        current := head
        while current != nil {
            if current.Data.user_conn == target {
                return current
            }
            current = current.Next
        }
        return nil
    }
    
    • 注意,这里的代码是伪代码,在Go语言中,while循环通常用for循环来实现。完整的代码如下:
    // 根据user_conn指针查找链表节点
    func FindNodeByUserConn(head *ListNode, target *tools.WebSoc) *ListNode {
        current := head
        for current != nil {
            if current.Data.user_conn == target {
                return current
            }
            current = current.Next
        }
        return nil
    }
    
    1. 多种解决方案及优缺点:
      - 方案一:基于user_conn指针查找。
      • 优点:如果user_conn指针具有唯一性,那么这种查找方式简单直接,效率较高。
      • 缺点:如果user_conn指针不唯一,可能会出现误判,需要额外处理。
      • 方案二:基于chat_websocket_conn结构体的其他属性查找(假设存在其他可用于查找的属性,如用户ID)。
      • 优点:可以根据更丰富的信息进行查找,准确性更高。
      • 缺点:需要确保属性的唯一性,否则可能出现查找不准确的情况,并且实现起来相对复杂一些,需要在节点结构和查找方法中增加对该属性的处理。
    2. 总结:
      - 首先定义了链表节点结构,然后基于chat_websocket_conn结构体中的user_conn指针封装了查找链表节点的通用方法。不同的查找依据有不同的优缺点,在实际应用中需要根据具体需求选择合适的查找方式。

    需要注意的是,以上代码是基于假设的链表节点结构和查找需求编写的,实际应用中可能需要根据具体的业务逻辑和数据结构进行调整。同时,代码中的tools.WebSoc类型未详细定义,在实际使用时需要确保其正确性。

    希望以上解答对您有所帮助。如果您有任何疑问,欢迎在评论区提出。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 10月29日
  • 已采纳回答 10月21日
  • 创建了问题 10月21日