C#源码分析—LinkedList

LinkedList为双向循环链表,链表的定义请自行百度;先贴一下节点类:

    // Note following class is not serializable since we customized the serialization of LinkedList. 
    [System.Runtime.InteropServices.ComVisible(false)] 
    public sealed class LinkedListNode<T> {
        /// <summary>
        /// 自身所属的链表
        /// </summary>
        internal LinkedList<T> list;

        /// <summary>
        /// 后继节点
        /// </summary>
        internal LinkedListNode<T> next;

        /// <summary>
        /// 前驱节点
        /// </summary>
        internal LinkedListNode<T> prev;

        /// <summary>
        /// 自身储存的数据
        /// </summary>
        internal T item;
        
        public LinkedListNode( T value) {
            this.item = value;
        }

        internal LinkedListNode(LinkedList<T> list, T value) {
            this.list = list;
            this.item = value;
        }

        public LinkedList<T> List {
            get { return list;}
        }

        public LinkedListNode<T> Next {
            //当后继节点为空或自身的后继节点为链表头节点时
            get { return next == null || next == list.head? null: next;}
        }

        public LinkedListNode<T> Previous {
            //当前驱节点为空或者自身为链表头节点时
            get { return prev == null || this == list.head? null: prev;}
        }

        public T Value {
            get { return item;}
            set { item = value;}
        }

        internal void Invalidate() {
            list = null;
            next = null;
            prev = null;
        }           
    }

LinkedListNode类内部保存有前驱节点prev和后继节点next以及自身存储数据item,且持有自身属于的链表list。

字段:

        // This LinkedList is a doubly-Linked circular list.
        internal LinkedListNode<T> head;    //头结点
        internal int count;                 //链表元素数量
        internal int version;
        private Object _syncRoot;
        
#if !SILVERLIGHT
        private SerializationInfo siInfo; //A temporary variable which we need during deserialization.        
#endif

        // names for serialization
        const String VersionName = "Version";
        const String CountName = "Count";  
        const String ValuesName = "Data";

属性:

        /// <summary>
        /// 获取链表数量
        /// </summary>
        public int Count {
            get { return count;}
        }

        /// <summary>
        /// 获取头节点
        /// </summary>
        public LinkedListNode<T> First {
            get { return head;}
        }

        /// <summary>
        /// 获取尾节点
        /// </summary>
        public LinkedListNode<T> Last {
            get { return head == null? null: head.prev;}
        }

        bool ICollection<T>.IsReadOnly {
            get { return false; }
        }

AddAfter函数和AddBefore函数:

        /// <summary>
        /// 插入到指定的节点后
        /// </summary>
        /// <param name="node">指定的节点</param>
        /// <param name="value">待插入的数据</param>
        /// <returns></returns>
        public LinkedListNode<T> AddAfter(LinkedListNode<T> node, T value) {
            ValidateNode(node);
            LinkedListNode<T> result = new LinkedListNode<T>(node.list, value); 
            InternalInsertNodeBefore(node.next, result);
            return result;
        }

        /// <summary>
        /// 插入到指定的节点后
        /// </summary>
        /// <param name="node">指定的节点</param>
        /// <param name="newNode">待插入的节点</param>
        public void AddAfter(LinkedListNode<T> node, LinkedListNode<T> newNode) {
            ValidateNode(node);
            ValidateNewNode(newNode);
            InternalInsertNodeBefore(node.next, newNode);
            newNode.list = this;
        }

        /// <summary>
        /// 插入到指定的节点前
        /// </summary>
        /// <param name="node">指定的节点</param>
        /// <param name="value">待插入的数据</param>
        /// <returns></returns>
        public LinkedListNode<T> AddBefore(LinkedListNode<T> node, T value) {
            ValidateNode(node);    
            LinkedListNode<T> result = new LinkedListNode<T>(node.list, value);
            InternalInsertNodeBefore(node, result);
            if ( node == head) {
                head = result;
            }
            return result;
        }

        /// <summary>
        /// 插入到指定的节点前
        /// </summary>
        /// <param name="node">指定的节点</param>
        /// <param name="newNode">待插入的节点</param>
        public void AddBefore(LinkedListNode<T> node, LinkedListNode<T> newNode) {
            ValidateNode(node);    
            ValidateNewNode(newNode);                        
            InternalInsertNodeBefore(node, newNode);
            newNode.list = this;
            if ( node == head) {
                head = newNode;
            }
        }

本质上调用了InternalInsertNodeBefore函数,ValidateNode函数和ValidateNewNode均为检查节点函数;其函数分别实现如下:

        /// <summary>
        /// 检查新节点
        /// </summary>
        /// <param name="node"></param>
        internal void ValidateNewNode(LinkedListNode<T> node) {
            if (node == null) {
                throw new ArgumentNullException("node");                
            }

            if ( node.list != null) {
                throw new InvalidOperationException(SR.GetString(SR.LinkedListNodeIsAttached));                
            }
        }

        /// <summary>
        /// 检查节点
        /// </summary>
        /// <param name="node">待检查的节点</param>
        internal void ValidateNode(LinkedListNode<T> node) {
            if (node == null) {
                throw new ArgumentNullException("node");                
            }

            if ( node.list != this) {
                throw new InvalidOperationException(SR.GetString(SR.ExternalLinkedListNode));
            }
        }

InternalInsertNodeBefore函数实现如下:

        /// <summary>
        /// 将指定的节点插入待指定的节点前
        /// </summary>
        /// <param name="node">指定的节点</param>
        /// <param name="newNode">待插入的节点</param>
        private void InternalInsertNodeBefore(LinkedListNode<T> node, LinkedListNode<T> newNode) {
            //新节点的后继节点指向指定的节点
            newNode.next = node;
            //新节点的前驱节点指定指定的节点的前驱节点
            newNode.prev = node.prev;
            //指定的节点前驱节点的后继节点执行新节点
            node.prev.next = newNode;
            //指定的节点的前驱节点指向新节点
            node.prev = newNode;            
            version++;
            count++;
        }

AddFirst函数和AddLast函数:

        /// <summary>
        /// 添加数据为头部
        /// </summary>
        /// <param name="value">待添加的数据</param>
        /// <returns></returns>
        public LinkedListNode<T> AddFirst(T value) {
            LinkedListNode<T> result = new LinkedListNode<T>(this, value);
            if (head == null) {
                InternalInsertNodeToEmptyList(result);
            } 
            else {
                InternalInsertNodeBefore( head, result);               
                head = result;                
            }
            return result;
        }

        /// <summary>
        /// 添加节点为头部
        /// </summary>
        /// <param name="node">待添加的节点</param>
        public void AddFirst(LinkedListNode<T> node) {
            ValidateNewNode(node);

            if (head == null) {
                InternalInsertNodeToEmptyList(node);
            } 
            else {
                InternalInsertNodeBefore( head, node); 
                head = node;                
            }
            node.list = this;
        }

        /// <summary>
        /// 添加数据为尾部
        /// </summary>
        /// <param name="value">待添加的数据</param>
        /// <returns></returns>
        public LinkedListNode<T> AddLast(T value) {
            LinkedListNode<T> result = new LinkedListNode<T>(this, value);        
            if (head== null) {
                InternalInsertNodeToEmptyList(result);
            } 
            else {
                InternalInsertNodeBefore( head, result);               
            }       
            return result;
        }

        /// <summary>
        /// 添加节点为头部
        /// </summary>
        /// <param name="node">待添加的节点</param>
        public void AddLast(LinkedListNode<T> node) {
            ValidateNewNode(node);            

            if (head == null) {
                InternalInsertNodeToEmptyList(node);
            } 
            else {
                InternalInsertNodeBefore( head, node); 
            }
            node.list = this;
        }

其中InternalInsertNodeToEmptyList函数实现如下:

        /// <summary>
        /// 将指定的节点插入到空链表
        /// </summary>
        /// <param name="newNode">待插入的节点</param>
        private void InternalInsertNodeToEmptyList(LinkedListNode<T> newNode) {
            Debug.Assert( head == null && count == 0, "LinkedList must be empty when this method is called!");
            newNode.next = newNode;
            newNode.prev = newNode;
            head = newNode;
            version++;
            count++; 
        }

Remove及其相关函数:

        /// <summary>
        /// 移除符合指定数据的节点
        /// </summary>
        /// <param name="value">指定的数据</param>
        /// <returns></returns>
        public bool Remove(T value) {
            LinkedListNode<T> node = Find(value);
            if (node != null) {
                InternalRemoveNode(node); 
                return true;
            }
            return false;
        }

        /// <summary>
        /// 移除指定节点
        /// </summary>
        /// <param name="node">指定的节点</param>
        public void Remove(LinkedListNode<T> node) {
            ValidateNode(node);          
            InternalRemoveNode(node); 
        }
                   
        /// <summary>
        /// 移除头节点
        /// </summary>
        public void RemoveFirst() {
            if ( head == null) { throw new InvalidOperationException(SR.GetString(SR.LinkedListEmpty)); }
            InternalRemoveNode(head);             
        }

        /// <summary>
        /// 移除尾节点
        /// </summary>
        public void RemoveLast() {
            if ( head == null) { throw new InvalidOperationException(SR.GetString(SR.LinkedListEmpty)); }
            InternalRemoveNode(head.prev);     
        }

而InternalRemoveNode函数实现如下:

        /// <summary>
        /// 移除指定的节点
        /// </summary>
        /// <param name="node">待删除的节点</param>
        internal void InternalRemoveNode(LinkedListNode<T> node) {
            Debug.Assert( node.list == this, "Deleting the node from another list!");   
            Debug.Assert( head != null, "This method shouldn't be called on empty list!");
            if ( node.next == node) {
                Debug.Assert(count == 1 && head == node, "this should only be true for a list with only one node");
                head  = null;
            } 
            else {
                //node的后继节点的前驱节点指向node的前驱节点
                node.next.prev = node.prev;
                //node的前驱节点的后继节点指向node的后继节点
                node.prev.next = node.next;
                //若node为头结点,则头结点的后继节点为头结点
                if ( head == node) {
                    head = node.next;
                }
            }
            node.Invalidate();  
            count--;
            version++;          
        }

引用一张图大致说一下节点的引用情况:

源码为.net 4.5.1;

.net源码网址:https://referencesource.microsoft.com/

注:本人水平有限,如果有错误,欢迎指正……

### RT-DETRv3 网络结构分析 RT-DETRv3 是一种基于 Transformer 的实时端到端目标检测算法,其核心在于通过引入分层密集正监督方法以及一系列创新性的训练策略,解决了传统 DETR 模型收敛慢和解码器训练不足的问题。以下是 RT-DETRv3 的主要网络结构特点: #### 1. **基于 CNN 的辅助分支** 为了增强编码器的特征表示能力,RT-DETRv3 引入了一个基于卷积神经网络 (CNN) 的辅助分支[^3]。这一分支提供了密集的监督信号,能够与原始解码器协同工作,从而提升整体性能。 ```python class AuxiliaryBranch(nn.Module): def __init__(self, in_channels, out_channels): super(AuxiliaryBranch, self).__init__() self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1) self.bn = nn.BatchNorm2d(out_channels) def forward(self, x): return F.relu(self.bn(self.conv(x))) ``` 此部分的设计灵感来源于传统的 CNN 架构,例如 YOLO 系列中的 CSPNet 和 PAN 结构[^2],这些技术被用来优化特征提取效率并减少计算开销。 --- #### 2. **自注意力扰动学习策略** 为解决解码器训练不足的问题,RT-DETRv3 提出了一种名为 *self-att 扰动* 的新学习策略。这种策略通过对多个查询组中阳性样本的标签分配进行多样化处理,有效增加了阳例的数量,进而提高了模型的学习能力和泛化性能。 具体实现方式是在训练过程中动态调整注意力权重分布,确保更多的高质量查询可以与真实标注 (Ground Truth) 进行匹配。 --- #### 3. **共享权重解编码器分支** 除了上述改进外,RT-DETRv3 还引入了一个共享权重的解编码器分支,专门用于提供密集的正向监督信号。这一设计不仅简化了模型架构,还显著降低了参数量和推理时间,使其更适合实时应用需求。 ```python class SharedDecoderEncoder(nn.Module): def __init__(self, d_model, nhead, num_layers): super(SharedDecoderEncoder, self).__init__() decoder_layer = nn.TransformerDecoderLayer(d_model=d_model, nhead=nhead) self.decoder = nn.TransformerDecoder(decoder_layer, num_layers=num_layers) def forward(self, tgt, memory): return self.decoder(tgt=tgt, memory=memory) ``` 通过这种方式,RT-DETRv3 实现了高效的目标检测流程,在保持高精度的同时大幅缩短了推理延迟。 --- #### 4. **与其他模型的关系** 值得一提的是,RT-DETRv3 并未完全抛弃经典的 CNN 技术,而是将其与 Transformer 结合起来形成混合架构[^4]。例如,它采用了 YOLO 系列中的 RepNCSP 模块替代冗余的多尺度自注意力层,从而减少了不必要的计算负担。 此外,RT-DETRv3 还借鉴了 DETR 的一对一匹配策略,并在此基础上进行了优化,进一步提升了小目标检测的能力。 --- ### 总结 综上所述,RT-DETRv3 的网络结构主要包括以下几个关键组件:基于 CNN 的辅助分支、自注意力扰动学习策略、共享权重解编码器分支以及混合编码器设计。这些技术创新共同推动了实时目标检测领域的发展,使其在复杂场景下的表现更加出色。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值