顺序表的定义及其特点;
顺序存储表示:用一组地址连续的存储单元依次存储线性表的数据元素的方式,具有顺序存储结构的特点(数据间的逻辑关系和物理关系是一致的)
假设线性表 L 存储的起始位置为 LOC(A) ,sizeof(ElemType) 是每个数据元素所占用存储空间的大小,则表 L 所对应的顺序存储如下图:
注意:线性表中的位序是从 1 开始的,而数组中元素的下标是从 0 开始的
线性表的顺序存储结构是一种随机存取的存储结构,即通过首地址和元素序号可以在O(1) 时间内找到指定的元素
由于线性表的长度可变,且所需最大存储空间随问题的不同而不同,在C语言中通常使用动态分配的一维数组表示线性表
顺序表的运算
顺序表的主要运算包括:
初始化
创建一个空的顺序表,并指定其最大容量。
/*顺序表初始化*/
int init(SeqList *L)
{
L->length = 0;
return 0;
}
插入
在指定位置插入一个元素,需要将插入位置后的元素依次后移。
/*插入元素*/
int insert(SeqList *L, int i, DataType x)
{
int j;
/*判断是否满*/
if(full(L))
{
printf("Error[10001],顺序表已满!\n");
return 10001;
}
/*判断位置i合法性*/
if(i<1 || i>length(L)+1)
{
printf("位置i不合法!\n");
return 10002;
}
/*移动元素,向后移动*/
for(j=L->length;j>=i;j--)
{
L->data[j] = L->data[j-1];
}
L->data[j] = x;
L->length++;
return 0; /*ok!*/
}
删除
删除指定位置的元素,需要将删除位置后的元素依次前移一个。
/*删除元素*/
int delete(SeqList *L, int i, DataType *x)
{
/*判断位置i合法性*/
if(i<1 || i>length(L)+1)
{
printf("Error[10002],位置i不合法!\n");
return 10002;
}
int j;
// 从删除位置把数据往前移 第n-1个
for (j = i-1; j < L ->length; j++)
{
L->data[j] = L->data[j+1];
}
L->length--;
return 0;
}
遍历
按顺序依次访问顺序表中的所有元素。
/*输出顺序表*/
void print(SeqList *L)
{
int i;
if(empty(L))
{
printf("顺序表为空!");
return ;
}
printf("顺序表为:");
for(i=0;i<L->length;i++)
{
printf(" %d ", L->data[i]);
}
printf("\n");
}
顺序表完成的起始都可以在突发时刻,即时间复杂度为O(1),因为元素在内存中是连续存储的。但是在插入和删除操作中,如果需要间隔地调整顺序表的结构,可能会导致数据迁移,造成一定的时间开销。
顺序表的实现(详细的介绍及C程序代码、执行结果)
完整代码
项目结构
h 的方法似于 java 的接口方法
│ main.c
│ SeqList.c
│ SeqList.h
│ welcome.h
项目文件
C语言讲义——传值、传引用 - 虎老狮 - 博客园 (cnblogs.com)
暗号:看你说不说你的宿舍地址
地址==指针
SeqList.h
/*
SeqList.h 顺序表定义
*/
#define MAXSIZE 1000
typedef int DataType;
/*顺序表*/
typedef struct
{
DataType data[MAXSIZE];
int length;
}SeqList;
/*顺序表初始化*/
int init(SeqList *L);
/*顺序表的长度*/
int length(SeqList *L);
/*顺序表是否满*/
int full(SeqList *L);
/*是否空*/
int empty(SeqList *L);
/*插入元素*/
int insert(SeqList *L, int i, DataType x);
/*删除元素*/
int delete(SeqList *L, int i, DataType *x);
/*输出顺序表*/
void print(SeqList *L);
SeqList.c
/*
SeqList.c 顺序表实现
*/
#include "SeqList.h"
/*顺序表初始化*/
int init(SeqList *L)
{
L->length = 0;
return 0;
}
/*顺序表的长度*/
int length(SeqList *L)
{
return L->length;
}
/*顺序表是否满*/
int full(SeqList *L)
{
return (L->length == MAXSIZE)?1:0;
}
/*是否空*/
int empty(SeqList *L)
{
return (L->length == 0)?1:0;
}
/*插入元素*/
int insert(SeqList *L, int i, DataType x)
{
int j;
/*判断是否满*/
if(full(L))
{
printf("Error[10001],顺序表已满!\n");
return 10001;
}
/*判断位置i合法性*/
if(i<1 || i>length(L)+1)
{
printf("位置i不合法!\n");
return 10002;
}
/*移动元素,向后移动*/
for(j=L->length;j>=i;j--)
{
L->data[j] = L->data[j-1];
}
L->data[j] = x;
L->length++;
return 0; /*ok!*/
}
/*删除元素*/
int delete(SeqList *L, int i, DataType *x)
{
/*判断位置i合法性*/
if(i<1 || i>length(L)+1)
{
printf("Error[10002],位置i不合法!\n");
return 10002;
}
int j;
for (j = i-1; j < L ->length; j++)
{
L->data[j] = L->data[j+1];
}
L->length--;
return 0;
}
/*输出顺序表*/
void print(SeqList *L)
{
int i;
if(empty(L))
{
printf("顺序表为空!");
return ;
}
printf("顺序表为:");
for(i=0;i<L->length;i++)
{
printf(" %d ", L->data[i]);
}
printf("\n");
}
welcome.h
char welcome[] = "welcome";
main.c
#include <stdio.h>
#include "SeqList.h"
#include <string.h>
#include "welcome.h"
int main(int argc, char* argv[])
{
SeqList L;
int cmd;
int i;
int m,n;
DataType x;
for(i=0;i<strlen(welcome);i++)
{
printf("%c",welcome[i]);
for(m=0;m<10000;m++)
for(n=0;n<1000;n++)
{
;
}
}
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,删除元素x(i):");
scanf("%d",&i);
if(!delete(&L,i,x))
{
printf("元素(%d)删除位置[%d]\n",x, i);
}
break;
case 4:
if(!empty(&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;
}
运行结果
小结
顺序表是一种常见的线性表数据结构,它由一组连续的存储空间组成,可以通过下标直接访问元素。顺序表具有随机访问的特性,使得查找、插入和删除等操作具有较高的效率。
顺序表的主要特点是元素在内存中的连续存储,这使得访问元素的时间复杂度为O(1),即常数时间。与链表相比,顺序表的随机访问效率更高。另外,顺序表还可以通过下标进行快速遍历,对于需要频繁访问和修改元素的场景,顺序表是一种很好的选择。
在实际应用中,顺序表适用于元素数量固定、操作频繁的场景。例如,在某些算法中,需要对大量数据进行排序、查找等操作,此时使用顺序表能够更快地访问和处理数据。此外,顺序表还可以用于实现其他数据结构,如栈和队列等。
然而,顺序表也存在一些限制。
- 首先,顺序表的容量是固定的,在初始化时需要指定最大容量,一旦超过容量限制就无法添加新元素。
- 其次,在插入和删除操作中,需要移动大量数据,可能会带来较大的时间开销。因此,在需要频繁插入和删除元素的场景下,可能不适合使用顺序表。
综上所述,顺序表是一种简单而高效的数据结构,适用于元素数量固定、频繁访问和修改的场景。根据实际需求,我们可以选择合适的数据结构来处理和操作数据,如b+树、跳表。。。以提高程序的效率和性能。
B+树看这一篇就够了(B+树查找、插入、删除全上) - 知乎 (zhihu.com)
参考文献
1. 数据结构C语言严蔚敏版(第二版)超详细笔记附带课后习题
2. ora.ai