一.线性结构
1.定义
如果⼀个数据元素序列满⾜:
- 除第⼀个和最后⼀个数据元素外,每个数据元素只有⼀个前驱数据元素和⼀个后继数据元素;
- 第⼀个数据元素没有前驱数据元素;
- 最后⼀个数据元素没有后继数据元素;
我们称这样的结构就叫做 线性结构
2.特点
数据元素存在一对一的逻辑关系。
3.举例
线性表(顺序表+链表)、栈、队列等都是线性结构。
二.线性表
1.定义
一个线性表是n个数据元素的有限序列。
2.特征
有限、序列、同构
3.抽象数据类型
- 数据集合
- 该数据集合上的操作集合(创建、插入、删除、查找)
4.存储方法
- 顺序存储-顺序表
- 非顺序存储-链表
三.顺序表
1.定义
线性表顺序存储结构是一组地址连续的存储单元依次存储线性表的数据元素,依顺序存储结构存放的线性表称为顺序表。
2.特点
- 逻辑相邻物理相邻
- 可以随机存取
3.实现方法
- 静态数组
- 指针数组
4.优劣势
优势
数据在数组中按顺序存储,可以通过数组下标直接访问,因此顺序表的查找定位元素很快。
劣势
- 插⼊和删除元素都需要大量的操作。
- 因为数组在声明的时候需要确定⻓度,因此顺序表的长度是确定的。若需要扩⼤顺序表⻓度,需要⼤量的操作,不够灵活。(要将该数组中的元素全部copy到另外⼀个数组)
- 由于数据大小的不可测性,有时会浪费掉大量的空间。
5.应用场景
顺序表适用于数据无需进行大量改动的结构
6.删除算法(delete)
- 找到删除目标的位置
- 将其后的元素整体向前移动一个位置
- 修改表长
void delete(Arr* a, int n)
{
int i = find(a, n);//删除元素下标
if (i == -1)
printf("没有此元素,删除失败");
else
{
for (int k = i; k < a->size; k++)
a->e[k] = a->e[k + 1];
a->size--;
}
}
7.插入算法(insert)
- 遍历数据找到插入位置
- 将要插⼊位置的元素以及后续的元素整体向后移动⼀个位置
- 将插入元素元素放到腾出来的位置上
void insert(Arr* a, int n, int i)
{
if (a->length <= i)
printf("插入位置超过数组范围");
else
{
if (a->size < a->length)
{
for (int k = a->size; k > i; k--)//依此向后移动一位,腾出一个空位
a->e[k] = a->e[k - 1];
a->e[i] = n;
a->size++;
}
else
printf("顺序表已满,不可插入");
}
}
四.完整代码(C语言)
包含一下函数:
- 创建空的顺序表
Arr InitArr();
- 依次添加数据元素
void insert(Arr* a, int n, int i);
- 指定位置插入数据元素
void insert(Arr* a, int n, int i);
- 查找元素
int find(Arr* a, int n);
- 删除指定元素
void delete(Arr* a, int n);
- 修改指定元素
void modification(Arr* a, int n, int i, int key);
- 展示全部数据
void show(Arr a);
为简化代码,上述数据类型都选用int型
完整代码如下:
#include<stdio.h>
#include<stdlib.h>
#define Size 5
typedef struct ArrayList
{
int* e;//指针数组
int length;//顺序表总元素
int size;//当前元素个数
}Arr;
Arr InitArr();
void add(Arr* a, int n);
void insert(Arr* a, int n, int i);
int find(Arr* a, int n);
void delete(Arr* a, int n);
void modification(Arr* a, int n, int i, int key);
void show(Arr a);
int main()
{
Arr a;
a = InitArr();
add(&a, 1);
add(&a, 2);
add(&a, 3);
add(&a, 4);
show(a);//输出1234
printf("\n");
insert(&a, 5, 0);
show(a);//输出51234
printf("\n");
delete(&a, 2);
show(a);//输出5134
printf("\n");
modification(&a, 1, 1, 2);
show(a);//输出5234
printf("\n");
int m = find(&a, 4);
printf("%d", m);//输出3
return 0;
}
/*创建空的顺序表*/
Arr InitArr()
{
Arr a;
a.e = (int*)malloc(Size * sizeof(int));
if (!a.e)
{
printf("创建失败");
exit(0);
}
a.length = Size;
a.size = 0;
return a;
}
/*添加元素*/
//数组用地址传递,待添加元素为n
void add(Arr* a, int n)
{
if (a->size < a->length)
{
a->e[a->size] = n;
a->size++;
}
else
printf("顺序表已满,不可添加");
}
/*插入元素*/
//在第i个元素前插入元素n
void insert(Arr* a, int n, int i)
{
if (a->length <= i)
printf("插入位置超过数组范围");
else
{
if (a->size < a->length)
{
for (int k = a->size; k > i; k--)//依此向后移动一位,腾出一个空位
a->e[k] = a->e[k - 1];
a->e[i] = n;
a->size++;
}
else
printf("顺序表已满,不可插入");
}
}
/*查找元素*/
//找到指定元素的数组下标
int find(Arr* a, int n)
{
int i;
for (i = 0; i < a->size; i++)//遍历数组,找到后返回数组下标
{
if (a->e[i] == n)
return i;
}
if (i > a->size)//遍历完后,没有找到,返回-1
return -1;
}
/*删除元素*/
//删除指定一个元素
void delete(Arr* a, int n)
{
int i = find(a, n);//删除元素下标
if (i == -1)
printf("没有此元素,删除失败");
else
{
for (int k = i; k < a->size; k++)
a->e[k] = a->e[k + 1];
a->size--;
}
}
/*修改元素*/
void modification(Arr* a, int n, int i, int key)
{
i = find(a, n);
if (i != -1)
{
a->e[i] = key;
}
}
/*展示元素*/
void show(Arr a)
{
if (a.length == 0)
printf("顺序表中没有元素");
else
{
for (int i = 0; i < a.size; i++)
printf("%d", a.e[i]);
}
}
代码都是自己敲的,如有错误,恳请指正!