线性表

线性表类型定义:

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

所有参数传递都有技巧,如果只需要读取数据,并不需要改变本身数据,直接传参即可,若要改变指向或者改变数据,传递时需要取地址&

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魔幻音

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值