顺序表的实现
1.概念
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组
上完成数据的增删查改。
2.顺序表定义
typedef int seqDataType;
//顺序表定义
typedef struct seqList
{
seqDataType* data;//存放元素的数组
int capacity;//容量
int size;//元素个数
}seqList;
3.接口的实现
//函数声明
void seqListInit(seqList* sl,int capacity); //顺序表初始化
void checkCapacity(seqList* sl);//如果顺序表满了,进行增容
void printfSeqList(seqList* sl);//打印顺序表
void seqListPushBack(seqList* sl, seqDataType val);//尾插一个数据
void seqListPopBack(seqList* sl);//尾删一个数据
void seqListPushFront(seqList* sl, seqDataType val);//头插一个数据
void seqListPopFront(seqList* sl);//头删一个数据
seqDataType seqListFind(seqList* sl, seqDataType val);//顺序表查找
void seqListInsert(seqList* sl, int pos, seqDataType val);// 顺序表在pos位置插入数据
void seqListErase(seqList* sl, int pos);// 顺序表删除pos位置的值
void seqListDestory(seqList* sl);// 顺序表销毁
顺序表初始化
- 顺序表的容量初始化为0。
- 顺序表的元素个数初始化为0。
- 存放元素的数组初始化为NULL。
void seqListInit(seqList* sl,int capacity)
{
sl->capacity = capacity;
sl->size = 0;
sl->data = NULL;
}
顺序表的扩容
- 判断顺序表已经有的元素个数和容量是否相等,如果相等,就需要扩容。
- 设置新的容量。
- 开辟一块儿更大的空间。
- 将原来空间内的数据拷贝到新申请的空间。
- 释放原来的空间。
- 将顺序表中的data指针指向新申请的空间。
- 将容量更新为新扩容后的容量
void checkCapacity(seqList* sl)
{
if(sl->size == sl->capacity)
{
int newCapacity = sl->capacity == 0 ? 1 : s * sl->capacity;
seqList* tmp = (seqList*) malloc (sizeof(seqList) * newcapacity);
memcpy(tmp, data, sizeof(seqList) * sl->capacity);
free(sl->data);
sl->data = tmp;
//上面四行可以替换成
sl->data = (seqList*) realloc (sl->data, sizeof(seqList) * newCapacity);
sl->capacity = newCapacity;
}
}
尾插操作
- 判断容量是否够用,不够则进行扩容。
- 在下标为size的位置插入新的数据。
- size++。
void seqListPushBack(seqList* sl, seqDataType val)
{
checkCapacity(sl);
sl->data[sl->size] = val;
sl->size++;
}
尾删操作
1.检查当前顺序表是否有数据。
2.顺序表的删除并不是将数据彻底删除,而是对size进行修改,让被删除的数据无法被访问到。
3. size–。
void seqListPopBack(seqList* sl)
{
if(sl->size > 0)
{
sl->size--;
}
}
头插操作
- 检查容量是否够用,不够则进行扩容。
- 从最后一个元素开始,依次向后移动一个位置。
- 第一个元素的位置插入新的数据。
- size++。
void seqListPushFront(seqList* sl, seqDataType val)
{
checkCapacity(sl);
for (int i = sl->size; i > 0; i--)
{
sl->data[i] = sl->data[i-1];
}
sl->data[0] = val;
sl->size ++;
}
头删操作
- 检查当前顺序表是否有数据。
- 要删除第一个数据,从第二个数据开始,依次向前移动一个位置。
- 这样操作可以覆盖掉第一个数据,达到删除的目的。
- size–。
void seqListPopFront(seqList* sl)
{
if(sl->size > 0)
{
for (int i = 0; i<sl->size - 1; i++)
{
sl->data[i] = sl->data[i+1];
}
sl->size--;
}
}
在pos位置插入数据
- 检查pos位置是否越界,pos的合法范围:[ 0 , size ]。
- 检查容量
- 从最后一个元素开始向后移动一个位置,到pos位置停止。
- pos的位置插入新的数据。
- size++。
void seqListInsert(seqList* sl, int pos, seqDataType val)
{
if(pos >= 0 && pos <= sl->size)
{
checkCapacity(sl);
for (int i = sl->size; i<pos; i--)
{
sl->data[i] = sl->data[i-1];
}
sl->data[pos] = val;
sl->size++;
}
}
在pos位置删除数据
- 检查pos位置是否越界,pos的合法范围:[ 0 , size ]。
- 从pos位置的下一个位置开始依次向前移动一个位置,覆盖掉pos位置的数据,达到删除的效果。
- size–。
void seqListErase(seqList* sl, int pos)
{
if(pos >= 0 && pos <= sl->size)
{
for (int i = pos; i < sl->size-1; i++)
{
sl->data[i] = sl->data[i + 1];
}
sl->size--;
}
}
顺序表查找
seqDataType seqListFind(seqList* sl, seqDataType val)
{
for (int i = 0; i < sl->size; i++)
{
if (val == sl->data[i])
{
return i;
}
}
return -1;
}
销毁顺序表
- 释放malloc申请的空间。
- 存放数据的指针置为NULL。
- 顺序表的容量和数据的个数置为0。
void seqListDestory(seqList* sl)
{
free(sl->data);
sl->data = NULL;
sl->size = sl->capacity = 0;
}