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;
}
}
}