链表(数组模拟)
链表也可以使用数组来实现,操作和基础知识比指针简单
但是个人觉得就思路和操作的清晰,以及对链表的理解而言,还是用指针好
模拟链表介绍
我们可以利用两个数组,分别记录链表要的两个东西:数据和地址
我们使用一个数组data,来存储每个结点的数据
使用另外一个数组right,来存储序列中每一个数右边的数的位置
比如现在二者如下:
位置 1 2 3 4 5 06 07 08 09
data: 2 3 5 8 9 10 18 26 32
right: 2 3 4 5 6 7 8 9 0
right[9] = 0 ,就代表data第九位的的右边没有数据
这里说一下,众所周知数组的第一位下标是0,但是书里按1开始算了
本着以书为本的原则,就没有修改,况且对于做链表而言也没区别
就是习惯了0开始数,看着难受
再如right[1]的值是2,指的是1号元素的右边的元素是2号元素(存放在data[2]中)
下面尝试按大小顺序,把6这个数值加入进去,那么该怎么做呢?
对于data数组比较简单,我们只需要做添加数据这个操作
让我们把这个数据添加到10号位置
位置 1 2 3 4 5 06 07 08 09 10
data: 2 3 5 8 9 10 18 26 32 6
对于right数组,会复杂一点,毕竟要排序和改地址
我们通过观察data数组,我们的6需要添加到5和8之间,也就是3号元素和4号元素之间
5对应的号数是3,8则是4.原本的地址是3号->4号,现在我们要加入6
那么我们新的次序是3号->10号->4号,即:
1.把3号“右边一位”改成10号
2.把10号“右边一位”改成4号
3.4号“右边一位”不变
位置 1 2 3 4 5 06 07 08 09 10
data: 2 3 5 8 9 10 18 26 32 6
right: 2 3 10 5 6 7 08 09 0 4
代码实例:
# include <stdio.h>
int main(){
int data[101],right[101]; //大小没有硬性要求,
int i,n,t,len ;
//开始读入已有的数
scanf("%d",&n) ;
for(i=1 ; i<=n ; i++){
scanf("%d",&data[i]) ;
}
len = n ;
//初始化数组
for(i = 1 ; i<= n ,i++){
if(i!=n) right[i] = i+1;
else right[i] = 0 ;
}
//直接在数组data末尾增加一个数
len++;
scanf("%d",&data[len]);
//从链表透开始遍历
t = 1 ;
while(t!=0){
if(data[right[t]] > date[len]){
//如果当前结点的下一结点的值大于待插入数,则把数插入
right[len] = right[t];
//新插入的数的下一结点的编号,等于当前结点的下一结点编号
right[t] = len ;
//当前结点的下一个结点编号,就是新插入的数的编号
break ; //插入完成,我们跳出循环
}
t = right[t] ;
}
//输出链表中所有的数
t = 1 ;
while(t!=0){
printf("%d",data[t]);
r = tight[t] ; //根据right数组的设置,读取下一个数
}
getchar();
getchar();
return 0 ;
}
小结
模拟链表以两个对应的数组,代替了指针
两者各有优劣,但是指针用的应该更多,毕竟你数组大小存在着限制
可以把模拟链表作为简单/削弱版的链表
不过,使用模拟链表一样可以实现双向链表和循环链表,这里就先不提了