详解数据结构 - 顺序表Sequential List

深入解析顺序表:实现、特点与应用

引言:
        顺序表是一种常见的数据结构,通过数组实现,以线性的方式存储元素,提供了随机访问和快速插入删除的操作。在本篇博客中,我们将深入探讨顺序表的定义、实现原理,以及其特点、优缺点,还会介绍一些顺序表的常见应用。

一、顺序表的定义
        

        顺序表是一种线性结构,其元素按照顺序存储在一块连续的内存空间中。顺序表可以通过数组实现,利用数组的下标来访问和操作元素。顺序表的长度可以动态变化,可以灵活地插入和删除元素。

二、顺序表的具体实现

代码示例:

#include <stdio.h>

#define MAXSIZE 1000 // 定义顺序表的最大长度

typedef int DataType; // 定义顺序表中元素的数据类型

typedef struct
{
	DataType data[MAXSIZE]; // 顺序表的元素数组
	int length; // 顺序表的当前长度
} SeqList; // 定义顺序表的结构体

// 初始化顺序表
int init(SeqList *L)
{
	L->length = 0; // 将顺序表的长度设为0,表示顺序表为空
	return 0;
}

// 获取顺序表的当前长度
int length(SeqList *L)
{
	return L->length;
}

// 判断顺序表是否已满
int full(SeqList *L)
{
	return (L->length == MAXSIZE) ? 1 : 0; // 如果顺序表的长度等于最大长度,则顺序表已满,返回1;否则返回0
}

// 删除顺序表中的元素
int delete(SeqList *L, int i) {
    if (i < 1 || i > L->length) { // 如果位置i不合法(小于1或大于顺序表的长度)
        printf("位置[%d]不存在!\n", i); // 输出错误信息
        return 0; // 返回删除失败
    }
    
    for (int j = i - 1; j < L->length - 1; j++) { // 从位置i开始,将后面的元素向前移动一位
        L->data[j] = L->data[j + 1];
    }
    
    L->length--; // 顺序表的长度减1
    
    return 1; // 返回删除成功
}
// 判断顺序表是否为空
int isEmpty(SeqList *L) {
    return L->length == 0; // 如果顺序表的长度为0,表示顺序表为空,返回1;否则返回0
}

// 在顺序表的指定位置插入元素
int insert(SeqList *L, int i, DataType x)
{
	int j;

	if (full(L)) // 如果顺序表已满
	{
		printf("Error[10001],顺序表已满!\n"); // 输出错误信息
		return 10001; // 返回插入失败的错误码
	}
	
	if (i < 1 || i > length(L) + 1) // 如果位置i不合法(小于1或大于顺序表的长度加1)
	{
		printf("Error[10002],位置i不合法!\n"); // 输出错误信息
		return 10002; // 返回插入失败的错误码
	}

	for (j = L->length; j >= i; j--) // 从顺序表的最后一个元素开始,将元素向后移动一位,腾出位置给新元素
	{
		L->data[j] = L->data[j - 1];
	}
	L->data[j] = x; // 将新元素插入到位置i
	L->length++; // 顺序表的长度加1
	return 0; // 返回插入成功
}

// 输出顺序表的元素
void print(SeqList *L)
{
	int i;

	if (isEmpty(L)) // 如果顺序表为空
	{
		printf("顺序表为空!"); // 输出提示信息
		return;
	}
	printf("顺序表为:");
	for (i = 0; i < L->length; i++) //
	{
		printf(" %d ", L->data[i]);
	}
	printf("\n");
}

方法函数敲完之后我们开始 敲main()方法

int main(int argc, char const *argv[])
{
	
	SeqList L;
	int cmd;
	int i;

	DataType x;

	printf("\n\n\n");
printf("-----------顺序表演示程序----------\n");
	do
	{
		printf("1. 初始化顺序表\n");
		printf("2. 插入元素\n");
		printf("3. 删除元素\n");
		printf("4. 判断顺序表是否为空\n");
		printf("5. 判断顺序表是否满\n");
		printf("6. 输出顺序表\n");
		printf("10. 帮助\n");
		printf("0. 退出\n");
		printf("请输入您要进行的操作(1~6,0退出):");
		scanf("%d", &cmd);
		switch (cmd)
		{
		case 1:
			if (!init(&L))
			{
				printf("顺序表已初始化!\n");
			}
			break;
		case 2:
			printf("请输入位置i,插入元素x(i,x):");
			scanf("%d,%d", &i, &x);
			if (!insert(&L, i, x))
			{
				printf("元素(%d)已插入位置[%d]\n", x, i);
			}
			break;
		case 3:
			printf("请输入要删除的位置i:");
			scanf("%d", &i);
			if (!delete (&L, i))
			{
				printf("位置[%d]的元素已删除\n", i);
			}
			break;
		case 4:
			if (isEmpty(&L))
			{
				printf("顺序表为空!\n");
			}
			else
			{
				printf("顺序表不为空!\n");
			}
			break;
		case 5:
			if (full(&L))
			{
				printf("顺序表已满!\n");
			}
			else
			{
				printf("顺序表未满!\n");
			}
			break;
		case 6:
			print(&L);
			break;
		case 10:
			printf(" 本程序为顺序表的演示程序,有XXX设计开发,程序完成了。。。。功能!。。。\n");
			break;
		}
	} while (cmd != 0);
	return 0;
}

运行结果:

           /\
          (*)=======/\====
           )(      /  \
__________/  )    /    \
\___         /   / ""   \
  \____    _/   / (*)   \
     / \__/    (----------)
    /____|__//_ ( 送给您- )
         |      ( 亲爱的 )
         |       (      )
         |        (____)
        _|__
         \\\    ☆新年 . 快乐☆
-----------顺序表演示程序----------
1. 初始化顺序表
2. 插入元素
3. 删除元素
4. 判断顺序表是否为空
5. 判断顺序表是否满
6. 输出顺序表
10. 帮助
0. 退出
请输入您要进行的操作(1~6,0退出):1
顺序表已初始化!
1. 初始化顺序表
2. 插入元素
3. 删除元素
4. 判断顺序表是否为空
5. 判断顺序表是否满
6. 输出顺序表
10. 帮助
0. 退出
请输入您要进行的操作(1~6,0退出):2
请输入位置i,插入元素x(i,x):1,2
元素(2)已插入位置[1]
1. 初始化顺序表
2. 插入元素
3. 删除元素
4. 判断顺序表是否为空
5. 判断顺序表是否满
6. 输出顺序表
10. 帮助
0. 退出
请输入您要进行的操作(1~6,0退出):3
请输入要删除的位置i:1
1. 初始化顺序表
2. 插入元素
3. 删除元素
4. 判断顺序表是否为空
5. 判断顺序表是否满
6. 输出顺序表
10. 帮助
0. 退出
请输入您要进行的操作(1~6,0退出):4
顺序表为空!
1. 初始化顺序表
2. 插入元素
3. 删除元素
4. 判断顺序表是否为空
5. 判断顺序表是否满
6. 输出顺序表
10. 帮助
0. 退出
请输入您要进行的操作(1~6,0退出):5
顺序表未满!
1. 初始化顺序表
2. 插入元素
3. 删除元素
4. 判断顺序表是否为空
5. 判断顺序表是否满
6. 输出顺序表
10. 帮助
0. 退出
请输入您要进行的操作(1~6,0退出):2
请输入位置i,插入元素x(i,x):1,4
元素(4)已插入位置[1]
1. 初始化顺序表
2. 插入元素
3. 删除元素
4. 判断顺序表是否为空
5. 判断顺序表是否满
6. 输出顺序表
10. 帮助
0. 退出
请输入您要进行的操作(1~6,0退出):2
请输入位置i,插入元素x(i,x):2,5
元素(5)已插入位置[2]
1. 初始化顺序表
2. 插入元素
3. 删除元素
4. 判断顺序表是否为空
5. 判断顺序表是否满
6. 输出顺序表
10. 帮助
0. 退出
请输入您要进行的操作(1~6,0退出):6
顺序表为: 4  5
1. 初始化顺序表
2. 插入元素
3. 删除元素
4. 判断顺序表是否为空
5. 判断顺序表是否满
6. 输出顺序表
10. 帮助
0. 退出
请输入您要进行的操作(1~6,0退出):10
 本程序为顺序表的演示程序,有XXX设计开发,程序完成了。。。。功能!。。。
1. 初始化顺序表
2. 插入元素
3. 删除元素
4. 判断顺序表是否为空
5. 判断顺序表是否满
6. 输出顺序表
10. 帮助
0. 退出
请输入您要进行的操作(1~6,0退出):
三、顺序表的特点和优缺点

顺序表具有以下特点

  1. 支持随机访问:可以通过下标快速定位元素,访问元素的时间复杂度为O(1)。
  2. 插入删除效率较低:每次插入或删除元素时,需要移动其他元素,时间复杂度为O(n)。
  3. 需要预先分配内存空间:顺序表需要提前分配足够的内存空间,当元素数量超过空间大小时,需要重新分配空间。

 顺序表的优缺点: 

        顺序表的优点是提供了快速随机访问和索引定位的能力,适用于需要频繁访问指定位置的场景。缺点是插入和删除操作的效率较低,且需要预先分配内存空间,不适用于频繁插入删除的场景。 

四、顺序表的应用举例
  1. 学生成绩管理系统:顺序表可以用来存储学生的成绩信息,通过下标快速获取某个学生的成绩。
  2. 订单管理系统:顺序表可以用来存储订单信息,通过下标或者订单编号快速访问和操作订单。
  3. 缓存实现:顺序表可以用来实现最近访问页面的缓存,通过下标定位和替换最旧的数据。
五、与其他数据结构的比较

与链表、栈、队列等数据结构相比,顺序表的主要优势在于支持随机访问和定位,并且相对简单易实现。而链表适合频繁插入删除元素的场景,栈和队列适用于遵循先入后出和先入先出原则的操作。

        通过深入了解顺序表的实现原理、特点和应用,我们可以更好地理解和应用这一常见的数据结构。顺序表在实际开发中具有广泛的应用,可以根据具体需求选择合适的数据结构来提高程序的效率和性能。 

总结 

        顺序表是一个非常有用和灵活的数据结构,可以用于许多应用中。掌握了它的使用,可以增强程序员的能力,并提高程序的效率和功能。

        顺序表是一种常见的线性表实现方式,具有随机访问高效、空间利用率高的优点,但插入和删除操作效率较低,并且需要预先分配空间。在实际应用中,可以根据具体需求选择合适的数据结构,权衡其优缺点。

        同时,由于顺序表元素在内存上是连续存储的,在进行元素插入或删除操作时,需要移动后续元素的位置,所以其时间复杂度为O(n)。因此,在频繁插入或删除数据的情况下,应该考虑使用其他数据结构,比如链表。此外,顺序表还需要额外的存储空间来存储元素个数和容量信息,所以在存储空间受限的情况下,应该考虑选择其他的数据结构。

        总之,不同的数据结构都有其独特的优缺点和适用场景,程序员需要根据实际情况选择合适的数据结构进行实现。同时,对于同一种数据结构,也存在多种不同的实现方式和优化技巧,不同的实现方式也会对数据结构的性能产生影响,程序员需要根据实际需求进行选择和优化。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值