/*
时间:2023年7月27日20:36:32
目的:考研
作者:wHappy
顺序表的实现(线性表的顺序存储结构)的特点 【数组实现】
(1)利用数据元素的存储位置表示线性表中相邻数据元素之间的前后关系,
即线性表的逻辑结构与存储结构一致
(2)在访问线性表时,可以快速地计算出任何-个数据元素的存储地址。
因此,可以粗略地认为,访问每个元素所花时间相等
这种存取元素的方法被称为 - 【随机存取法】
(3)顺序表的操作算法分析
·查找、插入、删除算法的平均时间复杂度
时间复杂度为O(n)
空间复杂度
·显然,顺序表操作算法的空间复杂度S(n)=0(1)(没有占用辅助空间)
(4) 顺序表优缺点
·优点:
·存储密度大(结点本身所占存储量/结点结构所占存储量)
·可以随机存取表中任一元素
·缺点:
·在插入、删除某一元素时,需要移动大量元素,浪费存储空间
·属于静态存储形式,数据元素的个数不能自由扩充
*/
# include <stdio.h>
# include <malloc.h>
# include "define.h"
# include <stdlib.h>
/*
时间:2023年7月27日20:36:32
目的:考研
作者:wHappy
顺序表的实现(线性表的顺序存储结构)的特点 【数组实现】
(1)利用数据元素的存储位置表示线性表中相邻数据元素之间的前后关系,
即线性表的逻辑结构与存储结构一致
(2)在访问线性表时,可以快速地计算出任何-个数据元素的存储地址。
因此,可以粗略地认为,访问每个元素所花时间相等
这种存取元素的方法被称为 - 【随机存取法】
(3)顺序表的操作算法分析
·查找、插入、删除算法的平均时间复杂度
时间复杂度为O(n)
空间复杂度
·显然,顺序表操作算法的空间复杂度S(n)=0(1)(没有占用辅助空间)
(4) 顺序表优缺点
·优点:
·存储密度大(结点本身所占存储量/结点结构所占存储量)
·可以随机存取表中任一元素
·缺点:
·在插入、删除某一元素时,需要移动大量元素,浪费存储空间
·属于静态存储形式,数据元素的个数不能自由扩充
*/
# ifndef _SEQUENCELIST_H
# define _SEQUENCELIST_H
# define SQLMAXSIZE 100
typedef int SqlElemType;
typedef struct _Sqlist //定义一个顺序表
{
SqlElemType *base; //定义一个动态数组
int length; //当前长度
} Sqlist;
Status InitSL(Sqlist* L, int length); //初始化
Status Is_Empty(Sqlist* L); //判空
Status GetSL_length(Sqlist* L); //数组长度
Status GetElem(Sqlist* L, int position, SqlElemType* e); //获取
int LocateElem(Sqlist* L, SqlElemType e); //查找
Status SqlInsert(Sqlist* L, int position, SqlElemType e); //插入
Status SqlDelete(Sqlist* L, int position, SqlElemType* e); //删除
Status SqlDestroy(Sqlist* L); //销毁
void SqlClear(Sqlist* L); //清空
void Traverse(Sqlist* L); //遍历
int main(void)
{
Sqlist L; //定义一个顺序表L
int len;
int val;
InitSL(&L,5);
len = GetSL_length(&L);
Traverse(&L);
printf("数组长度:len = %d\n",len);
//SqlDestroy(&L);
//SqlClear(&L);
//Traverse(&L);
//SqlInsert(&L, 1, 99);
//SqlDelete(&L,2,&val);
//Traverse(&L);
//len = GetSL_length(&L);
//printf("数组长度:len = %d\n",len);
return 0;
}
Status InitSL(Sqlist* L, int length) //初始化
{
L->base = (SqlElemType* )malloc(sizeof(SqlElemType)*SQLMAXSIZE);//动态分配数组内存
if(!L->base) // 异常处理 分配的没有内容 分配失败退出程序
return OVERFLOW;
L->length = 0;
for (int i=1; i<length+1; i++)
{
SqlElemType e; //用户输入的到数组元素
scanf("%d",&e);
SqlInsert(L,i,e); //插入元素
}
return OK;
}
Status Is_Empty(Sqlist* L) //判空
{
if(L->length == 0)
return OK;
else
return FALSE;
}
Status GetSL_length(Sqlist* L) //数组长度
{
return L->length;
}
Status GetElem(Sqlist* L, int position, SqlElemType* e) //获取 position:要获取的当前元素的位置 e:保存位置元素的值
{
//异常处理
if(position<1 || position>L->length)
return ERROR;
*e = L->base[position-1]; //逻辑位序和实际位序相差1,要找第i个元素,即第i个元素的下标为i-1
return OK;
}
void Traverse(Sqlist* L) //遍历
{
if(Is_Empty(L))
printf("数组为空!\n");
else
{
for(int i=0; i<L->length; i++)
printf("%d ",L->base[i]);
}
printf("\n");
}
/*
查找算法的时间复杂程度
最好情况 :T(n) = O(1)
最坏情况 :T(n) = O(n)
平均情况 :T(n) = O((n+1)/2)
*/
int LocateElem(Sqlist* L, SqlElemType e) //查找
{
for(int i=0; i<L->length; i++)
{
if(e == L->base[i])
return i+1;
}
return 0; //0代表查找的元素不在循环内
}
/*
插入算法的时间复杂程度
最好情况 :T(n) = O(1)
最坏情况 :T(n) = O(n)
平均情况 :T(n) = O(n/2)
*/
Status SqlInsert(Sqlist *L, int position, SqlElemType e) //插入
{
if(position<1 || position>L->length+1) //异常处理
return ERROR;
if (L->length == SQLMAXSIZE) //异常处理 数组最大
return OVERFLOW;
for(int i=L->length-1; i>=position-1; i--) //从第position开始往后移1位
L->base[i+1] = L->base[i]; //把第i数组赋值给后面元素
//插入元素
L->base[position-1] = e;
L->length++; //长度加一
return OK;
}
/*
删除算法的时间复杂程度
最好情况 :T(n) = O(1)
最坏情况 :T(n) = O(n)
平均情况 :T(n) = O((n-1)/2)
*/
Status SqlDelete(Sqlist* L, int position, SqlElemType* e) //删除
{
if(position<1 || position>L->length) //异常处理
return ERROR;
for(int i=position; i<L->length; i++) //将length个元素一个一个往前移到position,
L->base[i-1] = L->base[i]; //从position的后一个位置移到position的前一个位置
*e = L->base[position-1]; //删除的原始值
L->length--; //最终长度位置要减1
return OK;
}
Status SqlDestroy(Sqlist* L) //销毁
{
if (!L->base)
return ERROR;
else
{
free(L->base);
printf("数组已销毁!\n");
}
return OK;
}
void SqlClear(Sqlist* L) //清空
{
L->length = 0; //清空数组长度
printf("数组元素已清空!\n");
}
#endif