数据结构:单链表

单链表

主要思想:使用数组实现链表(而不用结构体,结构体代码更长,后续图论也是基于数组实现),即静态链表。因为动态链表使用new申请空间需要较多的时间,而算法要求的是以较少的时间完成任务。

  • 单链表:最主要用单链表写邻接表,用邻接表存储图或者树;
  • 双链表:优化某些问题

单链表:头指针head指向第一个结点,初始为-1.数组e[]存储结点的值,数组ne[]存储对应结点的下一个结点的下标,形成一个链条。本质是用数组下标来操作对应结点。

需要背过的板子:

cpp 复制代码
const int N=100010;

//head表示头节点的下标
//e[i]表示节点i的值
//ne[i]表示节点i的next指针是多少
//idx存储当前已经用到了哪个点
int head,e[N],ne[N],idx=0;


void init(){
    head=-1;//空
    idx=0;//当前可以从0号点开始用
}

//在链表头插入一个x
void add_to_head(int x){
    e[idx] = x;//存值
    ne[idx] = head;//next指向head指的
    head = idx;//head指向idx的位置
    idx ++;//idx后移
}

//将x插入到下标为k的点的后面
void add(int k,int x){
    e[idx] = x;
    ne[idx] = ne[k];
    ne[k] = idx;
    idx ++;
}

//将下标是k的点后面的一个点删掉
void remove(int k){
    ne[k] = ne[ne[k]];
}

我们通过一个题目来实战一下。

实现一个单链表,链表初始为空,支持三种操作:

1.向链表头插入一个数;

2.删除第 k 个插入的数后面的一个数;

3.在第 k个插入的数后插入一个数。

现在要对该链表进行 M 次操作,进行完所有操作后,从头到尾输出整个链表。


输入样例:

10

H 9

I 1 1

D 1

D 0

H 6

I 3 6

I 4 5

I 4 5

I 3 4

D 6

输出样例:

6 4 6 5

实现思路:

  • 设置数组e[]存储节点值,数组ne[]存储对应节点下一个节点的下标;
  • 设置头指针head指向第一个节点,初始值为-1;
  • 设置指针idx表示当前操作位置,初始为0即指向数组的第一个位置,单增;

样例模拟如下图所示:

代码实现:

cpp 复制代码
#include <iostream>

using namespace std;

const int N=100010;

//head表示头节点的下标
//e[i]表示节点i的值
//ne[i]表示节点i的next指针是多少
//idx存储当前已经用到了哪个点
int head,e[N],ne[N],idx=0;


void init(){
    head=-1;//空
    idx=0;//当前可以从0号点开始用
}

//在链表头插入一个x
void add_to_head(int x){
    e[idx] = x;//存值
    ne[idx] = head;//next指向head指的
    head = idx;//head指向idx的位置
    idx ++;//idx后移
}

//将x插入到下标为k的点的后面
void add(int k,int x){
    e[idx] = x;
    ne[idx] = ne[k];
    ne[k] = idx;
    idx ++;
}

//将下标是k的点后面的一个点删掉
void remove(int k){
    //当让在这特判进行删除头节点也可以
    //if(k==-1) head=ne[head];
    ne[k] = ne[ne[k]];
}


int main(){
    int m;
    cin >> m;
    init();
    while(m--){
        char s; cin >> s;
        int k,x;
        if(s == 'H'){
            cin >> x;
            add_to_head(x);
        }
        else if(s == 'D'){
            cin >> k;
            if(k == 0) head = ne[head];//删除头节点
            //特判可以放在删除函数中~
            remove(k-1);//函数中传的是下标,为k-1
        }
        else if(s == 'I'){
            cin >> k >> x;
            add(k-1,x);//函数中传的是下标,为k-1
        }
    }
    for(int i = head;i !=-1 ;i = ne[i]) cout<<e[i]<<' ';//遍历输出也背住
    cout<<endl;
    
    return 0;
}

好的,以上就是数组模拟单链表的一些内容啦~

相关推荐
大胆飞猪1 小时前
C++9--前置++和后置++重载,const,日期类的实现(对前几篇知识点的应用)
c++
1 9 J1 小时前
数据结构 C/C++(实验五:图)
c语言·数据结构·c++·学习·算法
夕泠爱吃糖1 小时前
C++中如何实现序列化和反序列化?
服务器·数据库·c++
长潇若雪1 小时前
《类和对象:基础原理全解析(上篇)》
开发语言·c++·经验分享·类和对象
汝即来归1 小时前
选择排序和冒泡排序;MySQL架构
数据结构·算法·排序算法
染指11103 小时前
50.第二阶段x86游戏实战2-lua获取本地寻路,跨地图寻路和获取当前地图id
c++·windows·lua·游戏安全·反游戏外挂·游戏逆向·luastudio
Code out the future4 小时前
【C++——临时对象,const T&】
开发语言·c++
sam-zy4 小时前
MFC用List Control 和Picture控件实现界面切换效果
c++·mfc
aaasssdddd964 小时前
C++的封装(十四):《设计模式》这本书
数据结构·c++·设计模式
芳菲菲其弥章4 小时前
数据结构经典算法总复习(下卷)
数据结构·算法