通用静态链表

1、头文件定义

#ifndef _STATICLIST_H
#define _STATICLIST_H

#include <stdio.h>
#include <stdlib.h>

typedef void ListNode;
typedef void StaticList;

StaticList* StaticList_Create(int capacity);

void StaticList_Clear(StaticList* list);

int StaticList_Length(StaticList* list);

int StaticList_Capacity(StaticList* list);

int StaticList_Insert(StaticList* list, ListNode* node, int pos);

ListNode* StaticList_GetNode(StaticList* list, int pos);

ListNode* StaticList_Delete(StaticList* list, int pos);

int StaticList_Destroy(StaticList* list);

#endif

2、头文件实现

#include "StaticList.h"

#define INVALID_NEXT -1

typedef struct{
	int next;
	unsigned int value;
}TListNode;

typedef struct{
	int capacity;
	TListNode header;
	TListNode node[];
}TStaticList;

StaticList* StaticList_Create(int capacity)
{
	TStaticList* list = NULL;
	int i;
	
	if(capacity <= 0)
	{
		return NULL;
	}
	
	list = (TStaticList*)malloc(sizeof(TStaticList) + sizeof(TListNode) * (capacity + 1));
	
	if(list == NULL)
	{
		return NULL;
	}
	
	list->capacity = capacity;
	list->header.next = 0;
	list->header.value = 0;
	
	for(i = 0; i < capacity; i++)
	{
		list->node[i].next = INVALID_NEXT;
	}
	
	return list;
}

void StaticList_Clear(StaticList* list)
{
	TStaticList* Tlist = (TStaticList*)list;
	int i;
	
	if(Tlist == NULL)
	{
		return;
	}
	
	Tlist->header.next = 0;
	Tlist->header.value = 0;
	
	for(i = 0; i < Tlist->capacity; i++)
	{
		Tlist->node[i].next = INVALID_NEXT;
	}
}

int StaticList_Length(StaticList* list)
{
	TStaticList* Tlist = (TStaticList*)list;
	
	if(Tlist == NULL)
	{
		return;
	}
	
	return Tlist->header.value;
}

int StaticList_Capacity(StaticList* list)
{
	TStaticList* Tlist = (TStaticList*)list;
	
	if(Tlist == NULL)
	{
		return;
	}
	
	return Tlist->capacity;
}

int StaticList_Insert(StaticList* list, ListNode* node, int pos)
{
	TStaticList* Tlist = (TStaticList*)list;
	int index;
	int Current = 0;
	int i;
	
	if(Tlist == NULL || node == NULL)
	{
		return -1;
	}
	
	if( pos < 0 || (pos + 1 > Tlist->capacity) )
	{
		return -2;
	}
	
	for(i = 1; i < Tlist->capacity; i++)
	{
		if(Tlist->node[i].next == INVALID_NEXT)
		{
			index = i;
			break;
		}
	}
	Tlist->node[index].value = (unsigned int)node;
	
	Tlist->node[0] = Tlist->header;	
	
	for(i = 0; (i < pos && Tlist->node[Current].next != 0); i++)
	{
		Current = Tlist->node[Current].next;
	}
	Tlist->node[index].next = Tlist->node[Current].next;
	Tlist->node[Current].next = index;
	
	(Tlist->node[0].value)++;
	
	Tlist->header = Tlist->node[0];	
		
	return 0;
}

ListNode* StaticList_GetNode(StaticList* list, int pos)
{
	TStaticList* Tlist = (TStaticList*)list;
	int Current = 0;
	int index;
	int i;
	
	if(Tlist == NULL)
	{
		return NULL;
	}
	
	if( pos < 0 || pos > StaticList_Length(list) - 1 )
	{
		return NULL;
	}
	
	Tlist->node[0] = Tlist->header;
	
	for(i = 0; i < pos; i++)
	{
		Current = Tlist->node[Current].next;
	}
	
	index = Tlist->node[Current].next;
	
	return (ListNode*)(Tlist->node[index].value);
}

ListNode* StaticList_Delete(StaticList* list, int pos)
{
	TStaticList* Tlist = (TStaticList*)list;
	int index;
	int Current = 0;
	int i;
	
	if(Tlist == NULL)
	{
		return NULL;
	}
	
	if( pos < 0 || pos > StaticList_Length(list) - 1 )
	{
		return NULL;
	}
	
	Tlist->node[0] = Tlist->header;
	
	for(i = 0; i < pos; i++)
	{
		Current = Tlist->node[Current].next;
	}
	
	index = Tlist->node[Current].next;
	Tlist->node[Current].next = Tlist->node[index].next;
		
	(Tlist->node[0].value)--;
	
	Tlist->header = Tlist->node[0];
	
	return (ListNode*)(Tlist->node[index].value);
}

int StaticList_Destroy(StaticList* list)
{
	if(list != NULL)
	{
		free(list);
	}
}

3、测试main

int main(int argc, char *argv[]) {
	
	StaticList* list = StaticList_Create(10);
	int i;
	int* node = NULL;
	
	int a1 = 1;
	int a2 = 2;
	int a3 = 3;
	int a4 = 4;
	int a5 = 5;
	
	StaticList_Insert(list, (ListNode*)&a1, StaticList_Length(list));
	StaticList_Insert(list, (ListNode*)&a2, StaticList_Length(list));
	StaticList_Insert(list, (ListNode*)&a3, StaticList_Length(list));
	StaticList_Insert(list, (ListNode*)&a4, StaticList_Length(list));
	StaticList_Insert(list, (ListNode*)&a5, StaticList_Length(list));
	
	for(i = 0; i < StaticList_Length(list); i++)
	{
		node = (int*)StaticList_GetNode(list, i);
		printf("%d: %d\n", i, *node);
	}
	
	while( StaticList_Length(list) != 0)
	{
		node = (int*)StaticList_Delete(list, StaticList_Length(list) - 1);
		printf("%d\n", *node);
	}
	
	return 0;
}
<think>好的,用户想了解通用链表的概念和实现。首先,我需要回顾一下已有的引用内容。引用[1]、[2]、[3]和[4]主要介绍了单链表链表的结构、应用以及时间复杂度比较。用户提到“通用链表”,这可能是指能够存储不同类型数据的链表,或者具有更广泛适用性的实现。 首先,通用链表通常指数据域可以存储任意数据类型,而不仅仅是特定的类型。比如在C语言中,可以通过void指针或联合体来实现。引用[3]中的单链表定义使用了typedef来定义数据类型,但这是针对特定类型的。通用链表需要更灵活的结构。 接下来,我需要考虑如何实现通用性。在C语言中,可以使用void*来存储任意类型的数据指针,这样每个节点可以指向不同类型的数据。但用户需要注意内存管理和类型转换的问题。此外,引用[4]提到链表访问元素的时间复杂度是O(n),而线性表是O(1),这在通用链表中也是一样的。 然后,可能涉及不同编程语言的实现差异。例如,在Python中,由于变量本身就是动态类型的,链表节点可以自然存储任何类型的数据。但在静态类型语言如C++或Java中,可能需要使用泛型或模板来实现通用链表。 另外,用户可能还关心通用链表的操作,如插入、删除、遍历等,这些操作在通用链表中与普通链表类似,但处理数据时需要额外的类型处理步骤。例如,在访问数据时,需要进行类型转换,这可能会引入运行时错误,需要谨慎处理。 还需要考虑内存管理的问题,尤其是当节点存储的数据是动态分配的内存时,释放节点时需要同时释放数据所占用的内存,避免内存泄漏。这在通用链表的实现中尤为重要,因为数据类型不确定,可能需要用户提供自定义的释放函数。 最后,应该总结通用链表的优缺点,比如灵活性高,但访问效率较低,适用于频繁插入删除而较少随机访问的场景。同时,引用[2]中提到链表在插入时复杂度为O(1),而查找为O(n),这在通用链表中同样适用。 在生成回答时,需要结构清晰,分点说明概念、实现方法、内存管理、类型安全、应用场景等。同时,结合引用中的内容,如引用[3]的代码结构可以调整为通用版本,引用[4]的时间复杂度对比也需要提及。最后,生成相关问题,帮助用户进一步学习。</think>### 通用链表的实现与概念 #### 1. 通用链表的定义 通用链表(Generic Linked List)是一种**可存储任意数据类型**的链表结构。其核心设计目标是**解耦数据存储类型与链表操作逻辑**,通过灵活的数据域实现泛用性。在C语言中,通常使用`void*`指针实现数据类型通用性[^3],而在面向对象语言(如C++/Java)中可通过泛型(Generics)实现。 #### 2. 实现方式 **C语言示例(使用`void*`):** ```c typedef struct GenericNode { void *data; // 通用数据指针 struct GenericNode *next; } GenericNode; // 创建节点时需要指定数据大小 GenericNode* create_node(void *data, size_t data_size) { GenericNode *node = malloc(sizeof(GenericNode)); node->data = malloc(data_size); memcpy(node->data, data, data_size); node->next = NULL; return node; } ``` **关键特性:** - `void* data`可指向任意类型数据 - 需配合`memcpy`进行数据拷贝 - 需要额外记录数据类型信息(可通过结构体封装) #### 3. 内存管理要求 由于数据类型的多样性,通用链表需要: - **显式内存释放**:销毁节点时必须释放`data`和节点本身 - **类型转换约定**:取出数据时需强制转换为目标类型 - **生命周期管理**:数据所有权需明确(链表是否负责释放数据) #### 4. 类型安全实现 在C++中可通过模板实现类型安全: ```cpp template <typename T> class GenericNode { public: T data; GenericNode* next; }; ``` 此时编译器会为不同类型生成特化代码,避免手动类型转换的风险。 #### 5. 应用场景 - 需要存储异构数据的场景(如JSON解析器) - 实现通用容器库(如C++ STL的`std::list`) - 插件系统间的数据传递 - 需要动态扩展的数据集合(相比数组更灵活)[^2] #### 6. 性能特点 与普通链表一致: - 插入/删除时间复杂度:$O(1)$(已知位置时) - 随机访问时间复杂度:$O(n)$[^4] - 空间开销:每个节点需额外存储指针(通常4/8字节) ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值