1.线性表的定义:
线性表是具有相同数据类型的n(n>=0)个数据元素的有限序列,n为表长,n=0时线性表是一个空表。(注意位序与数组下标的区别)
2.线性表的基本操作
InitList(&L):初始化线性表。
DestroyList(&L):销毁操作
ListInsert(&L,i,e):插入操作(i表示在第i位置上插入元素,e表示插入元素的内容)
ListDelet(&L,i,&e):删除操作,i表示删除第i位置的元素,e用来返回删除元素的内容
LocateElem(L,e):按值查找
GetElem(L,i):按位查找
Length(L):求表长
Empty(L):判空操作
PrinList(L):输出操作
3.线性表的顺序存储如下图所示
把逻辑上相邻的元素在物理位置也相邻。
判断一个数据元素 的大小通常用sizeof函数来实现,类型如下:
sizeof(ElemType)
由于线性表具有相同的数据元素类型所以每一个数据元素所占用的内存空间大小相同。
4.顺序表的实现静态分配
如下图所示定义一个int类型
此时存储空间的大小为:MaxSize*sizeof(int)
初始化顺序表
用静态分配方式输出打印数组
5.顺序表实现动态分配
以int类型为例
初始化:
动态申请和释放空间所用的函数为:malloc和free函数
L.data=(ElemType*)malloc(sizeof(ElemType)*InitSize);
初始化顺序表
增加动态数组长度
例子
#include<stdlib.h>
#include<stdio.h>
#define InitSize 10//顺序表的初始长度
typedef struct {
int* data;//指示动态分配数组的指针
int MaxSize;//顺序表的最大容量
int length;//顺序表的当前长度
}SqList;
//初始化顺序表
void InitList(SqList &L) {
L.data = (int*)malloc(sizeof(int) * InitSize);//申请一片连续的存储空间
L.length = 0;
L.MaxSize = InitSize;
}
//增加动态数组的长度
void IncreaseSize(SqList& L, int len) {
int* p = L.data;
L.data = (int*)malloc((L.MaxSize + len) * sizeof(int));
for (int i = 0; i < L.MaxSize; i++)
L.data[i] = p[i];//将数据复制到新的区域
L.MaxSize += len;//顺序表增加长度为len
free(p);//释放原来的内存空间
}
int main() {
SqList L;
InitList(L);
IncreaseSize(L, 10);
for (int i = 0; i < 18; i++)
printf("data[i]=%d\n",i);
}
顺序表的特点:
1.随机访问,可以在O(1)时间内找到第I个元素
2.存储密度高
3.拓展容量不方便,会增加时间开销
4.插入删除操作不方便,需要移动大量的元素。
二、顺序表的插入与删除
1.顺序表的插入(以静态分配为例)
ListInsert(&L,i,e):插入操作(i表示在第i位置上插入元素,e表示插入元素的内容)
最好情况下,当插入表尾不需要移动元素,此时为O(1)
最坏情况下,插入表头需要移动原有的n个元素,此时为O(n)
平均情况下,插入任一位置概率相同为p=1/(n+1),则平均概率为(1+2+..+n)*p=n/2即为
O(n)
完整代码示例
//顺序表插入操作
#include<stdio.h>
#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) {
if (i<1 || i>L.length + 1)//判断插入是否合法
return false;
if (L.length >= MaxSize)//判断当前存储空间是否已满
return false;
for (int j = L.length; j >= i; j--)//将第i个元素及i之后的元素后移
L.data[j] = L.data[j - 1];
L.data[i - 1] = e;//将位置i放入e
L.length++;//长度加1
return true;
}
int main() {
SqList L;
InitList(L);
ListInsert(L, 3, 20);
}
2.顺序表的删除操作
时间复杂度分析