单链表

线性表的一种常见存在形式,链表。在链式存储的过程中,每个元素Node不仅包含元素本身的信息,还包含元素之间的逻辑信息。前驱结点包含后继结点的地址信息(指针域),可以很方便的找到后继结点的位置。

今天先来认识一下单链表:每个结点除包含数据域外,只设置一个指针域,来指向后继结点,这样构成的链表就是单链表。

在链表中都会有一个头指针,便于插入和删除,可以通过头结点,沿着链,遍历每一个链表中的结点。

单向链表中结点的结构:

单链表结构:

终端指针域为空,表示链表的结束。

简单实现一下单链表:

定义链表单个结点类:

 class Node
    {
        public Node(object value)
        {
            item = value;
        }
        //数据
        public object item;
        //指针(指向后继结点)
        public Node next;


    }

单链表类:

 class SingleLinkList
    {
        //元素个数
        private int count;
        public int Count
        {
            get
            {
                return count;
            }
        }

        //头结点
        private Node headNode; 
}

通过索引获取指定元素

   //查找指定索引下的元素
        public Node GetByIndex(int index)
        {
            if (index < 0 || index >= count) 
            {
                throw new ArgumentOutOfRangeException("index", "Out Of Range");
            }
            Node temp = headNode;
            //通过头结点 往下找
            for (int i = 0; i < index; i++)
            {
                temp = temp.next;
            }
            return temp;
        }

添加元素

  //在链表尾部插入元素
        public void AddToLast(object value)
        {
            // 在链表结尾处添加
            Node newNode = new Node(value);
            if (headNode == null)
            {
                //链表为空,直接作为头结点
                headNode = newNode;
            }
            else
            {
                //插入链尾
                GetByIndex(count - 1).next = newNode;
            }
            count++;
        }

        //在指定索引处插入元素
        public void AddToIndex(int index ,object value)
        {
            Node tempNode;
            if (index==0)
            {
                if (headNode==null)
                {
                    headNode = new Node(value);
                }
                else
                {
                    tempNode = new Node(value);
                    //修改指针
                    tempNode.next = headNode;
                    headNode = tempNode;
                }
            }
            else
            {
                //插入点前后结点
                Node preNode = GetByIndex(index - 1);
                Node nextNode = preNode.next;
                tempNode = new Node(value);
                preNode.next = tempNode;
                tempNode.next = nextNode;
            }
            count++;
        }

移除指定索引位置元素,输出链表元素

  //移除指定索引的元素
        public void RemoveAt(int index)
        {
            if (index==0)
            {
                headNode = headNode.next;
            }
            else
            {
                Node preNode = GetByIndex(index - 1);
                if (preNode.next==null)
                {
                    throw new ArgumentOutOfRangeException("index", "Out Of Range");
                }
                else
                {
                    //同样修改指针所指
                    preNode.next = preNode.next.next;
                }
            }
            count--;
        }


        //输出链表的元素
        public string ConsoleContent()
        {
            string str = "";
            for (Node temp = headNode; temp != null; temp = temp.next)
            {
                str += temp.item.ToString() + " ";
            }
            return str;
        }

    }

被删除的结点并没有立即在内存中被真正删除,还在原来位置,直到GC运行时才会被真正删除。

测试如下:


            SingleLinkList TempList = new SingleLinkList();
            Console.WriteLine("元素个数:"+TempList.Count);
            TempList.AddToLast(2);
            TempList.AddToLast(3);
            Console.WriteLine(TempList.ConsoleContent());
            TempList.AddToIndex(1,4);
            TempList.AddToIndex(2, 5);
            Console.WriteLine(TempList.ConsoleContent());
            TempList.RemoveAt(3);
            Console.WriteLine(TempList.ConsoleContent());
            Console.WriteLine("元素个数:"+TempList.Count);
            Console.ReadKey();

总的来说单链表的操作很简单, 与顺序表比较来说,不需要移动元素,但是元素的定位,会导致效率下降,特别在元素很多的时候。微软给出的建议使用在十个或者10个一下元素。

我们可以尝试给单链表添加尾指针,来迅速地定位到尾节点,当我们遇到只添加数据,而很少删除数据的时候,那么这种链表就会非常合适,之后会修改这个单链表的代码,给它添加一个tail尾指针来解决这种效率问题~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值