数据结构之线性表-在静态链表中插入结点-学习笔记-19

引入

我们说过动态链表是使用malloc( )free( )这两个函数来实现的,动态插入,动态释放。那么静态链表该如何实现这样的功能呢?

静态链表中插入数据

简单来说就是要分清楚哪些没有使用过,哪些已经在使用了。
我们说

  • 备用链表存放的是所有可以用的下标,用游标链接
  • 数组的第一个元素,存放的是备用链表的第一个可用下标
    所以
    每次插入新节点,都可以从备用链表取得第一个结点作为待插入结点

步骤分解
1、先获取0下标指向的备用链表的第一个可写入下标
2、第一个可写入的结点的游标传递给0下标。
3、判断插入地址是否合法,不能小于1,不能大于结点长度+1的位置。
4、对第一个可写的节点的 data 赋值
5、通过循环从最后一个结点向前找到要插入的节点之前的结点
6、找到之后新结点的游标改成之前结点的游标
7、前一结点的游标指向新节点的下标。

代码实现

我设计了三个函数,静态链表初始化、获取静态链表当前长度、静态链表顺序插入函数。然后再静态链表中插入三个数据,并返回目前链表的情况以及它们的游标。以及下一个可用的下标。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 10

typedef struct {
int num;
int data;
}stu[MAXSIZE];

void init(stu stu_arr){
//用来初始化静态链表
for(int i=0;i<MAXSIZE-1;i++){
stu_arr[i].num=i+1;
stu_arr[i].data=0;
}
stu_arr[MAXSIZE-1].num=0;
}

int return_usefull(stu stu_arr){
int i=stu_arr[0].num;
//获取目前可用的下标
if(stu_arr[0].num){
stu_arr[0].num=stu_arr[i].num;
//将目前可用的下一个下标重新赋值给0下标
}
return i;
}
//返回0下标对应的游标

int listlength(stu stu_arr){
int i=0,n=1;
while(stu_arr[n].data!=0 && n<MAXSIZE){
i++;
n++;
}
return i;
}

int insert(stu stu_arr, int i ,int data){
int k ,j , l;
if(i<1 || i>listlength(stu_arr)+1){
return 0;
}
j=return_usefull(stu_arr); //获取第一个可用的下标
if(j){
stu_arr[j].data=data; //给第一个可以用的下标的 data 区域赋值
k=MAXSIZE-1; //指向最后一个下标
for(l=1;l<=i-1;l++){
//找到第 i-1 个位置就停
k=stu_arr[k].num;
//让 k 移动到目前静态链表的第i-1个位置,因为链表的第二个并不知道实际是s哪一个,只能顺藤摸瓜找到该下标。
}
stu_arr[j].num=stu_arr[k].num;
//先把要插入的 j 的游标改成原来 k 指向的游标
stu_arr[k].num=j;
//把 k 的游标指向 j
}
return 1;
}




int main(){
stu student;
init(student);
insert(student, 1, 111);
insert(student, 2, 222);
if(insert(student, 2, 333)==0){
printf("错误!\n");
}
int i=1;
while(student[i].data!=0){
printf("%d号下标:%d:%d\n",i,student[i].num,student[i].data);
i++;
}
printf("目前可用下标是%d\n",student[0].num);
printf("第一个结点是%d\n",student[MAXSIZE-1].num);
}

伪代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
int Malloc_SLL(StaticLinkList space){
int i=space[0].cur;
if(space[0].cur){
space[0].cur=space[i].cur;
//把原来0存储的游标的游标赋值给0,也就是下一个可用下标
}
return i;
}

Status ListInsert(StaticLinkList L , int i , ElemeType e){
int j,k,l; //k是数组最后一位下标、k 是前一结点下标,j 是插入结点下标
k=MAXSIZE-1; //k为数组最后一位下标
if(i <1 || i>ListLength(L)+1){
return ERROR;
//判断插入位置 i 的合法性,不能小于1,也不能超过当前链表+1得长度
}
j = Malloc_SLL(L); //j 为插入结点下标,获取得是链表第一个可用结点得下标。

if(j){
L[j].data=e; //先把 j 这个结点得数据域存上数据
for( int l=1; l<i-1; i++){
k=L[k].cur; //这个就像是那个链表向后找,指针等于这个指针得指针域
}
//for 循环就是顺着链表的尾巴指向的链表得第一个结点向后找

L[j].cur=L[k].cur;
L[k].cur=j;
//这个就简单了,插入嘛,先把新的等于老的,然后老的指向新的
return OK;
}
return ERROR;
}

尾巴

这是我的个人学习笔记,主要是应付考研复习使用,充斥着一些吐槽和个人观点,并不严谨,欢迎大家参考、指正。


-------------The End-------------
欢迎请我喝咖啡哦~!