持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
一、什么是顺序表?
顺序表是线性表的一种,是指用一组地址连续的存储单元依次存储线性表的数据元素。其特点是,逻辑上相邻的数据元素,其物次序也是相邻的。所以顺序表具有随机存取的性质。
二、顺序表中基本操作的实现
顺序表中的基本操作有很多取值、赋值、查找、插入、删除、排序、销毁、重置等等。
1.预处理及定义顺序表类型:
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100 //设置顺序表的最大长度为100
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
typedef char ElemType;
//定义顺序表类型
typedef struct
{
ElemType* elem;//此处为静态数组也可使用静态数组ElemType elem[MAXSIZE]代替
int length; //用于表示顺序表的长度
}SqList;
2.顺序表的初始化
//线性表的初始化
Status InitList(SqList &L)
{
//构造一个顺序表L
L.elem = new ElemType[MAXSIZE]; //为顺序表分配一个大小为MAXSIZE的数组空间
if (!L.elem) exit(OVERFLOW); //异常处理提高代码的健壮性
L.length = 0; //空表长度为0
return OK;
}
3.顺序表的赋值
void CreateSqList(SqList* L, int n) //n为需要创建顺序表的长度
{
int i = 0;
//异常处理:
if (n > MAXSIZE || n < 1)
{
printf("顺序表的长度非法");
}
else
{
printf("请输入%d个数据:", n);
for (i = 0; i < n; i++)
{
scanf_s("%d", &L->elem[i]);
L->length++;
}
}
}
4.顺序表的打印
void PrintList(SqList L)
{
int i = 0;
for (i = 0; i < L.length; i++) {
printf("%d ", L.elem[i]);
}printf("\n");
}
5.顺序表的插入
注意:一个长度为N的顺序表有N+1个位置可以插入
Status ListInsert(SqList& L, int i, ElemType e)//i表示要插入的位置
{ //e表示要插入的数据元素
int j = 0;
if ((i < 1) || (i > L.length + 1)) return ERROR;//异常处理
if (L.length == MAXSIZE) return ERROR;
printf("在第%d个位置插入:\n", i); //提示语
for (j = L.length - 1; j >= i - 1; j--)
L.elem[j + 1] = L.elem[j]; //数据元素依次都已覆盖
L.elem[i - 1] = e; //插入数据元素
++L.length; //长度加一
return OK;
}
6.顺序表的删除
Status ListDelete(SqList& L, int i) //i表示要删除的位置
{
int j = 0;
if ((i < 1) || (i > L.length)) return ERROR;
printf("删除第%d个数据元素:\n",i); //提示语
for (j = i; j <= L.length - 1; j++)
L.elem[j - 1] = L.elem[j]; //数据元素依次前移覆盖
--L.length; //长度减一
return OK;
}
7.主函数
int main()
{
SqList L;
ElemType e=100; //准备插入的数据元素
int i;
InitList(L); //创建一个空表
CreateSqList(&L, 3); //创建指定大小的顺序表
PrintList(L); //打印顺序表
ListInsert(L, 2, e); //插入指定位置的数据元素
PrintList(L); //打印顺序表
ListDelete(L, 1); //删除指定位置的数据元素
PrintList(L); //打印顺序表
return 0;
}
8.测试与运行结果
请输入3个数据:1 11 111
1 11 111
在第2个位置插入:
1 100 11 111
删除第1个数据元素:
100 11 111
总结:
顺序表可以随机存取表中的任一元素,其存储位置可用一简单、直观的公式来表示。然而,从另一方面看,这个特点也造成了这种存储结构的缺点:再次插入或删除操作时,需要移动大量元素。另外由于数组有长度的相对固定的静态特性,当表中数据元素较多且变化较大时,操作过程相对复杂,必然导致存储空间的浪费。所以这些问题,都快可以通过线性表的另一种方式——链式存储结构来解决。
完整代码
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;//这是干嘛??
typedef char ElemType;
//定义顺序表类型
typedef struct
{
ElemType* elem;//动态数组的方式
// ElemType elem[MAXSIZE];静态数组的方式
int length;
}SqList;
//线性表的初始化
Status InitList(SqList &L)
{
L.elem = new ElemType[MAXSIZE];
if (!L.elem) exit(OVERFLOW);//异常处理——健壮性
L.length = 0;
return OK;
}
Status GetElem(SqList L, int i, ElemType& e)
{
if (i<1 || i>L.length) return ERROR;
e = L.elem[i - 1];
return OK;
}
int LocateElem(SqList L, ElemType e)
{
int i = 0;
for (i = 0; i < L.length; i++)
if (L.elem[i] == e) return i + 1;
return 0;
}
Status ListInsert(SqList& L, int i, ElemType e)
{
int j = 0;
if ((i < 1) || (i > L.length + 1)) return ERROR;
if (L.length == MAXSIZE) return ERROR;
printf("在第%d个位置插入:\n", i);
for (j = L.length - 1; j >= i - 1; j--)
L.elem[j + 1] = L.elem[j];
L.elem[i - 1] = e;
++L.length;
return OK;
}
Status ListDelete(SqList& L, int i)
{
int j = 0;
printf("删除第%d个数据元素:\n",i);
if ((i < 1) || (i > L.length)) return ERROR;
for (j = i; j <= L.length - 1; j++)
L.elem[j - 1] = L.elem[j];
--L.length;
return OK;
}
void CreateSqList(SqList* L, int n) //n为需要创建顺序表的长度
{
int i = 0;
if (n > MAXSIZE || n < 1)
{
printf("顺序表的长度非法");
}
else
{
printf("请输入%d个数据:", n);
for (i = 0; i < n; i++)
{
scanf_s("%d", &L->elem[i]);
L->length++;
}
}
}
void PrintList(SqList L)
{
int i = 0;
for (i = 0; i < L.length; i++) {
printf("%d ", L.elem[i]);
}printf("\n");
}
int main()
{
SqList L;
ElemType e=100;
int i;
InitList(L);//创建一个空表
CreateSqList(&L, 3);//创建指定大小的顺序表
PrintList(L);//打印顺序表
ListInsert(L, 2, e);//插入指定位置的数据元素
PrintList(L);//打印顺序表
ListDelete(L, 1);//删除指定位置的数据元素
PrintList(L);//打印顺序表
return 0;
}