线性表——顺序表(c语言)

概念篇

下图展现了顺序表的概念以及分类

在这里插入图片描述

代码篇

1. 顺序表的定义

用结构体把一些属性封装起来表示顺序表
typedef struct sqlist
{
	int*elements;
	/*指向整数的指针,用于存储顺序表中的元素,指向动态分配的整形数组。*/
	size_t size;
	//顺序表中当前存储的元素数量
	size_t capacity;
	//顺序表当前能够存储的最大元素数量
}sqlist;
int*elements指向动态分配的整形数组,需要用malloc函数分配空间,可以用realloc函数扩容,如果已知数组大小可以替换成int elements[n],n表示数组长度。

2. 顺序表的初始化

void sqlist_init(sqlist*list,int capacity)
{
    list->elements=(int*)malloc(sizeof(int)*capacity);
    //给动态数组分配空间
    list->size=0;
    //数量初始化为0
    list->capacity=capacity;
    //容量初始化为函数传入进来的capacity值
}

3.顺序表的摧毁

顺序表的摧毁也就是释放顺序表所占有的内存空间。主要分为下几步:
a.释放数据元素所占用的内存。
b将指针置为NULL。
c重置顺序表的其他属性(容量,长度等)。(可要可不要)
void sqlist_destory(sqlist*list)
{
    if(list->elements)
    {
        free(list->elements);
        //释放malloc申请数据元素所用的内存空间
        list->elements=NULL;
        //确保在后续的程序执行中,不会错误地访问这块已被释放的内存
    }
}

4. 顺序表的元素数量

直接返回了顺序表结构体指针list所指向的对象的size成员。
size_t sqlist_size(sqlist*list)
{
	return list->size;
}

5. 顺序表的数据插入

1.插入的索引位置是否合法,不合法打印非法索引。
2.顺序表是否已经满了,如果满了,则扩容。
3.顺序表没有满,先将从要插入位置开始到顺序表末尾的所有元素向后移动一位,再插入新元素。
4.更新数据表大小。
void sqlist_insert(sqlist*list,int index,int element)
{
   if(index<0||index>list->size)
   {
   		printf("invalid index\n");
   		return;
   }
   //如果要插入的位置<0或大于顺序表中的元素个数,则打印非法索引,并返回。
   if(list->size==list->capacity)
   {
     	//如果顺序表的元素个数等于顺序表的容量,代表顺序表满了,需要扩容。
     	int*newelements=(int*)realloc(list->elements,sizeof(int)*list->capacity*2);
     	//尝试将elements的存储空间扩大到原来的两倍。 
   		if(newelements==NULL)
   		//如果内存为空,则扩容失败,返回。
       	{
           printf("failed to allocate\n");
           return;
       	}
       	list->elements=newelements;
       	list->capacity*=2;
       	//否则成功, 更新elements指针指向新的内存区域。
  	}
   	for(int i=list->size;i>index;i--)
       list->elements[i]=list->elements[i-1];
   	list->elements[index]=element;
   	//将从index位置开始到顺序表末尾的所有元素向后移动一位,为新元素腾出空间。
   	list->size++;
   	//插入后元素个数加一
}

6. 顺序表的元素查找

for循环遍历所有元素,满足条件则返回该元素,否则返回-1.
int sqlist_find(sqlist*list,int element)
{
   for(int i=0;i<list->size;i++)
   {
       if(list->elements[i]==element)
           return i;
   }
   return -1;
}

7. 顺序表的元素删除

数据删除跟数据插入有异曲同工之妙,删除是将该位置之后的所有元素向前移动一位
void sqlist_delete(sqlist*list,int index)
{
   if(index<0||index>=list->size)
   {
       printf("invalid index\n");
       return;
   }
   for(int i=index;i<list->size;i++)
       list->elements[i]=list->elements[i+1];
   list->size--;
}

8. 顺序表的元素修改

直接通过索引来访问数组进行元素修改。
void sqlist_alter(sqlist*list,int index,int element)
{
   if(index<0||index>=list->size)
   {
       printf("invalid index\n");
       return;
   }
   list->elements[index]=element;
}

9.顺序表索引对应的元素

通过索引直接访问数组,返回对应元素
int sqlist_index(sqlist*list,int index)
{
	if(index<0||index>=list->size)
    {
        printf("invalid index\n");
        return -1;
    }
    return list->elements[index];

}

10.完整代码

#include<stdio.h>
typedef struct sqlist
{
	int*elements;
	/*指向整数的指针,用于存储顺序表中的元素,指向动态分配的整形数组。*/
	int size;
	//顺序表中当前存储的元素数量
	int capacity;
	//顺序表当前能够存储的最大元素数量
}sqlist;
void sqlist_init(sqlist*list,int capacity)
{
    list->elements=(int*)malloc(sizeof(int)*capacity);
    //给动态数组分配空间
    list->size=0;
    //数量初始化为0
    list->capacity=capacity;
    //容量初始化为函数传入进来的capacity值
}
void sqlist_destory(sqlist*list)
{
    if(list->elements)
    {
        free(list->elements);
        //释放malloc申请数据元素所用的内存空间
        list->elements=NULL;
        //确保在后续的程序执行中,不会错误地访问这块已被释放的内存
    }
}
size_t sqlist_size(sqlist*list)
{
	return list->size;
}
void sqlist_insert(sqlist*list,int index,int element)
{
   if(index<0||index>list->size)
   {
   		printf("invalid index\n");
   		return;
   }
   //如果要插入的位置<0或大于顺序表中的元素个数,则打印非法索引,并返回。
   if(list->size==list->capacity)
   {
     	//如果顺序表的元素个数等于顺序表的容量,代表顺序表满了,需要扩容。
     	int*newelements=(int*)realloc(list->elements,sizeof(int)*list->capacity*2);
     	//尝试将elements的存储空间扩大到原来的两倍。 
   		if(newelements==NULL)
   		//如果内存为空,则扩容失败,返回。
       	{
           printf("failed to allocate\n");
           return;
       	}
       	list->elements=newelements;
       	list->capacity*=2;
       	//否则成功,更新elements指针指向新的内存区域。
  	}
   	for(int i=list->size;i>index;i--)
       list->elements[i]=list->elements[i-1];
   	list->elements[index]=element;
   	//需要插入的位置i后面的所有元素后移,再第i个位置插入元素。
   	list->size++;
   	//插入后元素个数加一
}
int sqlist_find(sqlist*list,int element)
{
   for(int i=0;i<list->size;i++)
   {
       if(list->elements[i]==element)
           return i;
   }
   return -1;
}
void sqlist_delete(sqlist*list,int index)
{
   if(index<0||index>=list->size)
   {
       printf("invalid index\n");
       return;
   }
   for(int i=index;i<list->size;i++)
       list->elements[i]=list->elements[i+1];
   list->size--;
}
void sqlist_alter(sqlist*list,int index,int element)
{
   if(index<0||index>=list->size)
   {
       printf("invalid index\n");
       return;
   }
   list->elements[index]=element;
}
int sqlist_index(sqlist*list,int index)
{
	if(index<0||index>=list->size)
    {
        printf("invalid index\n");
        return -1;
    }
    return list->elements[index];
}
int main()
{
    sqlist list;
    sqlist_init(&list,1);
    for(int i=0;i<10;i++)
        sqlist_insert(&list,i,i*10);
    //for循环插入分别0、10、20、30、40、50、60
    //70 80 90
    printf("size=%d\n",sqlist_size(&list));
    //size=10
    printf("%d\n",sqlist_find(&list,5));
    //没有值为5的元素,所以打印-1
    printf("%d\n",sqlist_find(&list,10));
    //值为10的下标为1,打印1。
    sqlist_alter(&list,3,60);
    //修改下标为3的值30为60
    for(int i=0;i<sqlist_size(&list);i++)
    	printf("%d %d\n",i,sqlist_index(&list,i));
    //调用函数打印每个值以及下标。
    sqlist_destory(&list);
    //不再访问线性表时销毁。
	return 0;
}
综上所述应该打印的结果与下图相一致

效果图

在这里插入图片描述
希望能给学习顺序表的同学带来一些启发,如果有路过的大佬提供宝贵的建议,那就最好了,非常感激!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值