线性表之链式储存——双向链表

本文通过C#深入探讨双向链表,包括其特点、用途和实现方式。重点介绍了双向链表如何解决顺序表增删操作性能问题及单链表查询效率低下的问题,帮助读者更好地理解和应用双向链表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文将会根据c#从双链表的特点、用途、实现来介绍双向链表。本人属于“懒散型”不逼到最后就不会去总结的人,实在是遇到双向链表问题较为频繁,错失众多机会,今在这不得不总结一下,让自己去更好的了解一下。(看到一句话挺好的:Technology is all!)

首先要知道的是:当我们碰见一个新的东西要去了解一下它是用来解决哪个问题的,才会能更好的理解好使用它。

链表的特点:一组任意储存单元来存储线性表的数据元素,每个数据元素不仅储存本身信息之外还需要储存指向另一个数据元素的信息。双向链表即数据元素除了储存自身信息外还储存指向上一个数据元素和下一个数据元素的两个信息。

链表的用途:所有的数据容器无非就是用来储存和管理需要的数据,即数据的增、删、改、查。双向链表的存在就是为了解决顺序表增删的耗费性能,单链表查询耗性能的问题。(由于链表申请的内存在堆中且位置是任意的,因此在增删时不必像顺序表一样需要依次移动后续元素。双向链表的数据元素储存了指向它的前驱元素和后继元素信息,因此查询时不必像单链表一样只能从头节点开始查询)

双向链表的实现:除了c#封装好的链表,自己去实现一个链表会对它有更好的理解。

using System;
//using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 双向链表
{
    class Program
    {
        public static LinkList<int> intlist = new LinkList<int>();
        static void Main(string[] args)
        {
            intlist.AddData(1);
            intlist.AddData(2);
            intlist.AddData(3);

            Console.WriteLine(intlist.GetNode(1).Data);
            intlist.Append(1,4);
            Console.ReadKey();
        }
    }

    //双向链表的节点类  //里面存放数据信息和  指向 前驱数据元素和后继元素的信息  指针
    public class LinkListNode<T>
    {
        public T Data;//储存的信息
        public LinkListNode<T> Next;//指向后继的指针
        public LinkListNode<T> Prev;//指向前驱的指针

        public LinkListNode(T date)
        {
            this.Data = date;
        }

        ///构造函数
        public LinkListNode(T data, LinkListNode<T> next, LinkListNode<T> prev)
        {
            this.Data = data;
            this.Next = next;
            this.Prev = prev;
        }
    }

    //双向链表操作  //链表的 增 删 改 查
    public class LinkList<T>
    {
        public readonly LinkListNode<T> LinkHead;//链表的表头 声明链表就是声明一个表头初始化表头
        public int Size;
        public LinkList()
        {
            //default关键字  类型的默认值 引用类型 null  int类型 0  bool类型 false
            LinkHead = new LinkListNode<T>(default(T), null, null);
            LinkHead.Next = LinkHead;
            LinkHead.Prev = LinkHead;
            Size = 0;
        }

        public bool IsEmpty() => (Size == 0);
        public int GetSize() => (Size);

        //添加数据元素
        public void AddData(T t)
        {
            LinkListNode<T> node = new LinkListNode<T>(t);
            if (Size.Equals(0))
            {
                LinkHead.Next = node;
                LinkHead.Prev = node;
                node.Prev = LinkHead;
                node.Next = LinkHead;
            }
            else
            {
                node.Next = LinkHead;
                node.Prev = LinkHead.Prev;
                LinkHead.Prev = node;
                LinkHead.Prev.Prev.Next = node;
            }

            Size++;
        }

        //通过下表查找数据元素(节点)
        public LinkListNode<T> GetNode(int index)
        {
            if (index < 0 || index >= Size)
            {
                throw new IndexOutOfRangeException("下标有错");
            }
            //正向查找
            LinkListNode<T> node = LinkHead;
            if (index < Size / 2)
            {
                for (int i = 0; i < Size / 2; i++)
                {
                    node = node.Next;
                }
            }
            if (index >= Size / 2)
            {
                for (int i = 0; i < Size - index; i++)
                {
                    node = node.Prev;
                }
            }
            return node;
        }

        //在index下标插入数据元素t
        public void Append(int index, T t)
        {
            LinkListNode<T> node = new LinkListNode<T>(t);
            LinkListNode<T> node1 ;
            if (index < 0 || index >= Size)

            {
                throw new IndexOutOfRangeException("下标有错");
            }
            else
            {
                node1 = GetNode(index);
                node.Next = node1;
                node.Prev = node1.Prev;
                node1.Prev.Next = node;
                node1.Prev = node;

                Size++;
            }
        }

        //删除下表index的数据元素
        public void Delete(int index)
        {
            LinkListNode<T> node = GetNode(index);
            node.Prev.Next = node.Next;
            node.Next.Prev = node.Prev;
            Size--;
        }

        //改变下标的值
        public void ChangeDate(int index, T t)
        {
            LinkListNode<T> node = GetNode(index);
            node.Data = t;
        }

    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值