C#数据结构与算法学习笔记 链表

1. 什么是链表

    class LinkedList1<E>
    {
        private class Node
        {
            public E e;         //实际存储的元素,E类型的泛型,支持任意类型的数组
            public Node next;   //记录当前节点的下一个节点

            public Node(E e,Node next)  //用构造函数对这个类进行初始化
            {
                this.e = e;
                this.next = next;
            }

            public Node(E e)            //用户不知道下一个节点是什么
            {
                this.e = e;
                this.next = null;       //这个节点没有下一个节点
            }

            public override string ToString()
            {
                return e.ToString();
            }
        }

        private Node head;          //记录链表的头部

        private int N;              //记录链表存储了多少元素

        public LinkedList1()
        {
            head = null;
            N = 0;
        }

        //链表不具备容量概念,有多少元素就创建多少个节点,没有容量的限制

        //存储数量
        public int Count 
        { 
            get { return N; }  
        }

        //判断是否为空
        public bool IsEmpty
        {
            get { return N == 0; }
        }
    }

2.往链表添加节点

        //添加
        public void Add(int index, E e)
        {
            if (index < 0 || index > N)
            {
                throw new ArgumentException("非法索引!");
            }
            if (index == 0)
            {
                Node node = new Node(e);
                node.next = head;
                head = node;

                //此处也可以用一行代码:
                //head = new Node(e, head);
            }
            else
            {
                Node pre = head;    //从头部开始查找(要插入节点的前一个)节点
                for (int i = 0; i < index - 1; i++)
                    //因为要在index位置插入新节点,所以要找到index位置前一个节点
                    pre = pre.next;

                Node node = new Node(e);
                node.next = pre.next;
                pre.next = node;

                //此处也可以用一行代码:
                //pre.next = new Node(e, pre.next);
            }

            N++;
        }

        public void AddFirst(E e)
        {
            Add(0, e);
        }
        public void AddLast(E e)
        {
            Add(N, e);
        }

3.查询、修改、包含、打印

查询:

        //查询
        public E Get(int index)
        {
            if (index < 0 || index >= N)
                throw new ArgumentException("非法索引!");

            Node cur = head;
            for (int i = 0; i < index; i++)
                cur = cur.next;

            return cur.e;
        }
        public E GetFirst()
        {
            return Get(0);
        }
        public E GetLast()
        {
            return Get(N - 1);
        }

修改:

        //修改
        public void Set(int index, E newE)
        {
            if (index < 0 || index >= N)
                throw new ArgumentException("非法检索!");

            Node cur = head;
            for (int i = 0; i < index; i++)
                cur = cur.next;

            cur.e = newE;
        }

包含:

        //包含
        public bool Contains(E e)
        {
            Node cur = head;
            while (cur != null)
            {
                if (cur.e.Equals(e))
                    return true;

                cur = cur.next;
            }
            return false;
        }

打印:

        //打印
        public override string ToString()
        {
            StringBuilder res = new StringBuilder();
            Node cur = head;
            while (cur!=null)
            {
                res.Append(cur + " -> ");
                cur = cur.next;
            }
            res.Append("Null");
            return res.ToString();
        }

4.删除链表中的节点


        //删除
        public E RemoveAt(int index)
        {
            if (index < 0 || index >= N)
                throw new ArgumentException("非法检索!");

            if (index == 0)             //删除头部节点
            {
                Node delNode = head;
                head = head.next;
                N--;
                return delNode.e;
            }
            else                        //删除中间或尾部的节点
            {
                Node pre = head;
                for (int i = 0; i < index - 1; i++)
                    pre = pre.next;

                Node delNode = pre.next;
                pre.next = delNode.next;
                N--;
                return delNode.e;
            }
        }

        //删除指定结点
        public void Remove(E e)
        {
            if (head == null)
                return;

            if (head.e.Equals(e))
            {
                head = head.next;
                N--;
            }
            else
            {
                Node cur = head;
                Node pre = null;
                while (cur != null)
                {
                    if (cur.e.Equals(e))    //遍历过程中发现这个结点就是要找的结点,则退出循环
                    {
                        pre.next = cur.next;
                        break;
                    }
                    else
                    {
                        pre = cur;              //否则给指针进行赋值移动
                        cur = cur.next;
                    }
                }
                N--;
            }
        }

5.时间复杂度分析









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值