C#数据结构与算法揭秘三 链表

作为一本通俗易懂的C#数据结构与算法书籍,其第三章主要介绍链表(Linked List)的概念和基本操作。下面是链表的基本概念:

  • 链表(Linked List)是一种动态数据结构,其中的元素按线性顺序排列,并且每个元素都称为一个结点(Node)。
  • 每个结点都包含一个元素和一个指向下一个结点的指针(Pointer)。
  • 相比于数组,链表的优势在于能够轻松地增加或减少链表中的元素。

链表基本操作:

1.头结点(head):链表的头结点是链表中的第一个结点。
2.尾结点(tail):链表的尾结点是链表中的最后一个结点。尾结点指向null。
3.添加结点(add):向链表添加新结点。有三种方法添加一个新节点:在开头添加、在结尾添加和在中间添加。
4.删除节点(delete):从链表中删除一个结点。有两种方法删除结点:根据结点元素删除和根据结点索引删除。
5.搜索结点(search):找到链表中包含指定元素或索引的结点。

其代码实现如下:

class LinkedListNode<T>
{
    public T Value;
    public LinkedListNode<T> Next;
}

class LinkedList<T> : IEnumerable<T>
{
    private LinkedListNode<T> _head;
    private LinkedListNode<T> _tail;

    public LinkedListNode<T> First
    {
        get { return _head; }
    }

    public LinkedListNode<T> Last
    {
        get { return _tail; }
    }

    public void AddFirst(T value)
    {
        LinkedListNode<T> node = new LinkedListNode<T> { Value = value };
        node.Next = _head;
        _head = node;

        if (_tail == null)
            _tail = node;
    }

    public void AddLast(T value)
    {
        LinkedListNode<T> node = new LinkedListNode<T> { Value = value };
        if (_tail == null)
        {
            _head = node;
            _tail = node;
        }
        else
        {
            _tail.Next = node;
            _tail = node;
        }
    }

    public void AddAfter(LinkedListNode<T> node, T value)
    {
        if (node == null)
            throw new ArgumentNullException(nameof(node));

        LinkedListNode<T> newNode = new LinkedListNode<T> { Value = value };
        newNode.Next = node.Next;
        node.Next = newNode;

        if (node == _tail)
            _tail = newNode;
    }

    public void RemoveFirst()
    {
        if (_head == null)
            throw new InvalidOperationException("LinkedList is empty");

        _head = _head.Next;

        if (_head == null)
            _tail = null;
    }

    public void RemoveLast()
    {
        if (_head == null)
            throw new InvalidOperationException("LinkedList is empty");

        if (_head == _tail)
        {
            _head = null;
            _tail = null;
            return;
        }

        LinkedListNode<T> current = _head;
        while (current.Next != _tail)
            current = current.Next;

        current.Next = null;
        _tail = current;
    }

    public void Remove(LinkedListNode<T> node)
    {
        if (node == null)
            throw new ArgumentNullException(nameof(node));

        if (_head == node)
        {
            RemoveFirst();
            return;
        }

        LinkedListNode<T> current = _head;
        while (current.Next != node)
        {
            current = current.Next;
            if (current == null)
                throw new InvalidOperationException("Node not found in LinkedList");
        }

        current.Next = node.Next;

        if (node == _tail)
            _tail = current;
    }

    public LinkedListNode<T> Find(T value)
    {
        LinkedListNode<T> current = _head;
        while (current != null && !current.Value.Equals(value))
            current = current.Next;

        return current;
    }

    public IEnumerator<T> GetEnumerator()
    {
        LinkedListNode<T> current = _head;
        while (current != null)
        {
            yield return current.Value;
            current = current.Next;
        }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

下面展示两个的示例说明:

1.在链表中搜索元素的示例:

int[] values = { 1, 2, 3, 4, 5 };
LinkedList<int> list = new LinkedList<int>(values);

LinkedListNode<int> node = list.Find(3);

if (node != null)
    Console.WriteLine("Node found: " + node.Value);
else
    Console.WriteLine("Node not found");

2.在链表中添加元素的示例:

LinkedList<int> list = new LinkedList<int>();

list.AddFirst(1);
list.AddFirst(2);
list.AddFirst(3);

list.AddLast(4);
list.AddLast(5);

list.AddAfter(list.Find(3), 6);

foreach (int value in list)
    Console.WriteLine(value);

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#数据结构与算法揭秘三 链表 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • golang中set数据结构的使用示例

    Golang中Set数据结构的使用示例 Set是一种无序的、元素不重复的数据结构。通过使用map来实现,map中的key即为Set中的元素,value则可以用来存储某种状态(比如计数)。 Set数据结构的定义 type Set struct { m map[interface{}]bool } Set数据结构的初始化 func NewSet() *Set {…

    数据结构 2023年5月17日
    00
  • 二叉搜索树的本质

    引言 打算写写树形数据结构:二叉查找树、红黑树、跳表和 B 树。这些数据结构都是为了解决同一个基本问题:如何快速地对一个大集合执行增删改查。 本篇是第一篇,讲讲搜索树的基础:二叉搜索树。 基本问题 如何在一千万个手机号中快速找到 13012345432 这个号(以及相关联信息,如号主姓名)? 最笨的方案 把一千万个手机号从头到尾遍历一遍,直到找到该手机号,返…

    算法与数据结构 2023年4月17日
    00
  • C语言数据结构时间复杂度及空间复杂度简要分析

    C语言数据结构时间复杂度及空间复杂度简要分析 什么是时间复杂度和空间复杂度? 在分析算法和数据结构的性能时,时间复杂度和空间复杂度是必须考虑的因素。 时间复杂度:衡量算法执行时间所需的资源,也就是算法的速度。通常使用“大O符号”来表示时间复杂度,例如O(1)、O(n)、O(nlogn)等。 空间复杂度:衡量算法使用的内存资源,也就是算法的空间利用率。通常使用…

    数据结构 2023年5月17日
    00
  • MySQL索引详解及演进过程及面试题延伸

    MySQL索引详解及演进过程及面试题延伸 索引的作用 在 MySQL 中,索引是一种数据结构,可用于快速查找和访问表中的数据。使用索引可以大大提高查询效率,特别是在大型数据表中。 索引可以看作是一本书中的目录,目录中列出了每个章节的页码,通过查询目录,读者可以快速找到感兴趣的章节。 索引的种类 MySQL 中支持多种类型的索引,下面我们介绍一下常见的索引类型…

    数据结构 2023年5月17日
    00
  • 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解

    解析从源码分析常见的基于Array的数据结构动态扩容机制的详解 什么是动态扩容机制 动态扩容机制是指,当一个数据结构达到其容量限制时,自动增加容量大小以继续存储新的数据。在动态扩容时,需要考虑到时间和空间的平衡,因为扩容需要分配新的内存空间,在处理大量数据时,需要尽可能减少空间浪费和分配内存的时间消耗。 基于Array的数据结构 Array是一种连续存储的数…

    数据结构 2023年5月17日
    00
  • JavaScript中的Map数据结构详解

    JavaScript中的Map数据结构详解 什么是Map数据结构 Map是JavaScript中一种新的数据结构,类似于对象,但是比对象更加灵活。Map可以将任意类型的值作为键名(包括对象、字符串、数字、布尔值等),并且不会将键名强制转换为字符串。Map的键值对个数没有限制,可以根据需要动态地增加或者删除键值对。Map内部实现了一个哈希表,因此增加、删除、查…

    数据结构 2023年5月17日
    00
  • 数据结构与算法之并查集(不相交集合)

    下面是详细的内容讲解。 数据结构与算法之并查集(不相交集合) 什么是并查集? 并查集,也叫不相交集合,是一种树形的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。常常是在使用 Kruskal 算法或者 Prim 算法来求解最小生成树(Minimum Spanning Tree)时用到的一种数据结构。 并查集的基本操作 Make…

    数据结构 2023年5月17日
    00
  • 动态开点线段树&线段树合并学习笔记

    动态开点线段树 使用场景 \(4 \times n\) 开不下。 值域需要平移(有负数)。 什么时候开点 显然,访问的节点不存在时(只会在修改递归时开点)。 trick 区间里面有负数时,\(mid = (l + R – 1) / 2\)。 防止越界。 例如区间 \([-1,0]\)。 开点上限 考虑到 update 一次最多开 \(\log V\) 个点(…

    算法与数据结构 2023年4月17日
    00
合作推广
合作推广
分享本页
返回顶部