数组模拟链表(单链表,双链表)

结构体+指针实现链表

struct Node {
    int val;
    Node* next;
};

每次创建一个新链表,就要调用new,new Node()这个操作非常慢,在笔试中一般不采用,会超时。

这里介绍用数组模拟链表,也称静态链表。

单链表:邻接表,用来存储图和树。

双链表:优化某些问题。

1.数组模拟单链表

e[N]数组来存储每个节点的值,用ne[N]数组来存储每个节点的next指针是多少。e数组和ne数组是由下标关联起来。空节点的下标用-1表示。

 初始化单链表

//head 表示头节点的next指向,即ne[头节点]
//e[i] 表示节点i的值
//ne[i] 表示节点i的next指针是多少
//idx 存储当前已经用到哪个点

//初始化链表
void init()
{
    head = -1;  //头节点指向空
    idx = 0;
}

插入操作

  • 插到头节点的位置

将节点nx插入到head与n0节点中间。

插入操作后

//将x插入到头节点
void add_to_head(int x)  //x为节点x存储的值
{
    e[idx] = x;  //设置x节点的值
    ne[idx] = head; //step1: x节点的next指向head的指向
    head = idx;  //step2-3: head指向x节点
    idx ++;  //当前可用节点后移
}

初始化链表+在头节点处插入一个值为6的节点,代码详细过程

  •  插到任意位置
//将x插入到节点k后面
void add(int k, int x)
{
    e[idx] = x;
    ne[idx] = ne[k];
    ne[k] = idx;
    idx ++;
}

删除操作

删除n2节点,让n1的next指向n2的next指向(即n3)。

//删除节点k的下一个节点
void remove(int k)
{
    ne[k] = ne[ne[k]];
}

2. 数组模拟双链表

l[N]来表示某节点左边指向的一个节点,用r[N]来表示某节点右边指向的一个节点。

初始化双链表

//初始化
void init()
{
    l[1] = 0;  //节点1的左边是节点0
    r[0] = 1;  //节点0的右边是节点1
    idx = 2;
}

插入操作

在节点k的右边插入一个新节点。

step2和step3先后顺序不能变,如果先修改n1的右指针,那么待会儿n1的右指针就不再指向n2,要修改n2的左指针就不能通过step2的方法了。

//在节点k的右边插入一个点
void add(int k, int x)
{
    e[idx] = x;
    l[idx] = k;  //step1,该节点的左指针指向k
    r[idx] = r[k];  //step1,该节点的右指针指向k的右节点
    l[r[k]] = idx;  //step2,节点k的右节点的左指针指向该节点
    r[k] = idx;  //step3,节点k的右指针指向该节点
    idx ++;
}

在节点k的左边插入一个数,即在节点k左节点的右边插入一个数,调用add(l[k],x)即可。

初始化链表+在节点0右边插入一个值为6的节点。

 删除操作

删除节点k。

//删除节点k
void remove(int k)
{
    r[l[k]] = r[k];
    l[r[k]] = l[k];
}

  • 8
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值