数据结构概念
1.什么是数据结构?
数据结构(Data Structure)是计算机存储、组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合。
2.什么是算法?
算法(Algorithm):就是定义良好的计算过程,他取一个或一组的值为输入,并产生出一个或一组值作为输出。简单来说算法就是一系列的计算步骤,用来将输入数据转化成输出结果。
3.算法效率
算法效率分析分为两种:第一种是时间效率,第二种是空间效率。
时间复杂度:算法中的基本操作的执行次数,为算法的时间复杂度。
空间复杂度:空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度 。
实际中我们计算时间和空间复杂度时,我们其实并不一定要计算精确的执行次数,而只需要大概执行次数,那么这里我们使用大O的渐进表示法。
顺序表
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
顺序表一般可以分为:
1. 静态顺序表:使用定长数组存储。
2. 动态顺序表:使用动态开辟的数组存储。
线性表每个元素必须有前驱和后继
静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以下面我们实现动态顺序表。
动态顺序表接口实现
**1.顺序表初始化**
// An highlighted block
void SeqListInit(SeqList *pst, size_t capacity)
{
pst->capacity = capacity;
pst->base = (ElemType*)malloc(sizeof(ElemType) * pst->capacity);
assert(pst->base != NULL);
memset(pst->base, 0, sizeof(ElemType)*pst->capacity);
pst->size = 0;
}
**2.尾插**
// An highlighted block
void SeqListPushBack(SeqList *pst, ElemType v)
{
//检查容量
if(_IsFull(pst) && !_Inc(pst))
{
printf("顺序表容量不足,%d 不能插入.\n", v);
return;
}
pst->base[pst->size++] = v;
}
**头插**
// An highlighted block
void SeqListPushFront(SeqList *pst, ElemType v)
{
//检查容量
if(_IsFull(pst) && !_Inc(pst))
{
printf("顺序表容量不足,%d 不能插入.\n", v);
return;
}
//移动数据
for(int i=pst->size; i>0; --i)
{
pst->base[i] = pst->base[i-1];
}
//插入数据
pst->base[0] = v;
pst->size++;
}
**3.存储数据显示**
// An highlighted block
void SeqListShow(SeqList *pst)
{
for(int i=0; i<pst->size; ++i)
printf("%d ", pst->base[i]);
printf("\n");
}
**4.尾删**
// An highlighted block
void SeqListPopBack(SeqList *pst)
{
if(_IsEmpty(pst))
{
printf("顺序表已空,不能删除.\n");
return;
}
//删除数据
pst->size--;
}
**5.头删**
// An highlighted block
void SeqListPopFront(SeqList *pst)
{
if(_IsEmpty(pst))
{
printf("顺序表已空,不能删除.\n");
return;
}
//将顺序表中的数据前移一位(第一个数据除外)
for(int i=0; i<pst->size-1; ++i)
pst->base[i] = pst->base[i+1];
//将size值减1,来达到删除的目的
pst->size--;
}
**6.按位置插入数据**
// An highlighted block
void SeqListInsertByPos(SeqList *pst, int pos, ElemType v)
{
//检查容量
if(_IsFull(pst) && !_Inc(pst))
{
printf("顺序表容量不足,%d 不能插入.\n", v);
return;
}
//判断顺序表空间是否满且增加空间是否失败?
if(pos<0 || pos>pst->size)
{
printf("插入的位置非法, %d 不能插入.\n", v);
return;
}
//将该位置及其之后的数据都向后移动一位并插入数据
for(int i=pst->size; i>pos; --i)
pst->base[i] = pst->base[i-1];
pst->base[pos] = v;
pst->size++;
}
**7.按值插入**
// An highlighted block
void SeqListInsertByVal(SeqList *pst, ElemType v)
{
//寻找插入的位置
int pos = 0;
while(pos<pst->size && v>pst->base[pos])
pos++;
//插入数据
SeqListInsertByPos(pst, pos, v);
}
void SeqListEraseByPos(SeqList *pst, int pos)
{
//检查位置
if(pos<0 || pos>=pst->size)
{
printf("删除的位置非法,不能删除数据.\n");
return;
}
//删除数据
for(int i=pos; i<pst->size-1;