数据结构(第二章)线性表1——顺序表
线性表的定义:具有相同数据类型的 n ( n ≥ 0 ) n(n\geq0) n(n≥0)个数据元素的有限序列,其中n为表长,当n=0时,线性表是一个空表。若用L命名线性表,则其一般表示为:L=(a1,a2,…,ai,ai+1,…,an)
相同数据类型:每个数据元素所占空间一样大
有限序列:有序表
ai表示线性表中第i个元素线性表中的位序
除了第一个元素之外,每个元素有且仅有一个直接前驱;除了最后一个元素外,每个元素有且仅有一个直接后继。
顺序存储:逻辑上相邻的元素存储在物理位置上也相邻的存储单元中,元素之间的关系由存储单元的邻接关系来体现
- 优点:实现随机存储,每个元素占用最少的存储空间
- 缺点:只能使用相邻的一整块存储单元,一次可能产生较多的外部碎片
顺序表的本质是一维数组,分为静态存储和动态存储两种。这里的动态存储需要和链表的动态存储区分开,顺序表的动态存储结构仍为在内存中申请一片连续的内存空间。
顺序表之静态存储
需要注意的是:位序i(从1开始计数)对应的是数组中的第i-1个元素
#include <stdio.h>
#include <stdlib.h> //malloc、free的头文件
// ———————————————————————————————————顺序表的静态实现
#define MaxSize 10 // 定义最大长度
typedef struct{
int data[MaxSize]; // 定义静态数组存放元素
int length; // 顺序表的当前长度
}SqList;
// 静态顺序表初始化
void InitList(SqList &L){
for(int i=0;i<MaxSize;i++){
L.data[i]=0;
}
L.length=0;
}
// 静态顺序表的插入
bool ListInsert( SqList &L ,int i,int e){ // 在顺序表的第i个位置(位序)插入元素e
if(i<1 || i>L.length+1){return false;} // 插入的数据位置不合法
if(L.length>=MaxSize){return false;} // 当前存储空间已满
for(int j=L.length;j>=i;j--){
L.data[j]=L.data[j-1]; //从第i个位置位序为i,对应数组下表为i-1开始,从后向前依次已从元素
}
L.data[i-1]=e;
L.length++;
return true;
}
// 静态顺序表的删除
bool ListDelete(SqList &L,int i ,int &e){ // 删除表L中的第i个位置的元素,并将该元素用e返回
if(i<1 || i>L.length){return false;}
e=L.data[i-1];
for(int j=i;j<L.length;j++){
L.data[j-1]=L.data[j];
}
L.length--;
return true;
}
// 静态顺序表的查找
int LocateElem(SqList L,int e){ // 查找一个元素值为e的元素,并返回其位序
for(int i=0;i<L.length;i++){
if(L.data[i]==e)
return i+1; //返回位序
}
return -1; //否则返回-1
}
// 简单演示
int main(){
SqList L;
InitList(L);
ListInsert(L,1,520); // 插入数据
ListInsert(L,1,521); // 插入数据
ListInsert(L,1,522); // 插入数据
ListInsert(L,1,523); // 插入数据
for(int i=0;i<L.length;i++){
printf("data[%d]=%d\n",i,L.data[i]);
}
int e=0; // 定义一个e来接收删除的元素
if(ListDelete(L,1,e)){ //如果删除成功则输出删除元素的数值
printf("删除的元素为:%d\n",e);
}
for(int i=0;i<L.length;i++){
printf("data[%d]=%d\n",i,L.data[i]);
}
printf("521在顺序表中的位序为%d\n",LocateElem(L,521));
return 0;
}
演示结果为:
顺序表之动态存储
动态增加内存单元其实是要另开辟一个连续的存储空间
#include <stdio.h>
#include <stdlib.h> //malloc、free的头文件
//——————————————————————————————————— 顺序表的动态实现
#define InitSzie 10 // 默认的最大长度
typedef struct{
int * data; // 指示动态分配数组的指针
int MaxSize1; // 顺序表最大容量
int length; // 当前数组个数
}SeqList;
// 动态顺序表初始化
void InitList1(SeqList &L){
L.data=(int *)malloc(InitSzie*sizeof(int)); //申请一片连续的存储空间
L.MaxSize1=InitSzie;
L.length=0;
}
// 动态顺序表增加内存单元
void IncreaseSize(SeqList &L ,int len){
int *p=L.data;
L.data=(int *)malloc((L.MaxSize1+len)*sizeof(int));
for(int i=0;i<L.length;i++){
L.data[i]=p[i]; // 申请的空间在内存中为新的一片连续的存储空间,依次把原来的数据复制到新申请的空间中去
}
L.MaxSize1=L.MaxSize1+len;// 顺序表的最大容量增加len
free(p); // 释放空间
}
// --------增删改查与静态存储类似
// 简单演示
int main(){
SeqList L1;
InitList1(L1);
printf("%d\n",L1.MaxSize1);
IncreaseSize(L1,5); // 增加动态数组空间
printf("%d\n",L1.MaxSize1);
return 0;
}
演示结果为: