Linux-C学习笔记-一劳永逸的顺序表

14 篇文章 0 订阅
12 篇文章 0 订阅

C语言学习笔记之——一劳永逸的顺序表

顺序表用来将同一类型的数据结点顺序存储于内存中,在学习阶段,通常是给一种数据类型创建一组顺序表操作函数,写多了就会发现,所有的顺序表操作基本上都相同,对于要在一个项目中写多组顺序表操作函数的做法,显然不可取,于是乎,学习了一种通用顺序表操作函数,采用顺序表存储数据节点地址的方式,建立顺序表,之后,对于各个结点的操作都用指针来操作,具体头文件及实现文件如下,下面的代码,可以对任何类型的数据结点按照标准的顺序表的操作方法实现管理:

/*************************************************************************************************************/

file : SeqList.h

#ifndef _SEQLIST_H_
#define _SEQLIST_H_

typedef void SeqList;
typedef void SeqListNode;

extern SeqList* SeqList_Create(int capacity);
extern void SeqList_Destroy(SeqList* list);
extern void SeqList_Clear(SeqList* list);
extern int SeqList_Length(SeqList* list);
extern int SeqList_Capacity(SeqList* list);
extern int SeqList_Insert(SeqList* list, SeqListNode* node, int pos);
extern SeqListNode* SeqList_Get(SeqList* list, int pos);
extern SeqListNode* SeqList_Delete(SeqList* list, int pos);
extern void SeqList_Reverse(SeqList* list);

#endif

/************************************************************************************************/

file : SeqList.c

#include <stdio.h>
#include <malloc.h>
#include "SeqList.h"


//typedef void* TSeqListNode;    //分装顺序表结点 
typedef unsigned int TSeqListNode;    //分装顺序表结点 
typedef struct _tag_TSeqList          //分装顺序表 
{
	int capacity;                     //顺序表容量 
	int length;                       //顺序表当前长度 
	TSeqListNode* node;               //顺序表结点指针 
}TSeqList;


/*****************************************************************************
* 顺序表创建 
* 创建成功返回顺序表头指针 
* 创建失败返回NULL 
******************************************************************************/
SeqList* SeqList_Create(int capacity)
{
	TSeqList* ret = NULL;
	
	if(capacity >= 0)
	{
		// 一次性申请顺序表表头空间及顺序表数据空间,顺序表数据区紧接顺序表表头空间 
		ret = (TSeqList*)malloc(sizeof(TSeqList) + sizeof(TSeqListNode)*capacity); 
	}
	
	if(ret != NULL)
	{
		ret->capacity = capacity;
		ret->length = 0;
		ret->node = (TSeqListNode*)(ret + 1);        // 利用表头与数据区特殊关系,得到数据区指针
	}
	
	return (SeqList*)ret;
}


/*****************************************************************************
* 顺序表销毁 
* 没有返回值,先释放数据区,再释放顺序表头,最后将顺序表指针清空 
******************************************************************************/
void SeqList_Destroy(SeqList* list)
{
	TSeqList* sList = (TSeqList*)list;
	TSeqListNode* pList = sList->node;
	free(pList);                             // 释放顺序表数据空间 
	free(list);                              // 释放顺序表表头空间 
	list = NULL;
}


/*****************************************************************************
* 顺序表清零
* 没有返回值,直接将顺序表长度清零,忽略原有数据的存在 
******************************************************************************/
void SeqList_Clear(SeqList* list)
{
	TSeqList* sList = (TSeqList*)list;
	
	if(sList != NULL)
	{
		sList->length = 0;
	}
}


/******************************************************************* 
* 返回顺序表的长度 
* 返回-1表示获取失败
* 返回非负数表示获取成功 
********************************************************************/
int SeqList_Length(SeqList* list)
{
	int ret = -1;
	TSeqList* sList = (TSeqList*)list;
	
	if(sList != NULL)
	{
		ret = sList->length;
	}
	
	return ret;
}


/******************************************************************* 
* 返回顺序表的容量
* 返回-1表示获取失败
* 返回非负数表示获取成功 
********************************************************************/
int SeqList_Capacity(SeqList* list)
{
	int ret = -1;
	TSeqList* sList = (TSeqList*)list;
	
	if(sList != NULL)
	{
		ret = sList->capacity;
	}
	
	return ret;
}


/******************************************************************* 
* 顺序表插入运算 
* 返回0表示插入失败
* 返回1表示插入成功 
********************************************************************/
int SeqList_Insert(SeqList* list, SeqListNode* node, int pos)
{
	int i = 0;
	TSeqList* sList = (TSeqList*)list;
	int ret = (sList != NULL);
	
	ret = ret && (0 <= pos) && (sList->length +1 <= sList->capacity);
	
	if(ret)
	{
		if(pos > sList->length)
		{
			pos = sList->length;
		}
		
		for(i = sList->length; i > pos; i--)
		{
			sList->node[i] = sList->node[i-1];
		}
		
		sList->node[i] = (TSeqListNode)node;   //保存地址值
		
		sList->length++;
	}
	
	return ret;
}


/******************************************************************* 
* 获取顺序表结点 
* 返回NULL表示获取失败
* 返回非NULL表示获取成功 
********************************************************************/
SeqListNode* SeqList_Get(SeqList* list, int pos)
{
	SeqListNode* ret = NULL;
	TSeqList* sList = (TSeqList*)list;
	
	if((sList != NULL) && (0 <= pos) && (pos <= sList->length))
	{
		ret = (SeqListNode*)(sList->node[pos]);
	}
	
	return ret;
}


/******************************************************************* 
* 删除顺序表结点 
* 返回NULL表示删除失败
* 返回非NULL表示删除成功 
********************************************************************/
SeqListNode* SeqList_Delete(SeqList* list, int pos)
{
	int i = 0;
	SeqListNode* ret = SeqList_Get(list, pos);
	
	if(ret)
	{
		TSeqList* sList = (TSeqList*)list;
		
		for(i = pos+1; i < sList->length; i++)
		{
			sList->node[i-1] = sList->node[i];
		}
		
		sList->length--;
	}
	
	return ret;
}

/******************************************************************* 
* 顺序表逆序操作 
* 无返回值
********************************************************************/
void SeqList_Reverse(SeqList* list)
{
	int index = 0;
	int length = SeqList_Length(list);
	
	if(length > 1)
	{
		TSeqList* sList = (TSeqList*)list;
		
		for(index = 0; index < length - 1 - index; index++)
		{
			TSeqListNode* swap = (TSeqListNode*)(sList->node[index]);
			sList->node[index] = sList->node[length-1-index];
			sList->node[length-1-index] = (TSeqListNode)swap;
		}
	}
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值