前言
链表实现我们主要通过动态链表,即指针+结构体,但是这种方法存在一定效率问题,例如我们在插入节点时需要创建一个新节点,即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;
}