一、什么是动态顺序表
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上 完成数据的增删查改。使用动态开辟的数组存储。
(
按需申请
)
二、动态顺序表结构定义
#define INIT_SIZE 5 //第一次分配的大小
typedef int list_type; //重定义int数据类型,可以适应各种扩展
//顺序表类型定义
typedef struct
{
list_type *a; //指向顺序表首地址
int count; //记录实际的元素个数
int size; //总的大小
}st_list;
三、动态顺序表常用操作函数
1、顺序表接口函数申明,顺序列表初始化函数
void list_int(list *plist)
{
assert( plist != NULL);
plist->a = NULL;
plist->size = 0;
plist->count = 0;
}
2、顺序列表尾增函数,在顺序表尾部添加一个数
需要检查空间是否足够,不够需要增,先创建一个函数实现空间的赋予
static int list_getspace(list *plist){
int size;
list_type *ptmp = NULL;
assert(plist != NULL);
//先看plist是否存在,不存在就要创建,存在再增加
if (plist->count == plist->size) //1、第一次。2、满了
{
ptmp = plist->a;
size = plist->size > 0? 2*LIST_SIZE : LIST_SIZE;
size += plist->size;
//realloc函数:如果ptmp=NULL会调用malloc去申请内存,否则扩展
ptmp = realloc(ptmp,size* sizeof(list_type));
if (ptmp == NULL)
{
return -1;
}
plist->a = ptmp;
plist->size = size;
}
return 0;
}
以上函数在添加时是需要调用的,创建尾增
int list_add_tail(list *plist,list_type x)
{
//断言
assert(plist != NULL);
int ret;
//第一次或者满了,需要分配内存
ret = list_getspace(plist);
if ( 0 == ret ){
plist->a[plist->count] = x;
plist->count++;
}
return ret;
}
3、总览函数,可以输出所有顺序表的数据
void list_show(list *plist)
{
int i;
//断言
assert( NULL != plist);
//循环遍历
for (i = 0; i < plist->count; i++)
{
printf("%d ",plist->a[i]);
}
printf("\n----------------------------\n");
}
4、实现尾部删除;
尾部删除,直接将最后一个覆盖,实现尾部数据的删除
void list_del_tail(list *plist)
{
//断言
assert(plist != NULL);
//直接覆盖最后一个
if (plist->count > 0)
{
plist->count--;
}
}
5、销毁顺序表
直接释放指针,将所有数据置空
void list_destroy(list *plist)
{
//断言
assert(plist != NULL);
//指针释放
free(plist->a);
plist->a = NULL;
plist->count = 0;
plist->size = 0;
}
6、顺序表头部增加
循环将数据往后移动一位,空出头部,往头部赋值
int list_add_head(list *plist,list_type x)
{
int ret,i;
//断言
assert(plist != NULL);
//调用函数申请空间
ret = list_getspace(plist);
if (0 == ret)
{
//利用循环实现数据后移
for (i = plist->count-1; i >= 0; i--) {
plist->a[i+1] = plist->a[i];
}
//给首位赋值
plist->a[0] = x;
plist->count++;
}
return ret;
}
7、顺序表指定位置添加
传入一个数,确定指定位置,利用for循环遍历,以输入点为循环条件,从后往前至指定位置赋值
int list_insert(list *plist,int pos,list_type x)
{
//断言
assert(plist != NULL);
assert((pos >= 0) && (pos <= plist->count));
int ret,i;
//申请空间
ret = list_getspace(plist);
if (0 == ret)
{
//for循环遍历,从后往前遍历,截至在指定位置
for (i = plist->count-1; i >= pos; i--)
{
plist->a[i+1] = plist->a[i];
}
//指定位置赋值
plist->a[pos] = x;
plist->count++;
}
return ret;
}
8、顺序表指定位置删除某个数据‘
利用循环遍历,从pos下一个元素开始向前移动一位,跳出循环后将实际元素个数减一,实现删减
void list_delete(list *plist,int pos)
{
int i;
//断言
assert(plist != NULL);
assert((pos >= 0) && (pos < plist->count));
//把从pos下一个元素开始向前移动一位
for (i = pos; i < plist->count-1; i++) {
plist->a[i] = plist->a[i+1];
}
plist->count--;
}