顺序表

静态顺序表

test.c

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
//顺序表是物理地址连续的存储单元,一次存储数据元素的线性结构,在数组上实现数据增删查改
//顺序表一般可以分为
//1.静态的顺序表:使用定长数组存储
//2.动态的顺序表,使用动态开辟的数组进行存储

//1.连续的物理空间存储——数组
//2.数据必须是从头开始,依次存储,一个一个存

//静态的顺序表,给少了不够用,够多了浪费,不能灵活利用
#include"seqlist.h"

void testseqlist()
{
SL s;
seqlistinit(&s);//要把实参的地址传给形参
seqlistpushback(&s, 1);
seqlistpushback(&s, 2);
seqlistpushback(&s, 3);
seqlistpushback(&s, 4);
seqlistpushback(&s, 5);
seqlistpushback(&s, 6);
seqlistpushback(&s, 7);
seqlistpushback(&s, 8);
seqlistpushback(&s, 9);
seqlistpushback(&s, 10);
seqlistpushback(&s, 11);

}
int main()
{
testseqlist();
return 0;
}

seqlist.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include"seqlist.h"
void seqlistinit(SL* ps)
{
memset(ps->a, 0, sizeof(seqdata)*n);//对数组初始化为0
ps->sz = 0;
}

void seqlistpushback(SL*ps, seqdata x)
{
if (ps->sz >= n)
{
printf("seqlist is full\n");
return;
}
ps->a[ps->sz] = x;//尾插在sz下一个位置的下标
ps->sz++;
//sz可能会超过数组的最大范围,会越界
}

seqlist.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#pragma once
#include<stdio.h>
#include<string.h>
#define n 10
typedef int seqdata;

typedef struct seqlist
{
seqdata a[n];
int sz;
}SL;

void testseqlist();


//初始化一个数组
void seqlistinit(SL* ps);

//尾插
void seqlistpushback(SL*ps, seqdata x);

动态版顺序表

 

seqlist.h

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
#define _CRT_SECURE_NO_WARNINGS 1;

#pragma once
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>
#define n 10
typedef int seqdata;

typedef struct seqlist
{
seqdata *a;//指向动态开辟的数组
int sz;//有效数据的个数
int capacity;//记录容量
}SL;

void testseqlist();


//初始化一个数组
void seqlistinit(SL* ps);

//尾插
void seqlistpushback(SL*ps, seqdata x);

//打印
void seqlistprint(SL*ps);

//头插
void seqlistpushfront(SL *ps, seqdata x);
//检查容量是否充足
void seqlistcheckcapacity(SL*ps);

//尾删
void seqlistpopback(SL*ps);

//头删
void seqlistpopfront(SL*ps);

//中间插入
void seqlistinsert(SL*ps, int pos, seqdata x);

//中间删除
void seqlisterase(SL*ps, int pos);

//销毁
void seqlistdestroy(SL*ps);

//查
void seqlistfind(SL *ps, seqdata x);

//修改
void seqlistmodify(SL *ps,int pos, seqdata x);

seqlist.c

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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include"seqlist.h"
void seqlistinit(SL* ps)//对顺序表进行初始化
{
ps->a = NULL;
ps->sz = 0;
ps->capacity = 0;
}


//尾插
void seqlistpushback(SL*ps, seqdata x)
{
seqlistcheckcapacity(ps);
ps->a[ps->sz] = x;//尾插在sz下一个位置的下标
ps->sz++;
//sz可能会超过数组的最大范围,会越界
}


//打印
void seqlistprint(SL*ps)
{
for (int i = 0; i < ps->sz; i++)
{
printf("%d ", ps->a[i]);
}
printf("\n");
}

//头插
void seqlistpushfront(SL *ps, seqdata x)//同样面临一个增容的问题,但每次都写增容的代码很麻烦,所以我们可以写一个
{
seqlistcheckcapacity(ps);
int end = ps->sz - 1;
//循环while的写法
//1.初始条件
//2.结束条件
//3.迭代过程
//头插就是每一位都往后挪,第一个位置空了出来

while (end >= 0)//我们想的结束的条件,而循环写的是继续的条件
{
ps->a[end + 1] = ps->a[end];
end--;
}
ps->a[0] = x;//把第一个元素插入
ps->sz++;

}

//搞出一个函数原来检查容量是否充足,如果不足就要增容
void seqlistcheckcapacity(SL*ps)
{
if (ps->sz == ps->capacity)//有效数据对于最大容量,那么我们就要进行扩容
{
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;//一开始sz为0,capacity也为0,所以当等于时有两种情况,
//1.为开辟空间
//2.sz到达了capabilities的容量
//如果一开始的capaci的初值为0,就把capacity改为4,否则就把他扩容两倍
//我们一般扩2倍,扩一倍浪费时间,扩3倍浪费空间
seqdata *tmp = (seqdata*)realloc(ps->a, newcapacity * 2 * sizeof(seqdata));
if (tmp == NULL)
{
printf("realloc failur");
return;
}
else
{
ps->a = tmp;
ps->capacity = newcapacity;
}
}
}
//尾删
void seqlistpopback(SL*ps)
{
//假如说sz为0就不用删除了
//但是如果想用粗暴的方法
//断言,如果大于0就继续删除,等于0的化就会报错
assert(ps->sz>0);
//由sz来标识有多少个有效数据
//直接把sz--,把有效数据减少就行了
//如果我们把最后一个数据置为0,再sz--,不合适,因为可能最后一个元素本来就是一个0,或者他并不是int类型,是一个double类型的变量

ps->sz--;
}
//头删
void seqlistpopfront(SL*ps)
{
//同时也要预防头没有数据了
assert(ps->sz > 0);
int start = 1;
//前一个都用后一个来覆盖
while (start < ps->sz)
{
ps->a[start - 1] = ps->a[start];//start下标最多到sz-1的位置
start++;
}
//头部数据删除完之后
//同样sz也要减
ps->sz--;
}

void seqlistinsert(SL*ps, int pos, seqdata x)
{
//pos只能再sz有效数据里面进行选择
assert(pos < ps->sz);
seqlistcheckcapacity(ps);
int end = ps->sz - 1;
while (end>=pos)
{
ps->a[end + 1] = ps->a[end];
end--;
}
//直到end挪到小于pos就终止了
ps->a[pos] = x;//pos是数组的下标
ps->sz++;
}

void seqlisterase(SL*ps, int pos)
{
//一次把后面的数据往前挪
//把pos的位置给覆盖掉
assert(pos < ps->sz);
int start = pos + 1;
while (start < ps->sz)
{
ps->a[start-1] = ps->a[start];
start++;
}
ps->sz--;
}


void seqlistdestroy(SL*ps)//malloc出来的空间不销毁就会内存泄露
{
free(ps->a);
ps->a = NULL;
ps->sz = ps->capacity = 0;
}

void seqlistfind(SL *ps, seqdata x)//如果有序的化就可以使用二分查找
{
//假如是有序的化,就可以用二分查找,但他并不是有序的
//那么我们就用暴力解法
int i = 0;
for (i = 0; i < ps->sz; i++)
{
if (ps->a[i] == x)
{
return i;//返回x的下标
}
}
return -1;//如果找到的化就返回下标,每找到就返回-1,因为数组里面的下标不可能是-1
}

void seqlistmodify(SL *ps, int pos, seqdata x)
{
assert(pos < ps->sz);
ps->a[pos] = x;
}

 test.c

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
//顺序表是物理地址连续的存储单元,一次存储数据元素的线性结构,在数组上实现数据增删查改
//顺序表一般可以分为
//1.静态的顺序表:使用定长数组存储
//2.动态的顺序表,使用动态开辟的数组进行存储

//1.连续的物理空间存储——数组
//2.数据必须是从头开始,依次存储,一个一个存

//静态的顺序表,给少了不够用,够多了浪费,不能灵活利用
#include"seqlist.h"

void testseqlist()
{
SL s;
seqlistinit(&s);//要把实参的地址传给形参
seqlistpushback(&s, 1);
seqlistpushback(&s, 2);
seqlistpushback(&s, 3);
seqlistpushback(&s, 4);
seqlistpushback(&s, 5);
seqlistpushback(&s, 6);
seqlistpushback(&s, 7);
seqlistpushback(&s, 8);
seqlistpushback(&s, 9);
seqlistpushback(&s, 10);
seqlistpushback(&s, 11);
seqlistpushfront(&s, 0);
seqlistpushfront(&s, -1);
seqlistpopfront(&s);
seqlistpopback(&s);
seqlistinsert(&s, 0, 20);//0数组的下标
seqlisterase(&s, 0);
seqlistprint(&s);
seqlistdestroy(&s);

}
int main()
{
testseqlist();
return 0;
}

随后我会上传一些顺序表的oj


顺序表
http://example.com/2021/11/21/顺序表/
作者
Zevin
发布于
2021年11月21日
许可协议