线性表的顺序存储
线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素,使得线性表在逻辑结构上相邻的元素存储在连续的物理存储单元中,即:通过数据元素物理存储的连续性来反应元素之间逻辑上的相邻关系。采用顺序存储结构存储的线性表通常简称为顺序表。
顺序存储的线性表的特点:
◆ 线性表的逻辑顺序与物理顺序一致;
◆ 数据元素之间的关系是以元素在计算机内“物理位置相邻”来体现。
顺序表的线性存储示意图
假设线性表中有n个元素,每个元素占k个存储单元,第一个元素的地址为Loc(a1),则第i个元素的地址Loc(ai):
Loc(ai) = Loc(a1) + (i-1) * k;
其中Loc(a1)称为基地址。
# include <stdio.h>
# include <malloc.h>
# define MAXSIZE 10 //线性表存储空间初始分配量
# define INCREMENT 5 //线性表存储空间分配增量
typedef struct
{
int* elem; //存储空间基址(指向顺序表第一个元素)
int length; //当前长度
int listsize; //顺序表的存储空间(容量),初始化为MAXSIZE
}Sqlist; //顺序表类型
int InitialList(Sqlist &L)
{
//构造一个空的线性表
L.elem = (int*)malloc(MAXSIZE * sizeof(int));//开辟新空间
if (!L.elem) return false; //存储分配失败
L.length = 0; //空表长度为0
L.listsize = MAXSIZE; //初始存储容量
return 1;
}
int ListInsert(Sqlist& L, int i, int item)
{
//在顺序线性表L中第i个位置之前插入新的元素item,i的合法值为(1<=i<=listlength+1)
int* base, * insertptr; //base指向新开辟空间地址,insertptr为插入位置
if (i<1 || i>L.length + 1) return false; //非法插入
if (L.length >= L.listsize) //当前存储空间已满,增加分配
{
base = (int*)realloc(L.elem,(L.listsize+ INCREMENT) * sizeof(int));
if (base == NULL) return 0; //分配失败
L.elem = base; //新基址
L.listsize += INCREMENT; //增加存储容量
}
insertptr = &(L.elem[i - 1]); //插入位置
for (int *p = &(L.elem[L.length - 1]); p >= insertptr; p--) //插入位置之后元素,从后向前,右移
{
*(p + 1) = *p;
}
*insertptr = item; //插入元素item
L.length++; //表长增1
return 1;
}
int ListDelete(Sqlist& L, int i, int item)
{
//顺序表L中删除位置i的元素item
int* p,*q;
if ((i < 1) || (i > L.length)) return 0; //非法删除
p = &(L.elem[i - 1]); //p是被删除元素的指针
item = *p; //用item返回被删除节点的值
q = L.elem + L.length - 1;//最后一个元素的指针
for (++p; p <= q; ++p) //从被删除节点的下一个节点开始,从前向后依次左移
{
*(p - 1) = *p;
}
--L.length; //表长减1
return 1;
}
int main()
{
Sqlist list1;
InitialList(list1);
for (int i = 1; i < 21; i++) //插入元素从下标1开始
{
ListInsert(list1, i, i);
}
printf("%d \n", list1.length);
for (int i = 0; i < list1.length; i++) //输出元素从下标0开始
printf("%d ", list1.elem[i]);
for (int i = 1,j = 1; i < 6; i++) //删除元素从下标1开始
{
int tem = 0;
ListDelete(list1, j, tem);
}
printf(" \n%d \n", list1.length);
for (int i = 0; i < list1.length; i++) //输出元素从下标0开始
printf("%d ", list1.elem[i]);
return 0;
}
运行结果