数组模拟链表【静态链表】

前言

链表实现我们主要通过动态链表,即指针+结构体,但是这种方法存在一定效率问题,例如我们在插入节点时需要创建一个新节点,即new Node,这种方法在c++中比较耗时,当链表中数据量比较大的时候,那么这种实现方法可能会存在超时问题,所以我们在这里引入静态链表,即通过数组模拟链表。

一、准备

我们这里通过两个数组,一个为data[n]用来表示这个节点的值域,一个为next[n]用来表示当前节点的指针域,在我们这里即下个节点的下标。这两个通过下标n进行关联。最开始的时候,链表的头节点要指向-1,表示链表里面没有元素,所以我们定义一个头节点下标head,我们可以把它看作一个特殊的指针,在链表里有元素的时候,它变成了一个指向第一个元素的指针。最后我们还要定义一个idx,也可以看作一个指针,表示当前链表分配到了哪,即那个位置我们可以继续使用。

int Data[N],Next[N],head,ind;

二、相关操作

1.初始化

初始化的时候需要把head定义为-1,表示头节点指向空集,因为我们的链表现在还没有元素。idx定义为0,因为我们可以从0这个位置开始分配。
代码如下(示例):

void init(){
    head=-1,ind=0;
}

2.插入

头插法

我们先讲讲最简单的头插法吧:
在这里插入图片描述
(手画有点丑,大家就凑合看看哈)
我在这里表示的是头插法,主要是四个操作。
1.将这个节点的值域保存,即Data[ind]=item
2.将这个节点的指针指向头节点指向的节点,在图中为第二个红箭头,即Next[ind]=head
3.将头节点指向我们插入的节点,在图中为第一个红箭头head=ind
4.因为我们下标为idx的这个点已经使用,所以idx++
所以这一操作的代码如下:

void inserthead(int item){
    Data[ind]=item;
    Next[ind]=head;
    head=ind;
    ind++;
}

在给定位置后插入

接下来我们在讲讲指定位置插入,让我们将新节点插到第k个插入点的后面,即下标为k-1的点的后面插入一个新的点。
同样有一张图:
在这里插入图片描述
和头插法一样,主要有四个操作:
1.将这个节点的值域保存,即Data[ind]=item
2.将这个节点的指针指向给定节点指向的节点,在图中为第二个红箭头,即Next[ind]=Next[pos]
3.将给定节点的指针指向我们插入的节点,在图中为第一个红箭头Next[pos]=ind
4.因为我们下标为idx的这个点已经使用,所以idx++
所以这一操作的代码如下:

void insert(int item,int pos){
    Data[ind]=item;
    Next[ind]=Next[pos];
    Next[pos]=ind;
    ind++;
}

3.删除

让我们删除第k个插入的节点后面的点,即下标为k-1的节点。
在这里插入图片描述

如图,我们设下标为K的节点指向的是下标为M的节点,而下标为M的节点指向下标为N的节点,我们想要删除K节点后面的节点,即M节点,我们只需将K节点的指针直接指向N节点,所以操作为Next[k]=Next[Next[k]];其中后面的表达式中Next[Next[k]]即代表N节点。
所以删除操作的代码如下:

void deleteitem(int pos){
    Next[pos]=Next[Next[pos]];
}

总结

以上就是今天要讲的内容,本文仅仅简单介绍了用数组模拟链表的相关操作,希望大家能够发掘更多相关知识。在下面附上完整代码:

#include<iostream>
using namespace std;
const int N=10010;
int Data[N],Next[N],head,ind;
void init(){
    head=-1,ind=0;
}
void inserthead(int item){
    Data[ind]=item;
    Next[ind]=head;
    head=ind;
    ind++;
}
void insert(int item,int pos){
    Data[ind]=item;
    Next[ind]=Next[pos];
    Next[pos]=ind;
    ind++;
}
void deleteitem(int pos){
    Next[pos]=Next[Next[pos]];
}
void printlist(int nums[]){
    for(int i=head;i!=-1;i=Next[i]){
        cout<<Data[i]<<'\t';
    }
    cout<<endl;
}
int main(){
    init();
    //头插法
    for(int i=1;i<=5;i+=2){
        inserthead(i);
    }
    printlist(Data);
    //在第二个(在链表中下标为1)插入的数(3)后面插入10
    insert(10,1);
    printlist(Data);
    //删除第四个(在链表中下标为3)插入的数(10)后面的数
    deleteitem(3);
    printlist(Data);
    return 0;
}
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值