1.定义:用一组连续的存储单元依次存储线性表中的各个元素
在逻辑上相邻,在物理上也相邻
口诀:关系线性化,节点顺序存
顺序表有两种存储结构:
typedef struct
{
Elemtype elem[MAXSIZE];
int last;
}Sqlist;
typedef struct
{
Elemtype * elem;
int length;
}Sqlist;
下面给出第一种存储结构的一些基本操作的代码:
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#define OK 1
#define ERROR 0
#define Elemtype int
#define MAXSIZE 100
#define ERROR1 -1
typedef struct
{
Elemtype elem[MAXSIZE];
int last;
}Sqlist;
void InitList(Sqlist & L); //建空表,并且初始化
int Input_Sqlist(Sqlist & L); //输入
int GetElem(Sqlist L, int i,Elemtype &e); //根据位置i获取数据元素的内容,取值
int LocateElem(Sqlist L, int e); //根据指定数据获取所在的位置,查找
int ListInsert_Sq(Sqlist &L, int i, Elemtype e); //插入
int ListDelete_Sq(Sqlist &L, int i); //删除
int showList(Sqlist L); //输出
int main()
{
int i;
Elemtype e,m;
Sqlist L;
InitList(L);
if(!Input_Sqlist(L))
exit(0);
//取值,用e带回取得的值
std::cout << "取值,输入:" << std::endl;
std::cin >> i;
if(!GetElem(L, i, e))
std::cout <<"输入无效" << std::endl;
else
std::cout<<e << std::endl;
//查找,用返回值
std::cout << "查找,输入:" << std::endl;
std::cin >> m;
if (!LocateElem(L, m))
std::cout << "未找到" << std::endl;
else
std::cout << LocateElem(L, m) << std::endl;
//插入
std::cout << "插入,输入:" << std::endl;
std::cin >> i >> e;
int r;
if (!(r=ListInsert_Sq(L, i, e)))
std::cout << "输入无效" << std::endl;
else if (!(r + 1))
std::cout << "空间已满" << std::endl;
else
showList(L);
//删除
std::cout << "删除,输入:" << std::endl;
std::cin >> i;
if(!ListDelete_Sq(L, i))
std::cout <<"删除无效"<<std::endl;
else
showList(L);
}
//初始化
void InitList(Sqlist & L)
{
L.last = -1;//数组本身已经分配好空间
}
//输入
int Input_Sqlist(Sqlist & L)
{
int num;
std::cout << "输入的数据的数量:" << std::endl;
std::cin >> num;
if (num > MAXSIZE || num < 1)
return ERROR;
std::cout << "输入" <<num<<"个:"<< std::endl;
for (int i = 0; i < num; i++)
{
std::cin >> L.elem[i];
L.last++;
}
return OK;
}
//取值
int GetElem(Sqlist L, int i, Elemtype &e)
{
if (i<1 || i>L.last + 1)
return ERROR;
else
{
e = L.elem[i - 1];
return OK;
}
}
//查找
int LocateElem(Sqlist L, int e)
{
int i = 0;
while (i <= L.last&&L.elem[i] != e)
i++;
if (i > L.last)
return ERROR;
else
return i+1;
}
//插入
int ListInsert_Sq(Sqlist &L, int i, Elemtype e)
{
//i的合法取值范围是:1<=i<=L.last +2
if (i<1 || i>L.last + 2)//输入是否合法,注意是加2
return ERROR;
else if (L.last + 1 == MAXSIZE)//数组是否是满的
return ERROR1;
else
{
for (int j = L.last; j >= i-1; j--)
L.elem[j + 1] = L.elem[j];
}
L.elem[i-1] = e;
L.last++;
return OK;
}
//删除
int ListDelete_Sq(Sqlist &L, int i)
{
if(i<1||i>L.last+1)//检查输入,注意是加1,与插入不同
return ERROR;
else
{
for (int j = i; j <L.last+1 ; j++)
L.elem[j] = L.elem[j + 1];
L.last--;
}
return OK;
}
//输出
int showList(Sqlist L)
{
for (int i = 0; i <= L.last; i++)
std::cout << L.elem[i]<<" ";
std::cout << std::endl;
return 0;
}
而对于第二种存储结构,初始化有些许差别:
void InitList(Sqlist & L)
{
L.elem = (Elemtype *)malloc(MAXSIZE*sizeof(Elemtype));
L.length = 0;
}
查找,删除,插入,取值的代码只需要将L.last 换成L.length-1即可;
顺序表算法分析
查找,删除,插入算法的平均时间复杂度为O(n);
查找,删除,插入算法的空间复杂度为O(1),没有占用辅助空间;
优点:
1.存储密度大(节点本身所占存储量/节点结构所占存储量)
2.可以随机存储表中任意元素
缺点:
1.插入,删除时需要移动大量元素
2.浪费存储空间
3.属于静态存储形式,元素的个数不能任意扩展