对用数组模拟单链表的理解

本文详细介绍了如何使用数组来模拟单链表的数据结构,包括头结点、结点插入、特定位置插入和删除操作。在数组中,通过下标关联value值和next指针,并通过一个idx指针跟踪数组末尾。初始化时,头结点设为-1,idx设为0。添加元素时,idx会更新;删除操作则只需改变指针的指向。注意,当链表只剩一个元素时,删除操作会导致链表为空,此时头指针需指向空结点。
摘要由CSDN通过智能技术生成

用数组模拟单链表

1.value值与next指针的存放
实际的单链表中每个结点中存放两个值,一个是value值,一个是next指针。
用数组来模拟的话,由于数组的一个位置只能存放一个值,所以我们需要两个数组来存放。
在这里,我们使用e[]数组存放每个结点的value值,ne[]数组存放每个结点的next指针。

2.e[]数组与ne[]数组如何联系起来?
通过下标
实际的单链表中一个结点和它后面的结点连接起来通过的是该结点next指针存放后面结点的地址。
用数组来模拟的话,可以用e[]数组的下标来模拟结点的地址,所以ne[]数组中存放的就是后一个
结点的的e[]数组的下标。

3.head头结点
确定一个实际的单链表在哪里是通过头结点,头结点是一个具有结点结构的指针。
用数组模拟的话头结点也是必不可少的。

4.结点的插入
向实际的单链表中插入一个结点,不需要考虑空间不够的问题,而且任何位置都可以。
用数组模拟的话,数组是有空间限制的,向它里面加入元素也可以在任意位置,但是很麻烦,
需要移动很多元素,所以在数组的最后添加元素是最方便的。要实现每次添加的元素都在
数组的最后一个位置,我们就要用一个指针记住数组每插入一个元素后,最后一个元素后面
的位置。这里这个指针我们用idx。

5.单链表的初始化
实际初始化一个单链表,是让头结点指向一个空结点
用数组来模拟的话,我们设定空结点的地址为-1,让头指针的值设定为-1。
idx指针的值我们设定为0。因为后面如果要加元素,就是在下标为0的位置。
idx指针是为下一个可能的插入操作作准备的,所以它指向的位置是数组中最后一个元素的后面
一个位置。刚开始的时候,数组是空的,所以此时数组中最后一个元素的后面一个位置就是数组
的第一个位置,即下标为0的位置。
void init( )
{
  head = -1;
  idx = 0;
}

6.单链表将x插入到头结点
对于一个实际的单链表而言,将x插入到头结点就是分配一个结点空间,将x放进去,
然后将x的next指针指向头指针原来指向的数,之后将头指针指向x所在结点。
用数组模拟的话,就是将x放入e[]数组中,分配空间的下标就是idx,结点的创建就完成了。
接着我们来建立它们之间的联系,让x的ne[]存放头指针原来指向的数的下标,头指针存放x的下标。
此时x的下标就是恰好就是idx。插入操作完成后,idx要向后走一步,因为它永远指向e[]数组中
最后一个元素后面一个位置。也就是说,每一次插入结束之后,idx的值就要更新,加1。
对于指针来说,位于赋值号左边表示它里面存放的地址;位于右边,表示它指向的空间的地址。
void add_to_head(int x)
{
  e[idx] = x, ne[idx] = head, head = idx++;
}

7.在单链表中某一个特定位置的后面插入x
对于实际的单链表而言,实现上述过程就是分配一个结点空间,将x放进去,
然后将x的next指针指向特定位置原来指向的数,之后将特定位置的指针指向x所在结点。
用数组模拟的话,将是将x放入e[]数组中下标为idx的位置,因为这就是给它分配的空间,
完成了这一步,结点的创建就完成了。接下来我们建立联系,让x的ne[]存放特定位置
原来指向数的下标,特定位置的ne[]上的值需要更新,因为它要指向x了,更新为x的下标,
就是idx。插入结束之后,idx的值更新,加1。
void add(int k, int x)
{
  e[idx] = x, ne[x] = ne[k], ne[k] = idx++;
}

8.将单链表中某一个特定位置的后面的结点删除
对于实际的单链表而言,实现上述过程就是将特定位置的next指针该向,越过它后面的结点,
指向它后面的第二个结点。
用数组模拟的话,就是将特定位置的ne[]存放头后面的第二个结点的下标。其实特定位置后面
的结点并没有从数组中删除,它还在原位置上,只是没有结点的ne[]存放它的下标了。idx的
值不需要更新。
void remove(int k)
{
   ne[k] = ne[ne[k]];
}

总结:只有插入操作,idx的值才会更新。
------------------------------------------------
本题保证所有操作都是有效的。
做所有操作之前的第一步是初始化链表。

该题由于它给出的是地址是1开始的,而数组的下标是从0开始的,所以这里需要做一些处理。

调用add()函数、remove()是要给k减1。
remove()函数还有一个注意点就是当数组中只有一个元素时,无法删除。因为它的功能是删除
某一个特定位置后面一个元素。当数组中只有一个元素时,你想删除它无法找到参照位置。
所以这个时候你可以通过让头指针该向,越过这个元素,指向空结点,那么这个时候链表空了。
这个情形下,k=0。所以可以做的处理是:if(!k) head=ne[head];

调用add_to_head()函数是不需要特殊处理,因为传递的仅仅是结点的值。

输出链表时,是通过遍历ne[]数组,从头指针开始,以空结点前面一个位置结束,输出对应的e[]数组中的value值。
for(int i = head; i!=-1; i = ne[i]) cout << e[i] <<' ';


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值