顺序表的相关操作 头插,尾插,头删,尾删,任意位置插入删除
顺序表的定义
定义一个结构体来存储顺序表,结构体三个元素:数组指针data,有效元素个数size,和数组当前的容量capacity。
此处应该注意为了提高代码的适用性,我们将数组的数据类型用typedef起了个别名,slDatatype,方便后期操作其他数据类型时使用。
初始化顺序表
将顺序表初始化,即该顺序表已存在,但是内容为空
检查容量及扩容
由于该顺序表需要动态开辟空间来存储,所以在插入操作时就需要检查空间大小是否满足插入数据的需求,无论在那个位置插入元素,都需要进行检查。
尾插尾删操作
尾插:首先判断该顺序表是否合法,然后检查容量及扩容,在该数组的最后一个有效位置之后放入需要插入的数据,然后将size++,即将插入的数据存入顺序表的有效位中。
尾删:判断顺序表合法,然后直接将size- -,即最后一位不是顺序表的有效数据。此处为假删除,该位置的数据其实并未删除,只是切断了其与顺序表的联系,无法再使用。
头插头删操作
头插和头删比较尾插尾删相对复杂,因为都涉及了元素的移动。
头插:判断合法,检查容量,再将该顺序表所有元素按照从后向前的顺序,分别向后移动一位,然后在首位插入指定元素。
头删:结合头插和尾删操作,按照从前向后的顺序将元素分别向前移动一位即可。
任意位置的插入,删除
类比头插头删,尾插尾删操作,只需要在再入需要操作的位置pos即可实现,该功能实现后也可进一步优化头删头插尾删尾插操作,只要想pos分别置为0和size即可。
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef int slDatatype;//顺序表内的数据类型(便于维护)
//动态顺序表
typedef struct seqList
{
slDatatype *data; //数组指针
int size; //有效元素个数
int capacity; //数组内存空间
} seqList;
//初始化顺序表
void Init(seqList* sl)//形参为结构体指针
{
sl->data = NULL;
sl->size = 0;
sl->capacity = 0;
}
//检查容量及扩容
void Checkcapacity(seqList*sl)
{
if (sl->size == sl->capacity)
{
//开辟新空间
int newCapacity = sl->capacity == 0 ? 1 : 2 * sizeof(sl->capacity);
slDatatype * tmp = (slDatatype*)malloc(newCapacity*sizeof(slDatatype));
//拷贝数据
memcpy(tmp, sl->data, sizeof(slDatatype)*sl->size);
//释放原有空间
free(sl->data);
sl->data = tmp;
//若使用realloc动态开辟空间————可替换35-42行
//sl->data = (seqList*)ralloc(sl->data, newCapacity * sizeof(slDatatype));
//更新容量
sl->capacity = newCapacity;
}
}
//打印顺序表
void Listprint(seqList*sl)
{
if (sl == NULL)
return;
for (int i = 0; i < sl->size; i++)
{
printf("%d ", sl->data[i]);
}
printf("\n");
}
//尾插
void Pushback(seqList* sl,slDatatype val)
{
if (sl == NULL)
return;
Checkcapacity(sl);
sl->data[sl->size] = val;
sl->size++;
}
//尾删
void Popback(seqList* sl)
{
if (sl == NULL||sl->size==0)
return;
if (sl->size > 0)
sl->size--;
}
//头插
void Pushfront(seqList*sl,slDatatype val)
{
if (sl == NULL)
return;
//检查容量
Checkcapacity(sl);
//移动元素--从后向前
int end = sl->size;
while (end > 0)
{
sl->data[end] = sl->data[end - 1];
--end;
}
//插入元素
sl->data[0] = val;
sl->size++;
}
//头删
void Popfront(seqList* sl)
{
if (sl == NULL||sl->size==0)
return;
//从前向后移动元素
for (int i = 0; i < sl->size; i++)
{
sl->data[i] = sl->data[i + 1];
}
//更新size
sl->size--;
}
//任意位置插入元素
void Insert(seqList*sl, int pos, slDatatype val)
{
if (sl == NULL)
return;
Checkcapacity(sl);
if (pos >= 0 && pos <= sl->size)
{
//移动数据
int end = sl->size;
while (end > pos)
{
sl->data[end] = sl->data[end - 1];
end--;
}
//插入数据
sl->data[pos] = val;
sl->size++;
}
}
//删除任意位置数据
void Erase(seqList*sl, int pos)
{
if (sl == NULL || sl->size == 0)
return;
if (pos >= 0 && pos < sl->size)
{
while (pos<sl->size)
{
sl->data[pos] = sl->data[pos+1];
pos++;
}
sl->size--;
}
}
//测试模块---该部分功能根据用户需要自定义
void test()
{
seqList sl;
Init(&sl);
Pushback(&sl, 1);
Pushback(&sl, 2);
Pushback(&sl, 3);
Pushback(&sl, 4);
Erase(&sl, 1);
Listprint(&sl);
}
//销毁顺序表
void Destroy(seqList* sl)
{
if (sl != NULL && sl->data != NULL)
{
free(sl->data);
sl->data = NULL;
}
}
int main()
{
test();
return 0;
}