关于数据结构链表问题(C语言实现)—— 线性表顺序存储设计与实现

这是我的第一篇博客(内容为废话)

现在马上面临毕业的我,发现整理总结问题真的非常重要,刚刚开始学习数据结构,并且非科班出身的我,感觉得到压力非常大,所以开始学习完后在这进行回忆,复习学习。在这里要感谢传智播客的讲师传智扫地僧的课程。刚开始,肯定会有很多不好的地方,慢慢改变积少成多。特别喜欢一句话叫,十年饮冰,难凉热血。

什么是线性表?

首先说一说我理解的线性表,顾名思义,线性表就是用线串起来的表格呗,其实差不多一个意思,线性表就是零个或多个数据元素的有限序列,首先它是一个序列,也就是说,元素之间是有顺序的,必须是一个连着一个,不可能是一个连着好几个,其次他应该是有限个数的。其实计算机处理中所有的都是有限个数的,我们所说的无限的只存在与数学中。

数据结构之线性表顺序存储

线性表的顺序存储结构,指的就是用一段地址连续的存储单元依次储存线性表的数据元素。

废话不多说,直接上代码吧:

#ifndef  __MY_SEQLIST_H__ 
#define __MY_SEQLIST_H__

typedef void SeqList;
typedef void SeqListNode;

SeqList* SeqList_Create(int capacity);

void SeqList_Destroy(SeqList* list);

void SeqList_Clear(SeqList* list);

int SeqList_Length(SeqList* list);

int SeqList_Capacity(SeqList* list);

int SeqList_Insert(SeqList* list, SeqListNode* node, int pos);

SeqListNode* SeqList_Get(SeqList* list, int pos);

SeqListNode* SeqList_Delete(SeqList* list, int pos);


#endif  //__MY_SEQLIST_H__

上面代码为seqlist.h的头文件,需要完成的就对函数声明的实现,线性表顺序存储相当于一个在数组中存储数据,并且在内存中的顺序是连在一起的。要实现的功能为建立链表,摧毁链表,初始化链表(清空链表),求链表长度,求链表容量,在任意位置插入元素,得到任意位置元素,在任意位置删除元素。

功能实现

在功能实现之前因为存储到链表的数据类型不一样,所以要进行转换,要建立一个中间过程,我们用结构体来做,在结构体中嵌套一个一级指针。

typedef struct _tag_SeqList
{
	int length;
	int capacity;
	unsigned int** node;
}TSeqList;

1、建立链表

SeqList* SeqList_Create(int capacity)
{
	int ret = 0;
	TSeqList* tmp = NULL;
	tmp = (TSeqList*)malloc(sizeof(TSeqList));
	//进行错误检查,如果没有成功分配内存,则建立链表失败
	if(tmp == NULL){
		ret = -1;
		printf("func SeqList_Create err:%d\n",ret);
		return NULL;
	}
	memset(tmp,0,siezeof(TSeqList));
	//根据capacity分配空间
	tmp->node = (unsigned int **)malloc(sizeof(unsigned int*)*capacity);
	if(tmp->node == NULL){
		ret = -1;
		printf("func SeqList_Create err:malloc %d\n",ret);
		return NULL;
	}
	tmp->length = 0;
	tmp->capacity = capacity;
	return tmp;
}

2、摧毁链表

void SeqList_Destroy(SeqList* list)
{
	//摧毁链表,及将分配的内存回收
	TSeqList* tlist = NULL;
	if(tlist == NULL){
		return;
	}
	tlist = (TSeqList*)list;
	if(tlist->node != NULL){
		free(tlist->node);
	}
	free(tlist);
	
}

3、清空链表

void SeqList_Clear(Seqlist* list)
{
	//清空链表,相当于初始化链表,将所有参数初始化为开始值
	TSeqList* tlsit = NULL;
	if(tlist == NULL)
	{
		return;
	}
	tlist = (TSeqList*)list;
	tlist->length = 0;
}

4、返回链表长度

int SeqList_Length(SeqList* list)
{
	TSeqList* tlsit = NULL;
	if(tlist == NULL)
	{
		return;
	}
	tlist = (TSeqList*)list;
	return tlist->length; 
}

5、返回链表实际容量

在这里要特别说明,链表的长度和容量不是一个东西,链表长度表示链表的实际存储的长度,capacity表示链表的容量。

int SeqList_Capacity(SeqList* list)
{
	TSeqList* tlsit = NULL;
	if(tlist == NULL)
	{
		return;
	}
	tlist = (TSeqList*)list;
	return tlist->capacity; 
}

6、在链表任意位置插入元素

int SeqList_Insert(SeqList* list,SeqListNode* node,int pos)
{
	int ret = 0,i = 0;
	TSeqList* tlist  = NULL;
	if(list == NULL || node == NUll ||pos<0){
		ret  = -1;
		printf("func SeqList_Insert() err:%d \n",ret);
		return ret;
	}
	tlist = (TSeqList*)list;
	//判断插入元素后,链表是否会溢出
	if(tlist->length >= tlist->capacity){
		ret = -2;
		printf("func SeqList_Insert() err:%d \n",ret);
		return ret;
	}
	//容错修正,及插入的位置大于链表中数据的长度,在末尾插入元素
	if(pos >= tlist->length){
		pos = tlist->length;
	}
	//后移,插入新元素后,在插入位置后的元素要后移
	if(i = tlist->length;i>pos;i--){
		tlist->node[i] = tlist->node[i-1];
	}
	//插入元素
	tlist->node[pos] = node;
	tlist->length++;
	return 0;
	
}

7、在链表任意位置得到元素

SeqListNode* SeqList_Get(SeqList* list,int pos)
{
	int i = 0,ret = 0;
	SeqListNode* tmp = 0;
	TSeqList* tlist = NULL;
	if(list == NULL || pos < 0){
		ret = -1;
		printf("func SeqList_Get() err:%d \n",ret);
		return NULL;
	}
	tlist = (SeqList*)list;
	tmp = (void*)tlist->node[pos];
	return tmp;
	
}

8、在链表任意位置删除元素并返回删除的值

SeqListNode* SeqList_Del(SeqList* list,int pos)
{
	int i = 0,ret = 0;
	SeqListNode* tmp = 0;
	TSeqList* tlist = NULL;
	if(list == NULL || pos < 0){
		ret = -1;
		printf("func SeqList_Del() err:%d \n",ret);
		return NULL;
	}
	tlist = (SeqLisst*)list;
	tmp = (SeqListNode*)tlist->node[pos];
	for(i = pos+1;i < tlist->length;i++){
		tlist->node[i-1] = tlist->node[i];
	}
	tlist->length--;
	return tmp;
}

至此所有的功能全部实现。

线性表顺序存储的优缺点

优点:

1、无需为表示表中元素之间的逻辑关系而增加额外的存储空间
2、可以快速的存取表中任意位置的元素

缺点:

1、插入和删除操作需要移动大量元素
2、当线性表长度变化较大时,难以确定存储空间的容量
3、造成存储空间的“碎片”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值