【算法详解】链表

链表

0. 引言

开学快乐!!!!!!!

1. 单链表

1.1 链表代码

// head存储链表头,e[]存储节点的值,ne[]存储节点的next指针,idx表示当前用到了哪个节点
int head, e[N], ne[N], idx;

// 初始化
void init(){
    head = -1; //head的位置
    idx = 0; //存入的节点个数
}

// 在链表头插入一个数a //下标从0开始
void add_to_head(int x)
{
    e[idx] = x; //存入x
    ne[idx] = head; //节点的下一个为旧head,尾部为-1
    head = idx ++ ; //更新head并且, 存入的节点个数+1
}


// 将x插到下标是k的点后面
void add(int k, int x){
    e[idx] = x; //存入x
    ne[idx] = ne[k]; //当前节点指向原节点的下一个节点
    ne[k] = idx ++ ; //原节点指向当前节点, 并且存入的节点个数+1
}

// 将头结点删除,需要保证头结点存在
void remove_head(){
    head = ne[head]; //将head指向下一个节点
}

// 删除k后节点
void remove(int k){
    ne[k] = ne[ne[k]];//指向k后第二个节点,跳过k后第一个节点
}

// 遍历所有节点
for (int i = head; i != -1; i = ne[i])
    cout << e[i] << " ";

1.2 解释

准备工作

// head存储链表头,e[]存储节点的值,ne[]存储节点的next指针,idx表示当前用到了哪个节点
int head, e[N], ne[N], idx;

初始化

// 初始化
void init(){
    head = -1; //head的位置
    idx = 0; //存入的节点个数
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

表头插入数

// 在链表头插入一个数a
void add_to_head(int x)
{
    e[idx] = x; //存入x
    ne[idx] = head; //先更新尾链接-1的指向
    head = idx ++ ; //更新head并且, 存入的节点个数+1
}
  1. 存入 xxx

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. 更新

先更新尾链接 −1-11 的指向,再更新链表头的指向

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

xxx 插到下标是 kkk 的点后面

void add(int k, int x){
    e[idx] = x; //存入x
    ne[idx] = ne[k]; //当前节点指向原节点的下一个节点
    ne[k] = idx ++ ; //原节点指向当前节点, 并且存入的节点个数+1
}

简单来说插入节点就是存入节点,更新新节点指向下节点,原节点指向新节点3步骤

删除头节点

void remove_head(){
    head = ne[head]; //将head指向下一个节点
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

删除 kkk 后节点

void remove(int k){
    ne[k] = ne[ne[k]];//指向k后第二个节点,跳过k后第一个节点
}

2. 双链表

2.1 链表代码

#include<bits/stdc++.h>
using namespace std;

const int N = 1e5 + 10;
int e[N], l[N], r[N], idx;

// 初始化
void init(){
    r[0] = 1;
    l[1] = 0;
    idx = 2;
}

// 插入 //可以插入任意位置
void insert(int k, int x){
    e[idx] = x;
    l[idx] = k;
    r[idx] = r[k];
    l[r[k]] = idx;
    r[k] = idx ++;
}

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

int main(){
    int n;
    cin >> n;
    init();
    while(n --){
        string op;
        cin >> op;
        
        // 插入头
        if(op == "L"){
            int x;
            cin >> x;
            insert(0, x);
        }
        
        // 插入尾
        if(op == "R"){
            int x;
            cin >> x;
            insert(l[1], x);
        }
        
        // 删除
        if(op == "D"){
            int k;
            cin >> k;
            delete(k + 1);
        }
        
        // 插入左边
        if(op == "IL"){
            int k, x;
            cin >> k >> x;
            insert(l[k + 1], x);
        }
        
        // 插入右边
        if(op == "IR"){
            int k, x;
            cin >> k >> x;
            insert(k + 1, x);
        }
    }
    
    // 从右遍历
    for(int i = r[0]; i != 1; i = r[i]){
        cout << e[i] << ' ';
    }
    return 0;
}

2.2 详解

插入

// 插入 //可以插入任意位置
void insert(int k, int x){
    e[idx] = x;
    l[idx] = k;
    r[idx] = r[k];
    l[r[k]] = idx;
    r[k] = idx ++;
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

注意:这一步的步骤不能调换

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

删除

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

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值