一.线性表
1.定义
具有相同数据类型的n个(n>=0)数据元素的有限序列。n为表长。
表示:
L
=
(
a
1
,
a
2
,
.
.
.
a
i
,
a
i
+
1
.
.
.
,
a
n
)
L = (a_1,a_2,...a_i,a_{i+1}... ,a_n)
L=(a1,a2,...ai,ai+1...,an) i 为位序,从1开始
2.基本操作
InitList(&L) 初始化表,分配存储空间
DestroyList(&L) 销毁表,释放存储空间
ListInsert(&L,i,e) 在表中第i个位置插入元素e
ListDelete(&L,i,&e) 删除表L中第i个位置的元素,并用e返回删除元素的值
LocateElem(L,e) 按值查找
GetElem(L,i) 按位查找
Length(L) 求表长度(元素个数)
PrintList(L) 顺序输出所有元素值
Empty(L) 判空
二.线性表之顺序表
1.定义
用顺序存储的方式实现线性表
顺序存储: 逻辑上相邻的元素存储在物理位置也相邻的存储单元中
数据元素大小: sizeof(int / struct A)
2.实现(静态分配)
#define MaxSize 10 //最大长度
typeof struct{
Elemtype data[MaxSize]; //静态“数组”存放数据,类型为Elemtype
int length; //顺序表当前长度
}SeqList; //起名
3.实现(动态分配)
#define InitSize 10 //初始长度
typedef struct{
ElemType *data; //动态分配数组的指针
int MaxSize; //顺序表最大容量
int length; //当前长度
}SeqList;
malloc:动态申请内存空间
L.data = (ElemType *)malloc(sizeof(ElemType) * InitSize)
free:动态释放内存空间
free(p)
释放p指向的一片存储空间
#include <stdlib.h> //包含malloc\free的头文件
#define InitSize 10
typedef struct{
int *data;
int MaxSize; //表最大容量
int length; //表当前长度(有目的内容的长度)
}SeqList;
//初始化表
void InitList(SeqList &L){
L.data = (int *)malloc(InitSize*sizeof(int));//申请一片连续的存储空间
L.length = 0;
L.MaxSize = InitSize;
}
//追加空间
void IncreaseSize(SeqList &L,int len){
int *p = L.data;
L.data = (int *)malloc((L.MaxSize+len)*sizeof(int));
for(int i=0;i<L.length;i++){
L.data[i] = p[i]; //复制元素到新空间
}
L.MaxSize = L.L.MaxSize+len; //最大长度变长
free(p);
}
int main(){
SeqList L;
InitList(L);
//随便加几个元素
/*for(int i=0;i<L.length;i++){
L.data[i] = i;
}*/
IncreaseSize(L,5); //追加5个单位的空间
return 0;
}
![存储空间结构](http://ghy121.gitee.io/img-bed/picture/20200716/1.png)
4.顺序表特点
- 随机访问,可在O(1)时间内找到第i个元素
- 存储密度高,每个节点只存数据元素
- 拓展容量不方便
- 插入、删除元素不方便
5.基本操作
ListInsert(&L,i,e):在L中的第i个位置插入指定元素e。
插入
void ListInsert(SqList &L,int i,int e){
for(int j=L.length;j>=i;j--)
L.data[j] = L.data[j-1];
L.data[i-1] = e;
L.length++;
}
若L.length = 5,MaxSize = 10,调用ListInsert(L,8,3),则位置7、6(L.data[6]、L.data[5])是空的。
避免:判断 i 是 否 ∈ [ 1 , L . l e n g t h + 1 ] i是否\in[1,L.length+1] i是否∈[1,L.length+1]
bool ListInsert(sqList &L,int i,int e){
if(i<1 || i>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];
L.data[i-1] = e;
L.length++;
return true
}
时间复杂度
n = L.length
最好情况:插入到表尾 循环0次 T ( n ) = O ( 1 ) T(n) = O(1) T(n)=O(1)
最坏情况:插入到表头 循环n次 T ( n ) = O ( n ) T(n) = O(n) T(n)=O(n)
平均情况: T ( n ) = ( n + n − 1 + n − 2 + . . . + 0 ) 1 n + 1 = n 2 = O ( n ) T(n) = (n+n-1+n-2+...+0)\frac{1}{n+1} = \frac{n}{2} = O(n) T(n)=(n+n−1+n−2+...+0)n+11=2n=O(n)
删除
bool ListDelete(SqList &L,int i,int &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 main(){
SqList L;
InitList(L);
//插入元素
int e = -1;
if(ListDelete(L,3,e))
printf("删除了第3个元素,值为%d\n",e);
else
printf("位序i不合法,删除失败\n");
return 0;
}
时间复杂度
n = L.length
T ( n ) = O ( n ) T(n) = O(n) T(n)=O(n)
按位查找
ElemType GetElem(SeqList L,int i){
return L.data[i-1];
}
时间复杂度:O(1)
按值查找
//在顺序表L中查找第一个元素等于e的元素,并返回其位序
int LocateElem(SeqList L,ElemType e){
for(int i=0;i<L.length;i++){
if(L.data[i] == e)
return i+1;
}
return 0;
}
时间复杂度: T ( n ) = O ( n ) T(n) = O(n) T(n)=O(n)
C语言 结构体不能用 == 比较
参考王道数据结构课程做的笔记