函数接口声明
函数实现
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构。一般情况下采用数组存储,在数组上完成数据的增删查改。
顺序表一般分为:
1.静态顺序表:使用定长数组存储
2.动态顺序表:使用动态开辟数据存储。
下面首先定义一个顺序表的结构:
typedef struct SeqList
{
ElemType *base; // base类似于数组名;
size_t capacity; //顺序表容量;
size_t size; // size为目前已存储的元素个数;
}SeqList;
函数接口声明
为了对顺序表进行一些基本操作,给出以下函数接口声明:
static bool _Inc(SeqList *pst);//增加成功返回ture,失败返回false.
void SeqListInit(SeqList *pst); //初始化循序表
bool IsFull(SeqList *pst);//判断循序表是否已满
bool IsEmpty(SeqList *pst);//判断循序表是否为空
void SeqListShow(SeqList *pst);
void SeqListPushBack(SeqList *pst,ElemType x); //后插
void SeqListPushFront(SeqList *pst, ElemType x); //前插
void SeqListInsertByPos(SeqList *pst,int pos,ElemType x); //按位置插入元素
void SeqListInsertByVal(SeqList *pst, ElemType x);//按值插入元素
void SeqListDeleteByPos(SeqList *pst, int pos);//按位置删除元素
void SeqListDeleteByVal(SeqList *pst, ElemType key);//按值删除元素
void SeqListRemoveAll(SeqList *pst, ElemType key);
void SeqListSort(SeqList *pst);//排序
int SeqListFind(SeqList *pst,ElemType key);//按值查找
void SeqListReverse(SeqList *pst);//顺序表逆置
void SeqListPopBack(SeqList *pst);//尾部删除
void SeqListPopFront(SeqList *pst);//头部删除
size_t SeqListLength(SeqList *pst);//计算顺序表长度
size_t SeqListCapacity(SeqList *pst);//顺序表容量
void SeqListClear(SeqList *pst);//清除
void SeqListDestroy(SeqList *pst);//摧毁
函数接口实现
初始化顺序表:
void SeqListInit(SeqList *pst)
{
//malloc进行动态内存开辟
pst->base = (ElemType*)malloc(sizeof(ElemType)*SEQLIST_DEFAULT_SIZE);
assert(pst->base != NULL);//断言内存是否申请成功
memset(pst->base,0,sizeof(ElemType)*SEQLIST_DEFAULT_SIZE);//用menset()进行内存设置,将base设置为0;
pst->capacity = SEQLIST_DEFAULT_SIZE;
pst->size = 0;
}
判断顺序表是否已满:
bool IsFull(SeqList *pst)
{return pst->size >= pst->capacity;}
判断顺序表是否为空:
bool IsEmpty(SeqList *pst)
{return pst->size == 0;}
顺序表扩容:
static bool _Inc(SeqList *pst)
{
ElemType *new_base = (ElemType*)realloc(pst->base,sizeof(ElemType)*pst->capacity*2);//扩容两倍
if (new_base == NULL)
return false;
pst->base = new_base;
pst->capacity *= 2;
return true;
}
插入数据(后插):
void SeqListPushBack(SeqList *pst, ElemType x)
{
assert(pst->base != NULL);
//空间满了并且扩容不成功
if (IsFull(pst)&&!_Inc(pst))//短路求值
{
printf("顺序表空间已满,不能插入数据%d\n",x);
return;
}
pst->base[pst->size++] = x;
}
插入数据(头部插入):
void SeqListPushFront(SeqList *pst, ElemType x)
{
assert(pst!=NULL);
if (IsFull(pst) && !_Inc(pst))
{
printf("顺序表空间已满,不能插入数据%d\n", x);
return;
}
for (size_t pos = pst->size; pos > 0;pos--)
{
pst->base[pos] = pst->base[pos - 1];
}
pst->base[0] = x;
pst->size++;
}
显示顺序表:
void SeqListShow(SeqList *pst)
{
assert(pst!=NULL);
for (size_t i = 0; i < pst->size; i++)
{
printf("%d ",pst->base[i]);
}
printf("\n");
}
顺序表的销毁:
assert(pst!=NULL);
if (pst->base)//如果Pst所指向的base不为空,则进行空间的释放;
free(pst->base);
pst->base = NULL;
pst->capacity = pst->size = 0;
顺序表尾部删除:
void SeqListPopBack(SeqList *pst)
{
assert(pst!=NULL);
if (IsEmpty(pst))
{
printf("顺序表已空,不能尾部删除\n");
return;
}
pst->size--;
}
顺序表头部删除:
void SeqListPopFront(SeqList *pst)
{
assert(pst != NULL);
if (IsEmpty(pst))
{
printf("顺序表已空,不能头部删除\n");
return;
}
for (int i = 0; i<pst->size; i++)
pst->base[i] = pst->base[i + 1];
pst->size--;
}
顺序表长度:
size_t SeqListLength(SeqList *pst)
{
assert(pst!=NULL);
return pst->size;
}
顺序表容量:
size_t SeqListCapacity(SeqList *pst)
{
assert(pst != NULL);
return pst->capacity;
}
清空顺序表
void SeqListClear(SeqList *pst)
{
assert(pst != NULL);
pst->size=0;
}
按位置插入:
void SeqListInsertByPos(SeqList *pst, ElemType pos, ElemType x)
{
assert(pst != NULL);
if (IsFull(pst) && !_Inc(pst))
{
printf("顺序表空间已满,不能插入数据%d\n", x);
return;
}
if (pos<0 || pos>pst->size)
{
printf("要插入数据的位置非法,%d不能插入\n", x);
return;
}
for (int i = pst->size; i > pos;i--)
pst->base[i] = pst->base[i - 1];
pst->base[pos] = x;
pst->size++;
}
按值插入:
void SeqListInsertByVal(SeqList *pst, ElemType x)
{
//从后往前比较
assert(pst != NULL);
if (IsFull(pst) && !_Inc(pst))
{
printf("顺序表空间已满,不能插入数据%d\n", x);
return;
}
int end = pst->size;
while (end>0 && x<pst->base[end-1])
{
pst->base[end] = pst->base[end - 1];
end--;
}
pst->base[end] = x;
pst->size++;
}
顺序表排序:
void SeqListSort(SeqList *pst)
{
assert(pst!=NULL);
if (pst->size <= 1)
return;
for (int i = 0; i < pst->size-1;i++)
{
for (int j = 0; j < pst->size - i - 1;j++)
if (pst->base[j]>pst->base[j+1])
{
ElemType tmp = pst->base[j];
pst->base[j] = pst->base[j + 1];
pst->base[j + 1]=tmp;
}
}
}
按位置删除数据:
void SeqListDeleteByPos(SeqList *pst, int pos)
{
assert(pst!=NULL);
if (IsEmpty(pst))
{
printf("顺序表已空,不能按位置删除元素.\n");
return;
}
if (pos<0 || pos>=pst->size)
{
printf("要删除数据的位置非法,不能按位置删除.\n");
return;
}
for (int i = pos; i < pst->size; i++)
pst->base[i] = pst->base[i + 1];
pst->size--;
}
数据查找:
int SeqListFind(SeqList *pst, ElemType key)
{
assert(pst!=NULL);
for (int i = 0; i < pst->size;i++)
{
if (key==pst->base[i])
return i;
}
return -1;
}
按值删除:
void SeqListDeleteByVal(SeqList *pst, ElemType key)
{
assert(pst != NULL);
if (IsEmpty(pst))
{
printf("顺序表已空,不能按值删除元素.\n");
return;
}
int pos = SeqListFind(pst,key);
if (pos == -1)
{
printf("要删除的数据不存在,不能删除.\n");
return;
}
SeqListDeleteByPos(pst,pos);
}
顺序表逆置:
void SeqListReverse(SeqList *pst)
{
assert(pst!=NULL);
if (pst->size < 2)
return;
int left = 0;
int right = pst->size - 1;
while (left<right)
{
Swap(&pst->base[left],&pst->base[right]);
left++;
right--;
}
}