0.引言
顺序表数据结构相对简单,操作起来方便,即使有时运行效率未必理想。
对于顺序表,通常是静态分配和动态分配两种类型。因方便,本文仅以静态分配为例。
和所有数据结构一样,最基础的部分无非是建立、销毁、增、删、改、查、遍历。
1.建立
01.定义顺序表
(1)静态分配
#define MaxSize 50
typedef int ElemType;//顺序表中元素的类型
//静态分配
typedef struct {
ElemType data[MaxSize];//定义的数组,用来存元素
int length;//当前顺序表中有多少个元素
}SqList;
(2)动态分配
#define InitSize 10//默认的最大长度
typedef int ElemType;
typedef struct {
ElemType* data;//指示动态分配数组的指针
int MaxSize;//顺序表的最大容量
int length;//顺序表的当前长度
}SeqList;
(3)动态分配长度增加
void IncreaseSize(SeqList& L, int len)
{
ElemType* p = L.data;
L.data = (ElemType*)malloc((L.MaxSize + len) * sizeof(ElemType));
for (int i = 0; i < L.length; i++)
{
L.data[i] = p[i];//将数据复制到新区域
}
L.MaxSize = L.MaxSize + len;//顺序表最大长度增加len
free(p);//释放原来的内存空间
}
02.初始化顺序表
(1)静态分配
void InitList(SqList& L)
{
for (int i = 0; i < MaxSize; i++)
{
L.data[i] = 0;
}
L.length = 0;
}
(2)动态分配
void InitList(SeqList& L)//用malloc函数申请一片连续的存储空间
{
L.data = (ElemType*)malloc(InitSize * sizeof(int));
L.length = 0;
L.MaxSize = InitSize;
}
2.增:插入元素
bool ListInsert(SqList& L, int i, ElemType 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];
L.data[i - 1] = e;//数组下标从零开始,插入第一个元素,访问的下标为0
L.length++;
return true;//走到这里代表插入成功,返回true
}
3.删:删除元素
bool ListDelete(SqList& L, int i, ElemType& e)
{
if (i<1 || i>L.length)//如果删除的位置不合法
return false;
if (L.length == 0)//顺序表中没有元素,无需删除
return false;
e = L.data[i - 1];//获取顺序表中对应的元素,赋值给e
for (int j = i; j < L.length; j++)//从i的位置依次往前覆盖
L.data[j - 1] = L.data[j];
L.length--;//删除一个元素,顺序表长度减1
return true;
}
4.查:查找元素
(1)按位查找
a.静态分配
ElemType GetElem(SqList L, int i)//按位查找
{
return L.data[i - 1];
}
b.动态分配
ElemType GetElem(SeqList L, int i)//按位查找
{
return L.data[i - 1];
}
(2)按值查找
a.静态分配
int LocateElem(SqList& L, ElemType e)
{
int i;
for (i = 0; i < L.length; i++)
if (L.data[i] == e)
return i + 1;//加1就是元素在顺序表中的位置
return 0;
}
b.动态分配
int LocateElem(SeqList& L, ElemType e)//按值查找
{
int i;
for (i = 0; i < L.length; i++)
if (L.data[i] == e)
return i + 1;//加1就是元素在顺序表中的位置
return 0;
}
5.遍历:打印顺序表
void PrintList(SqList& L)
{
for (int i = 0; i < L.length; i++)
{
printf("%4d", L.data[i]);
}
printf("\n");
}
附:
1.关于销毁和改
由于顺序表静态分配靠数组实现,在程序运行时根据存储类型决定占用内存时间,因而不在此写销毁。而对于动态分配的情况,调用free函数即可。
关于改,只要用数组访问或者用指针间接访问即可。
2.此文代码中语法问题
以上因为书写方便,故使用到布尔类型、引用等C++语法,所以使用以上代码文件名后缀要改为cpp,其余书写与C++几乎无关
如果用纯C语言,示例如下:
int ListInsert(SqList* L, int i, ElemType e)
{
if (i<1 || i>L->length + 1)
return 0;
if (L->length >= MaxSize)
return 0;
for (int j = L->length; j >= i; j--)
L->data[j] = L->data[j - 1];
L->data[i - 1] = e;
L->length++;
return 1;
}
主程序调用时
int main(int argc,int* argv[])
{
int i = ListInsert(&L, n, e);
return 0;
}