线性表-顺序表(含完整C代码)

一.线性结构

1.定义

如果⼀个数据元素序列满⾜:

  1.  除第⼀个和最后⼀个数据元素外,每个数据元素只有⼀个前驱数据元素和⼀个后继数据元素;
  2.  第⼀个数据元素没有前驱数据元素;
  3.  最后⼀个数据元素没有后继数据元素;

我们称这样的结构就叫做 线性结构

2.特点

数据元素存在一对一的逻辑关系。

3.举例

线性表(顺序表+链表)、栈、队列等都是线性结构。

二.线性表

1.定义

一个线性表是n个数据元素的有限序列List=(a_{1},a_{2},...,a_{n})

2.特征

有限、序列、同构

3.抽象数据类型

  • 数据集合
  • 该数据集合上的操作集合(创建、插入、删除、查找)

4.存储方法

  • 顺序存储-顺序表
  • 非顺序存储-链表

三.顺序表

1.定义

线性表顺序存储结构是一组地址连续的存储单元依次存储线性表的数据元素,依顺序存储结构存放的线性表称为顺序表。

2.特点

  • 逻辑相邻\rightarrow物理相邻
  • 可以随机存取

3.实现方法

  • 静态数组
  • 指针数组

4.优劣势

优势

数据在数组中按顺序存储,可以通过数组下标直接访问,因此顺序表的查找定位元素很快

劣势

  • 插⼊和删除元素都需要大量的操作
  • 因为数组在声明的时候需要确定⻓度,因此顺序表的长度是确定的。若需要扩⼤顺序表⻓度,需要⼤量的操作,不够灵活。(要将该数组中的元素全部copy到另外⼀个数组)
  • 由于数据大小的不可测性,有时会浪费掉大量的空间

5.应用场景

顺序表适用于数据无需进行大量改动的结构

6.删除算法(delete)

  1. 找到删除目标的位置
  2. 将其后的元素整体向前移动一个位置
  3. 修改表长
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)

  1. 遍历数据找到插入位置
  2. 将要插⼊位置的元素以及后续的元素整体向后移动⼀个位置
  3. 将插入元素元素放到腾出来的位置上
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]);
	}
}

代码都是自己敲的,如有错误,恳请指正!

  • 8
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~在下小吴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值