1 原理
特点:
表中元素的个数是有限的。
表中元素的数据类型都相同。意味着每一个元素占用相同大小的空间
表中元素具有逻辑上的顺序性,在序列中各元素排序有其先后顺序
线性表的逻辑结构是独立于存储结构的
优缺点
优点:
- 可以随机存取(根据表头元素地址和元素序号)表中任意一个元素。
- 存储密度高,每个结点只存储数据元素。
缺点:
- 插入和删除操作需要移动大量元素。
- 线性表变化较大时,难以确定存储空间的容量。
- 存储分配需要一整段连续的存储空间,不够灵活。
2 顺序表表示
2.1 定义
#define MaxSize 50
typedef int ElemType;//让顺序表存储其他类型元素,可以快速完成代码修改的顺序
//静态分配
typedef struct {
ElemType data[MaxSize];
int len;
}SqList;
2.2 插入元素
//顺序表的插入,因为L会改变所以需要使用引用,pos是插入的位置
bool ListInsert(SqList &L, int pos,ElemType ele)
{
//判断pos是否合法
if(pos<1 || pos >L.len+1)
{
return false;
}
//如果存储空间满了,不能插入
if(L.len == MaxSize)
{
return false;
}
//把后面的元素依次往后移动,空出位置
for(int j = L.len; j >= pos; j--)
{
L.data[j] = L.data[j-1];
}
L.data[pos-1]=ele;
L.len++;//顺序表长度+1
return true;
}
计算时间复杂度:
最好情况:在表尾插入元素,不需要移动元素,时间复杂度为0(1)。
最坏情况:在表头插入元素,所有元素依次后移,时间复杂度为O(n)。
平均情况:在插入位置概率均等的情况下,平均移动元素的次数为n/2,时间 复杂度为O(n)。
2.3 删除元素
//删除顺序表中的元素,del为了获取被删除元素的值
bool ListDelete(SqList &L, int i, ElemType &del)
{
//判断删除的元素的位置是否合法
if(i<1 || i> L.len)
{
return false;
}
del = L.data[i-1]; //保存要删除元素的值
for(int j = i-1; j < L.len-1;j++)
{
L.data[j] = L.data[j+1];
}
L.len--;//长度-1
return true;
}
计算时间复杂度:
最好情况:删除表尾元素,不需要移动元素,时间复杂度为0(1)。
最坏情况:删除表头元素,之后的所有元素依次前移,时间复杂度为O(n)。
平均情况:在删除位置概率均等的情况下,平均移动元素的次数为(n-1)/2,时间 复杂度为O(n)。
2.4 查找元素
int LocateElem(SqList L, ElemType ele)
{
int i;
for(i = 0; i < L.len; i++)
{
if(ele == L.data[i])
{
return i+1; // i是数组的下表,+1才是顺序表的
}
}
return 0;
}
2.5 打印顺序表
//打印顺序表
void PrintList(SqList L)
{
int i;
for( i= 0; i<L.len; i++)
{
printf("%3d",L.data[i]);
}
printf("\n");
}
代码实战
#include <stdio.h>
/**命名规范 变量名或者函数名
* 1、下划线命名法list_insert 不同的单词用下划线
* 2、驼峰命名法ListInsert,每个单词的首字母大写
* **/
#define MaxSize 50
typedef int ElemType;//让顺序表存储其他类型元素,可以快速完成代码修改的顺序
//静态分配
typedef struct {
ElemType data[MaxSize];
int len;
}SqList;
//顺序表的插入,因为L会改变所以需要使用引用,pos是插入的位置
bool ListInsert(SqList &L, int pos,ElemType ele)
{
//判断pos是否合法
if(pos<1 || pos >L.len+1)
{
return false;
}
//如果存储空间满了,不能插入
if(L.len == MaxSize)
{
return false;
}
//把后面的元素依次往后移动,空出位置
for(int j = L.len; j >= pos; j--)
{
L.data[j] = L.data[j-1];
}
L.data[pos-1]=ele;
L.len++;//顺序表长度+1
return true;
}
//打印顺序表
void PrintList(SqList L)
{
int i;
for( i= 0; i<L.len; i++)
{
printf("%3d",L.data[i]);
}
printf("\n");
}
//删除顺序表中的元素,del为了获取被删除元素的值
bool ListDelete(SqList &L, int i, ElemType &del)
{
//判断删除的元素的位置是否合法
if(i<1 || i> L.len)
{
return false;
}
del = L.data[i-1]; //保存要删除元素的值
for(int j = i-1; j < L.len-1;j++)
{
L.data[j] = L.data[j+1];
}
L.len--;//长度-1
return true;
}
int LocateElem(SqList L, ElemType ele)
{
int i;
for(i = 0; i < L.len; i++)
{
if(ele == L.data[i])
{
return i+1; // i是数组的下表,+1才是顺序表的
}
}
return 0;
}
//顺序表的操作
int main() {
SqList L; //定义一个顺序表
bool ret;//一般用ret来代表函数返回值
ElemType del;
L.data[0]=1;
L.data[1]=2;
L.data[2]=3;
L.len=3;
ret = ListInsert(L,2,60);
if(ret == true)
{
printf("insert sqList success!");
PrintList(L);
}
else
{
printf("insert sqList failed!");
}
ret = ListDelete(L, 1,del);
if(ret == true)
{
printf("del sqList success!");
printf("del =%d\n",del);
PrintList(L);
}
else
{
printf("del sqList failed!");
}
//查找
int pos;//元素位置
pos = LocateElem(L,100);
if(pos)
{
printf("pos = %d\n",pos);
printf("find this elemen\n");
}
else{
printf("do not find this element\n");
}
return 0;
}