C语言线性表
/*
线性表一般需要包含以下功能:
● 初始化线性表:将一个线性表进行初始化,得到一个全新的线性表。
● 获取指定位置上的元素:直接获取线性表指定位置i上的元素。
● 获取元素的位置:获取某个元素在线性表上的位置i。
● 插入元素:在指定位置i上插入一个元素。
● 删除元素:删除指定位置i上的一个元素。
● 获取长度:返回线性表的长度。
*/
/* 顺序表 */
#include <stdio.h>
#include <stdlib.h>
typedef int E;
typedef struct List List;
struct List
{
E *array; // 实现顺序表的底层数组 指向顺序表的底层数组
E capacity; // 表示底层数组的容量
E size; // 表中的元素数量
};
typedef struct List *ArrayList; // 因为是数组实现,所以就叫ArrayList,这里直接将List的指针起别名
_Bool initList(ArrayList list)
{
list->array = malloc(sizeof(E) * 10); // 使用malloc函数申请10个int大小的内存空间,作为底层数组使用
if (list->array == NULL)
return 0; // 需要判断如果申请的结果为NULL的话,表示内存空间申请失败
list->capacity = 10; // 直接把数组的容量设置为10即可
list->size = 0; // 元素数量默认为0
return 1; // 正常情况下返回true也就是1
}
/*
但是我们发现一个问题,这样的话我们的顺序表长度不就是固定为10的了吗?
而前面我们线性表要求的是长度是动态增长的,那么这个时候怎么办呢?
我们可以直接使用一个指针来指向底层数组的内存区域,
当装不下的时候,我们可以创建一个新的更大的内存空间来存放数据,
这样就可以实现扩容了,所以我们来修改一下:
*/
// 这样,一个比较简单的顺序表就定义好,我们可以通过initList函数对其进行初始化:
// 接着我们来编写一下插入和删除操作
_Bool insertList(ArrayList list, E element, E index)
{
// 转换成位序,也就是[1, size + 1]这个闭区间,所以我们在一开始的时候进行判断
if (index < 1 || index > list->size + 1)
{
return 0; // 如果在非法位置插入,返回0表示插入操作执行失败
}
// list就是待操作的表,element就是需要插入的元素,
// index就是插入的位置(注意顺序表的index是按位序计算的,从1开始,一般都是第index个元素)
/*
不过我们还是没有考虑到一个情况,那么就是如果我们的表已经装满了,
也就是说size已经达到申请的内存空间最大的大小了,那么此时我们就需要考虑进行扩容了,否则就没办法插入新的元素了:
*/
if (list->size >= list->capacity)
{
E newCapacity = list->capacity + (list->capacity >> 1); // 如果size已经到达最大的容量了,肯定是插不进了,那么此时就需要扩容了
E *newArray = realloc(list->array, sizeof(E) * newCapacity); // 我们先计算一下新的容量大小,这里我取1.5倍原长度,当然你们也可以想扩多少扩多少
// 这里我们使用新的函数realloc重新申请更大的内存空间
if (newArray == NULL)
return 0; // 如果申请失败,那么就确实没办法插入了,只能返回0表示插入失败了
list->array = newArray;
list->capacity = newCapacity;
}
for (int i = list->size; i > index - 1; i--)
{
list->array[i] = list->array[i - 1]; ////先使用for循环将待插入位置后续的元素全部丢到后一位
}
list->array[index - 1] = element; // 挪完之后,位置就腾出来了,直接设定即可
list->size++; // 插入之后相当于多了一个元素,记得size + 1
return 1; // 正常情况return 1
}
void printList(ArrayList list)
{
for (E i = 0; i < list->size; i++)
{
printf("%d ", list->array[i]);
}
printf("\n");
}
_Bool deleteList(ArrayList list, E index)
{
// list就是待操作的表,index是要删除的元素位序
if (index < 1 || index > list->size)
return 0;
for (int i = index - 1; i < list->size; i++)
{
list->array[i] = list->array[i + 1];
}
list->size--;
return 1; // 正常情况返回1
}
E sizeList(ArrayList list)
{
return list->size;
}
E getList(ArrayList list, E index)
{
if (index < 1 || index > list->size)
return NULL; // 如果超出范围返回NULL
return list->array[index - 1];
}
E findList(ArrayList list, E element)
{
for (E i = 0; i < list->size; ++i)
{
if (list->array[i] == element)
return i + 1;
}
return -1;
}
E main(void)
{
List list; // 创建新的结构体变量
if (initList(&list)) // 对其进行初始化,如果失败就直接结束
{
for (E i = 1; i <= 30; ++i)
insertList(&list, i, i);
printList(&list);
printf("\n");
printf("%d\n", getList(&list, 23));
}
else
{
printf("顺序表初始化失败,无法启动程序!");
}
}