C语言Array_List简单实现

C语言Array_List简单实现,对集合的增删改查,不做线程控制

Array_List.h

/****************************************************************************
作者:代浩然
时间:2017-8-2
该文件定义为线性链表相关的实现
线性链表的特性:
	1、在内存中的存放地址是连续的
优点:
	1、由于地址的连续性,所以CPU的pc指针寻址的地址空间的范围不会太大,所以随机访问链表的速度非常快,遍历的速度非常快,释放空间也比较快
缺点:
	2、也正是地址的连续性,所以当每次随机插入的时候都要进行链表剩余空间的检查,如果空间不够,然后又要重新分配内存,
	   如果随机插入的位置后面有元素,需要把该位置的元素都要依次往后挪一位,然后在当前位置进行插入,所以这样就造成速度非常慢
****************************************************************************/
#pragma once
#ifndef _ARRAY_LIST_H
#define _ARRAY_LIST_H

#ifdef __cplusplus
extern "C" {
#endif

//链表初始化大小
#define ARRAY_LIST_INIT_SIZE 100
//链表存满每次增加的大小
#define ARRAY_LIST_INCREASE_SIZE 200

//定义节点
typedef struct _Array_Node{
	void* data;//数据域
}Array_Node;

//定义链表结构
typedef struct _Array_List{
	Array_Node *node;//数据域
	unsigned long length;//链表的当前长度
	unsigned long size;//链表的整体大小
}Array_List;

/**
 * 功能:初始化链表
 * 返回值:如果成功,则返回链表的地址,如果失败返回NULL
 */
Array_List* Array_List_Init();

/**
 * 功能:随机插入链表
 * 参数:
 *		pList:链表地址
 *		pData:插入的数据节点
 *		index:要插入的位置,如果为0,则默认从链表的开始处插入,如果为-1,则默认从链表的最后插入
 * 返回值:成功返回0,失败返回-1
 */
int Array_List_Insert(Array_List* pList,void* pData,long index);

/**
 * 功能:从某个位置取出元素
 * 参数:
 *		pList:链表地址
 *		index:位置
 * 返回值:返回数据体指针
 */
void* Array_List_GetAt(Array_List* pList,unsigned long index);

/**
 * 功能:通过索引删除元素,删除元素只是将data域置为NULL,并不会释放data指针,由调用者释放
 * 参数:
 *		pList:链表地址
 *		index:位置
 */
void Array_List_RemoveAt(Array_List* pList,unsigned long index);

/**
 * 功能:清空链表
 * 参数:
 *	pList:链表地址
 */
void Array_List_Clear(Array_List* pList);

/**
 * 功能:释放链表空间
 * 参数:
 *	pList:链表地址
 */
void Array_List_Free(Array_List* pList);

/**
 * 功能:Array测试
 */
void Array_List_Test();

#ifdef __cplusplus
}  /* end of the 'extern "C"' block */
#endif

#endif

Array_List.c

#include "Array_List.h"
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>


/**
 * 功能:初始化链表
 * 返回值:如果成功,则返回链表的地址,如果失败返回NULL
 */
Array_List* Array_List_Init()
{
	int i = 0;
	Array_List* pList = (Array_List*)malloc(sizeof(Array_List));//配置链表空间
	if(pList == NULL)
	{
		return NULL;
	}
	//分配Node节点
	pList->node = (Array_Node*)malloc(ARRAY_LIST_INIT_SIZE * sizeof(Array_Node));//分配存放数据域的空间
	if(pList->node == NULL)
	{
		free(pList);
		return NULL;
	}
	//将Node的data域置为空置
	for(i = 0;i < ARRAY_LIST_INIT_SIZE;i++)
	{
		pList->node[i].data = NULL;
	}
	pList->length = 0;
	pList->size = ARRAY_LIST_INIT_SIZE;
	return pList;
}

/**
 * 功能:随机插入链表
 * 参数:
 *		pList:链表地址
 *		pData:插入的数据节点
 *		index:要插入的位置,如果为0,则默认从链表的开始处插入,如果为-1,则默认从链表的最后插入
 * 返回值:成功返回0,失败返回-1
 */
int Array_List_Insert(Array_List* pList,void* pData,long index)
{
	long i = 0;
	unsigned long reallocSize = 0;//重新分配空间的大小
	if(pList == NULL)
		return -1;
	if(index < -1 || (index > pList->length && index != -1))
	{
		return -1;
	}
	//判断链表空间够不够长
	if(pList->length == pList->size - 1)
	{
		//重新分配空间
		reallocSize = pList->size + ARRAY_LIST_INCREASE_SIZE;
		pList->node = (Array_Node*)realloc(pList->node,reallocSize * sizeof(Array_Node));
		if(pList->node == NULL)
		{
			return -1;
		}
		//并且将新增节点的data域置为空
		for(i = pList->length;i < reallocSize;i++)
		{
			pList->node[i].data = NULL;
		}
		pList->size = reallocSize;
	}
	//开始插入
	if(index == -1)//从末尾处插入
	{
		pList->node[pList->length].data = pData;
		pList->length++;//长度自增1
		return 0;
	}
	else if(index == 0) //从开始处插入
	{
		for(i = pList->length;i >0;i--)
		{
			pList->node[i] = pList->node[i - 1];
		}
		pList->node[0].data = pData;
		pList->length++;//长度自增1
		return 0;
	}
	else//指定位置插入
	{
		for(i = pList->length;i > index;i--)
		{
			pList->node[i] = pList->node[i - 1];
		}
		pList->node[i].data = pData;
		pList->length++;//长度自增1
		return 0;
	}
	return 0;
}

/**
 * 功能:通过索引删除元素,删除元素只是将data域置为NULL,并不会释放data指针,由调用者释放
 * 参数:
 *		pList:链表地址
 *		index:位置
 */
void Array_List_RemoveAt(Array_List* pList,unsigned long index)
{
	int i = 0;
	if(pList == NULL)
		return;
	if(index < 0 || index >= pList->length)
		return;
	for(i = index; i < pList->length;i++)//让删除的索引后的元素依次往前移
	{
		pList->node[i] = pList->node[i + 1];
	}
	//将最后一位置空
	pList->node[pList->length - 1].data = NULL;
	//长度减1
	pList->length--;
}

/**
 * 功能:从某个位置取出元素
 * 参数:
 *		pList:链表地址
 *		index:位置
 */
void* Array_List_GetAt(Array_List* pList,unsigned long index)
{
	void* pData = NULL;
	if(pList == NULL)
	{
		return NULL;
	}
	if(index < 0 || index >= pList->length)
	{
		return NULL;
	}
	pData = pList->node[index].data;
	return pData;
}

/**
 * 功能:清空链表
 * 参数:
 *	pList:链表地址
 */
void Array_List_Clear(Array_List* pList)
{
	int i = 0;
	if(pList == NULL)
	{
		return;
	}
	//将数据域置为空
	for(i = 0;i < pList->length;i++)
	{
		if(pList->node[i].data != NULL)
		{
			pList->node[i].data = NULL;
		}
	}
	pList->length = 0;
}

/**
 * 功能:释放链表空间
 * 参数:
 *	pList:链表地址
 */
void Array_List_Free(Array_List* pList)
{
	if(pList == NULL)
		return;
	//释放节点
	if(pList->node != NULL)
	{
		free(pList->node);
		pList->node = NULL;
	}
	if(pList != NULL)
	{
		free(pList);
		pList = NULL;
	}
}

/**
 * 功能:Array_List测试
 */
void Array_List_Test()
{
	int i = 0;
	int *p = NULL;
	Array_List* list = Array_List_Init();
	//动态添加1000个值
	for(i = 0;i < 1000;i++)
	{
		p = (int*) malloc(sizeof(int));
		*p = i;
		Array_List_Insert(list,p,-1);
	}
	//取出第500个元素
	p = (int*)Array_List_GetAt(list,499);
	//删除第500个元素,删除之后记得释放
	Array_List_RemoveAt(list,499);
	free(p);
	//重新获取第500个元素
	p = (int*)Array_List_GetAt(list,499);
	//开始释放空间
	for(i = 0;i<list->length;i++)
	{
		p = (int*)Array_List_GetAt(list,i);
		free(p);
	}
	Array_List_Clear(list);
	Array_List_Free(list);
}


  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

落寞书生

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

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

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

打赏作者

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

抵扣说明:

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

余额充值