백엔드 개발 C#.Net 튜토리얼 .NET Framework-이중 연결 목록(LinkedList) 코드 분석(그림)

.NET Framework-이중 연결 목록(LinkedList) 코드 분석(그림)

Mar 18, 2017 am 11:37 AM



.NET프레임워크의 LinkList는 이중 연결 목록을 구현합니다. 구현 소스 코드를 요약해 보겠습니다.

먼저 LinkedList에서 제공하는 공용 속성 및 메서드 맵을 살펴보세요.


.NET Framework-이중 연결 목록(LinkedList) 코드 분석(그림)

1 LinkedList에 의해 구현된 인터페이스:

public class LinkedList<T> : ICollection<T>, ICollection, IReadOnlyCollection<T>, ISerializable, IDeserializationCallback
로그인 후 복사

2 LinkedList의 전역 변수에는

head가 포함됩니다. 은 캡슐화된 클래스의 헤드 노드입니다.

        // This LinkedList is a doubly-Linked circular list.
        internal LinkedListNode<T> head;        
        internal int count;        
        internal int version;        
        private object _syncRoot;        
        //A temporary variable which we need during deserialization.  
        private SerializationInfo _siInfo; 

        // names for serialization
        private const string VersionName = "Version";        
        private const string CountName = "Count";  
        private const string ValuesName = "Data";
로그인 후 복사

캡슐화된 각 노드의 데이터 구조는 다음과 같습니다.

public sealed class LinkedListNode<T>
{   public LinkedListNode(T value);   
//获取LinkedListNode所属的LinkedList
   public LinkedList<T> List { get; }   
   public LinkedListNode<T> Next { get; }   
   public LinkedListNode<T> Previous { get; }   
   //获取节点中包含的值。
   public T Value { get; set; }
}
로그인 후 복사

3 생성자 :

        public LinkedList() //默认的构造函数
        {
        }        //带有参数的
        public LinkedList(IEnumerable<T> collection)
        {            if (collection == null)
            {                throw new ArgumentNullException(nameof(collection));
            }            foreach (T item in collection)
            {
                AddLast(item);
            }
        }
로그인 후 복사

는 IEnumerable 유형의 컬렉션을 구성할 때 AddLast(T) 메서드를 사용합니다. 여기에는 오버로드도 포함됩니다.

        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;
        }        

        public void AddLast(LinkedListNode<T> node)
        {
            ValidateNewNode(node);            
            if (head == null)
            {
                InternalInsertNodeToEmptyList(node);
            }            else
            {
                InternalInsertNodeBefore(head, node);
            }
            node.list = this; //结合LinkedListNode看
        }
로그인 후 복사

위 내용은 다음과 같습니다. 2가지 방법에서 의미론은 노드를 삽입하는 것입니다.
빈 목록에 새 노드를 삽입하고 InternalInsertNodeToEmptyList
비어 있지 않은 목록인 InternalInsertNodeBefore에 새 노드를 삽입하고 newNode가 삽입되기 전에 노드를 제공합니다. 또한 새로 삽입된 노드는 유효한 새 노드가 아니라고 판단합니다.

 internal void ValidateNewNode(LinkedListNode<T> node)
        {            if (node == null)
            {                throw new ArgumentNullException(nameof(node));
            }            if (node.list != null)
            {                throw new InvalidOperationException(SR.LinkedListNodeIsAttached);
            }
        }
로그인 후 복사

동시에 노드가 유효한 노드인지 확인하는 방법도 제공합니다.

        internal void ValidateNode(LinkedListNode<T> node)
        {            if (node == null)
            {                throw new ArgumentNullException(nameof(node));
            }            if (node.list != this)
            {                throw new InvalidOperationException(SR.ExternalLinkedListNode);
            }
        }
로그인 후 복사

이것은 이중 연결 목록의 중요한 내부 방법입니다

InternalInsertNodeToEmptyList의 구현 세부 사항:

        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++;
        }
로그인 후 복사

InternalInsertNodeBefore 구현 세부 사항:

        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++;
        }
로그인 후 복사

4 연결된 목록은 노드를 삽입하는 공용 메서드

        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;
        }        public void AddAfter(LinkedListNode<T> node, LinkedListNode<T> newNode)
        {
            ValidateNode(node);
            ValidateNewNode(newNode);
            InternalInsertNodeBefore(node.next, newNode);
            newNode.list = this;
        }        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;
        }        public void AddBefore(LinkedListNode<T> node, LinkedListNode<T> newNode)
        {
            ValidateNode(node);
            ValidateNewNode(newNode);
            InternalInsertNodeBefore(node, newNode);
            newNode.list = this;            if (node == head)
            {
                head = newNode;
            }
        }        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;
        }        public void AddFirst(LinkedListNode<T> node)
        {
            ValidateNewNode(node);            if (head == null)
            {
                InternalInsertNodeToEmptyList(node);
            }            else
            {
                InternalInsertNodeBefore(head, node);
                head = node;
            }
            node.list = this;
        }        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;
        }        public void AddLast(LinkedListNode<T> node)
        {
            ValidateNewNode(node);            if (head == null)
            {
                InternalInsertNodeToEmptyList(node);
            }            else
            {
                InternalInsertNodeBefore(head, node);
            }
            node.list = this;
        }
로그인 후 복사

5와 자연스럽게 분리될 수 없습니다. 다시 보면 연결리스트에 있는 모든 노드를 삭제하고, 여기에서는 모든 노드가 메모리 힙을 가리키지 않도록 설정한 다음 GC 재활용을 기다리는 것인데,

        public void Clear()
        {
            LinkedListNode<T> current = head;            
            while (current != null)
            {
                LinkedListNode<T> temp = current;
                current = current.Next;   
                // use Next the instead of "next", otherwise it will loop forever
                temp.Invalidate();
            }

            head = null;
            count = 0;
            version++;
        }
로그인 후 복사

6에 해당하는 것은 a만 제거하는 것입니다. 추가와 유사하며 자세히 설명하지 않을 특정 노드의 일련의 인터페이스

Clear는 Invalidate()를 호출하고 구현은 매우 간단합니다.

        internal void Invalidate()
        {
            list = null;
            next = null;
            prev = null;
        }
로그인 후 복사

7 결정하려면 노드 값이 값으로 존재하면 Find 메서드,

        public bool Contains(T value)
        {            return Find(value) != null;
        }
로그인 후 복사

Find 메서드 구현 세부 정보를 호출합니다. API 및 FindLast와 유사합니다. 연결 목록 방식이므로 끝에서 연결 목록을 순회하세요.

       public LinkedListNode<T> Find(T value)
        {
            LinkedListNode<T> node = head;            
            //调用默认相等比较器
            EqualityComparer<T> c = EqualityComparer<T>.Default;            
            if (node != null)//链表为null
            {                
            if (value != null) 
                {                    
                do
                    {                        
                    if (c.Equals(node.item, value)) //Equals:某个节点node的item与value相等
                        {                            
                        return node;
                        }
                        node = node.next;
                    } while (node != head);
                }                
                else
                {                    
                do
                    {                        
                    if (node.item == null)
                        {                            
                        return node; 
                        }
                        node = node.next;
                    } while (node != head);
                }
            }            return null; //链表为null,直接返回null
        }
로그인 후 복사

8 배열 구현에 대한 또 다른 데이터 복사본을 살펴보겠습니다.

        public void CopyTo(T[] array, int index)
        {            
        if (array == null)
            {                
            throw new ArgumentNullException(nameof(array));
            }            
            if (index < 0)
            {                
            throw new ArgumentOutOfRangeException(nameof(index), index, SR.ArgumentOutOfRange_NeedNonNegNum);
            }            
            if (index > array.Length)
            {                
            throw new ArgumentOutOfRangeException(nameof(index), index, SR.ArgumentOutOfRange_BiggerThanCollection);
            }            
            if (array.Length - index < Count)
            {                
            throw new ArgumentException(SR.Arg_InsufficientSpace);
            }

            LinkedListNode<T> node = head;            
            if (node != null)
            {
                do
                {
                    array[index++] = node.item;
                    node = node.next;
                } while (node != head); //双向链表,再次遍历到头结点时
            }
        }
로그인 후 복사

위 내용은 .NET Framework-이중 연결 목록(LinkedList) 코드 분석(그림)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

뜨거운 기사 태그

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

LinkedList 클래스의 RemoveLast() 메소드를 사용하여 연결된 목록의 마지막 요소를 삭제합니다. LinkedList 클래스의 RemoveLast() 메소드를 사용하여 연결된 목록의 마지막 요소를 삭제합니다. Jul 24, 2023 pm 05:13 PM

LinkedList 클래스의 RemoveLast() 메소드를 사용하여 연결된 목록의 마지막 요소를 삭제합니다.

C++를 사용하여 주어진 크기로 역방향 이중 연결 목록 그룹화 C++를 사용하여 주어진 크기로 역방향 이중 연결 목록 그룹화 Sep 04, 2023 am 09:49 AM

C++를 사용하여 주어진 크기로 역방향 이중 연결 목록 그룹화

Java 문서 해석: LinkedList 클래스의 addFirst() 메소드 함수 분석 Java 문서 해석: LinkedList 클래스의 addFirst() 메소드 함수 분석 Nov 03, 2023 am 09:09 AM

Java 문서 해석: LinkedList 클래스의 addFirst() 메소드 함수 분석

LinkedList에 요소를 추가하는 Java 프로그램 LinkedList에 요소를 추가하는 Java 프로그램 Aug 26, 2023 pm 10:21 PM

LinkedList에 요소를 추가하는 Java 프로그램

LinkedList.addFirst() 메서드를 사용하여 Java에서 연결된 목록의 헤드에 요소를 추가하는 방법은 무엇입니까? LinkedList.addFirst() 메서드를 사용하여 Java에서 연결된 목록의 헤드에 요소를 추가하는 방법은 무엇입니까? Nov 18, 2023 pm 03:51 PM

LinkedList.addFirst() 메서드를 사용하여 Java에서 연결된 목록의 헤드에 요소를 추가하는 방법은 무엇입니까?

Java 문서 해석: LinkedList 클래스의 getFirst() 메소드 기능 분석 Java 문서 해석: LinkedList 클래스의 getFirst() 메소드 기능 분석 Nov 04, 2023 am 08:02 AM

Java 문서 해석: LinkedList 클래스의 getFirst() 메소드 기능 분석

Jul 24, 2023 pm 06:52 PM

LinkedList 클래스의 addFirst() 메서드를 사용하여 Java에서 연결 목록의 시작 부분에 요소를 추가합니다. LinkedList 클래스의 addFirst() 메서드를 사용하여 Java에서 연결 목록의 시작 부분에 요소를 추가합니다. Jul 26, 2023 pm 03:05 PM

LinkedList 클래스의 addFirst() 메서드를 사용하여 Java에서 연결 목록의 시작 부분에 요소를 추가합니다.

See all articles