线性表类型定义:
typedef struct LINEAR
{
USER_TYPE *data;
int capacity;
int count;
EQU_FUN equals;
}LINEAR;
USER_TYPE为想要使用线性表时所要存储的数据类型。
该结构体说明线性表是由一个表头指向一个数组来存储,管理数据。
capacity表示线性表所能储存的数据量,count表示已经存储进去的数据量;
equals表示用于比较的函数,初始的比较函数用的是切片比较:
static boolean defaultEquals(USER_TYPE one, USER_TYPE other) {
u8 *p = (u8 *) &one;
u8 *q = (u8 *) &other;
int size = sizeof(USER_TYPE);
int i;
for (i = 0; i < size; i++) {
if (*p != *q) {
return FALSE;
}
p++;
q++;
}
return TRUE;
}
即将数据按unsigned char切分,用遍历对比。
定义好类型之后,开始初始化线性表:
boolean initLinear(LINEAR **head, const int capacity) {
if (NULL == head || *head != NULL || capacity <= 0) {
return FALSE;
}
*head = (LINEAR *) calloc(sizeof(LINEAR), 1);
(*head)->data = (USER_TYPE *) calloc(sizeof(USER_TYPE), capacity);
(*head)->capacity = capacity;
(*head)->count = 0;
(*head)->equals = defaultEquals;
return TRUE;
}
要定义一个线性表,首先需要一个表头,因为要改变表头的指向,所以应该&表头,额外还需要申请空间数量,
首先用calloc申请一个空间给表头,线性表的data实例也需要由calloc申请capacity个大小为sizeof(数据类型)的空间。
因为申请的线性表头和data实例都由calloc申请,
所以在运行完程序后需要free,即destoryLinear:
void destoryLinear(LINEAR **head) {
if(NULL == head || NULL == *head) {
return ;
}
free((*head)->data);
free(*head);
*head = NULL;
}
初始化和释放做完之后,就该输入数据了
即追加/插入数据:
通过思考过程,追加(新增)数据就等于在线性表末尾插入数据,所以先实现插入数据的函数。
在线性表插入数据:
手工过程是从末尾开始,一直遍历到想要插入的位置之后,将数据后移一位,
(注意下标和count,因为下标从0开始,最后一个元素的下标应该是count-1)
for (i = head->count - 1; i >= index; i--) {
head->data[i + 1] = head->data[i];
}
在数据后移完成之后,当前index就是新数据想要插入的地方,再进行赋值,数据数加一即可
head->data[index] = data;
head->count++;
这个过程下来,我们进行插入操作所需要的参数有:表头,插入的位置,想插入的数据
那么声明:
boolean insertElementAt(LINEAR *head, int index, USER_TYPE data);
表头的指向不用更改,所以head类型为LINEAR*
追加数据就是插入的位置为最后一位进行插入数据,即:
boolean appendElement(LINEAR *head, USER_TYPE data) {
return insertElementAt(head, head->count, data);
}
最后一位就是index = count
删除数据:
在线性表中删除数据,就是从想要删除的位置开始,用下一位的数据覆盖当前数据,所以只需要表头和要删除的下标即可:
boolean removeElementAt(LINEAR *head, int index) {
int i;
if (NULL == head || index < 0 || isLinearEmpty(head) || index >= head->count) {
return FALSE;
}
for (i = index; i < head->count - 1; i++) {
head->data[i] = head->data[i + 1];
}
--head->count;
return TRUE;
}
删除结束后,将数据数减一
改数据:
直接将要该数据的位置重新赋值即可:
boolean setElementAt(const LINEAR *head, const int index, USER_TYPE data) {
if (NULL == head || index < 0 || index >= head->count) {
return FALSE;
}
head->data[index] = data;
return TRUE;
}
注:
每个函数运行时都需要考虑能否正常运行,例如:
①任何操作:1.要考虑表头是否为NULL,若为NULL则无法初始化 2.所给的数据是否合理,capacity不能小于等于0,count不能小于0
②新增,删除操作:要考虑想要新增的位置是否合理,index不能大于count
所有参数传递都有技巧,如果只需要读取数据,并不需要改变本身数据,直接传参即可,若要改变指向或者改变数据,传递时需要取地址&