线性表(List)—顺序存储结构的设计与实现
线性表顺序结构的设计
线性表顺序存储结构:用一段地址连续地存储单元依次存放 线性表的数据元素。
定义一个结构体用存储数据
typedef struct _tag_SeqList
{
int Length;//长度
int Capacity;//容量
unsigned int **node;
}TSeqList;
- int Capacity:表示线性表顺序分配空间的总个数【容量】。
- int Length:表示当前顺序表存放数据的个数【当前长度】。
- unsigned int **node:分配Capacity个连续的内存空间存放unsigned int *node ,以便接收外外部数据地址。
线性表顺序存储结构的重要算法
插入元素算法 int SeqList_Insert(Seqlist *list, SeqlistNode *node, int pos)
1.判断线性表是否合法;
2.判断插入元素位置是否合法;
3.要把插入第pos位的后面的位置的元素都后移一位;
4.新元素插入;
5.线性表当前长度(Length)加1。获取元素算法 SeqlistNode *SeqList_Get(Seqlist *list, int pos)
1.判断线性表是否合法;
2.判断位置是否合法;
3.直接通过数组下标方式获取元素。删除元素算法 SeqlistNode *SeqList_Get(Seqlist *list, int pos)
1.判断线性表是否合法;
2.判断删除位置是否合法;
3.将元素取出;
4.将删除位置后的元素分别向前移动一一个位置;
5.线性表当前长度(Length)减1。
线性表顺序结构的实现
- SeqList.h
#ifndef _SEQLIST_H_
#define _SEQLIST_H_
typedef void Seqlist;
typedef void SeqlistNode;
//创建容量为capacity的线性表
Seqlist * SeqList_Create(int capacity);
//清空线性表
void SeqList_Clear(Seqlist *list);
//销毁线性表
void SeqList_Destroy(Seqlist *list);
//获取线性表的当前长度
int SeqList_Length(Seqlist *list);
//获取线性表的容量
int SeqList_Capacity(Seqlist *list);
//向线性表pos位置插入node元素
int SeqList_Insert(Seqlist *list, SeqlistNode *node, int pos);
//将线性表pos位置的元素删除
SeqlistNode *SeqList_Delete(Seqlist *list, int pos);
//获取线性表的pos位置元素
SeqlistNode *SeqList_Get(Seqlist *list, int pos);
#endif // !_SEQLIST_H_
- SeqList.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "seqlist.h"
typedef struct _tag_SeqList
{
int Length;//长度
int Capacity;//容量
unsigned int **node;
}TSeqList;
//创建容量为capacity的线性表
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() malloc(sizeof(TSeqList)) err:%d\n", ret);
return tmp;
}
//初始化内存空间
memset(tmp, 0, sizeof(TSeqList));
//根据capacity分配线性表空间容量
tmp->node = (unsigned int **)malloc(sizeof(unsigned int *)*capacity);
if (tmp->node == NULL)
{
ret = -2;
printf("func SeqList_Create() malloc(sizeof(unsigned int *)*capacity) err:%d\n", ret);
return tmp->node;
}
tmp->Capacity = capacity;
//tmp->Length()在memset()函数中已经被初始化为0了
return tmp;
}
//清空线性表
void SeqList_Clear(Seqlist *list)
{
TSeqList *tlist = NULL;
//判断线性表list是否为空
if (list == NULL)
{
return;
}
tlist = (TSeqList *)list;
tlist->Length = 0;
return;
}
//销毁线性表
void SeqList_Destroy(Seqlist *list)
{
TSeqList *tlist = NULL;
//判断线性表list 是否为空
if (list == NULL)
{
return;
}
tlist = (TSeqList *)list;
//判断tlist->node是否为空
if (tlist->node != NULL)
{//释放tlist->node的内存空间
free(tlist->node);
tlist->node = NULL;
tlist->Length = 0;
tlist->Capacity = 0;
}
return ;
}
//获取线性表的长度
int SeqList_Length(Seqlist *list)
{
int ret = 0;
TSeqList *tlist = NULL;
if (list == NULL)
{
ret = -1;
printf("func SeqList_Length() err:%d\n", ret);
return ret;
}
tlist = (TSeqList *)list;
ret = tlist->Length;
return ret;
}
//获取线性表的容量
int SeqList_Capacity(Seqlist *list)
{
int ret = 0;
TSeqList *tlist = NULL;
if (list == NULL)
{
ret = -1;
printf("func SeqList_Capacity() err:%d\n", ret);
return ret;
}
tlist = (TSeqList *)list;
ret = tlist->Capacity;
return ret;
}
//向线性表pos位置插入元素node
int SeqList_Insert(Seqlist *list, SeqlistNode *node, int pos)
{
int i = 0, ret = 0;
TSeqList *tlist = NULL;
// ①判断线性表是否合法;
if (list == NULL || node == NULL || pos < 0)
{
ret = -1;
printf("func SeqList_Insert() (list == NULL || node == NULL || pos < 0) err:%d\n", ret);
return ret;
}
tlist = (TSeqList *)list;
// ②判断插入元素位置是否合法;
if (tlist->Length >= tlist->Capacity)
{
ret = -2;
printf("func SeqList_Insert() (tlist->Length >= tlist->Capacity) err:%d\n", ret);
return ret;
}
// 容错:线性表容量为20,但是length为6,用户要在第10个位置插入元素,将元素插入到了第7个位置
if (pos > tlist->Length)
{
pos = tlist->Length;
}
// ③要把插入第pos位的后面的位置的元素都后移一位;
for (i = tlist->Length; i > pos; i--)
{
tlist->node[i] = tlist->node[i-1];
}
// ④新元素插入;
tlist->node[i] = (unsigned int*)node;
// ⑤线性表当前长度(Length)加1;
tlist->Length++;
return ret;
}
//将线性表pos位置的元素删除
SeqlistNode *SeqList_Delete(Seqlist *list, int pos)
{
int ret = 0, i = 0;
TSeqList *tlist = NULL;
SeqlistNode *tmp = NULL;
// ①判断线性表是否合法;
if (list == NULL || pos < 0)
{
ret = -1;
printf("func SeqList_Delete() (list == NULL || pos < 0) err:%d\n", ret);
return tmp;
}
tlist = (TSeqList *)list;
// ②判断删除位置是否合法;
if (pos > tlist->Length)
{
ret = -2;
printf("func SeqList_Delete() (pos > tlist->Length) err:%d\n", ret);
return tmp;
}
// ③将元素取出;
tmp = (SeqlistNode *)tlist->node[pos];
// ④将删除位置后的元素分别向前移动一一个位置
for ( i = pos+1; i < tlist->Length; i++)
{
tlist->node[i - 1] = tlist->node[i];
}
// ⑤线性表当前长度(Length)减1
tlist->Length--;
return tmp;
}
//获取线性表pos位置的元素
SeqlistNode *SeqList_Get(Seqlist *list, int pos)
{
int ret = 0;
TSeqList *tlist = NULL;
SeqlistNode *tmp = NULL;
// ①判断线性表是否合法;
if (list == NULL || pos < 0)
{
ret = -1;
printf("func SeqList_Get() (list == NULL || pos < 0) err:%d\n", ret);
return tmp;
}
tlist = (TSeqList *)list;
// ②判断位置是否合法;
if (pos > tlist->Length)
{
ret = -2;
printf("func SeqList_Get() (pos > tlist->Length) err:%d\n", ret);
return tmp;
}
// ③直接通过数组下标方式获取元素
tmp = tlist->node[pos];
return tmp;
}
- SeqList集成测试框架
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "seqlist.h"
typedef struct Teacher
{
int age;
char name[64];
}Teacher;
void main()
{
int ret = 0, i = 0;
Seqlist *list = NULL;
Teacher t1,t2,t3,t4,t5;
t1.age = 11;
t2.age = 22;
t3.age = 33;
t4.age = 44;
t5.age = 55;
strcpy(t1.name, "t1");
strcpy(t2.name, "t2");
strcpy(t3.name, "t3");
strcpy(t4.name, "t4");
strcpy(t5.name, "t5");
list = SeqList_Create(10); //创建一个容量为10的线性表
if (list == NULL) //判断线性表是否创建成功
{
printf("func SeqList_Create() err\n");
return;
}
ret = SeqList_Capacity(list); //获取线性表容量
printf("The Capacity of List is %d\n", ret);
ret = SeqList_Insert(list, (SeqlistNode *)&t1, 0); //向线性中插入元素
if (ret != 0) //判断是否插入成功
{
printf("func SeqList_Insert() err: %d\n", ret);
return;
}
ret = SeqList_Insert(list, (SeqlistNode *)&t2, 1); //向顺序表中插入元素
if (ret != 0) //判断是否插入成功
{
printf("func SeqList_Insert() err: %d\n", ret);
return;
}
ret = SeqList_Insert(list, (SeqlistNode *)&t3, 2); //向顺序表中插入元素
if (ret != 0) //判断是否插入成功
{
printf("func SeqList_Insert() err: %d\n", ret);
return;
}
ret = SeqList_Insert(list, (SeqlistNode *)&t4, 3); //向顺序表中插入元素
if (ret != 0) //判断是否插入成功
{
printf("func SeqList_Insert() err: %d\n", ret);
return;
}
ret = SeqList_Insert(list, (SeqlistNode *)&t5, 4); //向顺序表中插入元素
if (ret != 0) //判断是否插入成功
{
printf("func SeqList_Insert() err: %d\n", ret);
return;
}
ret= SeqList_Length(list); //获取线性表当前长度
printf("The Length of SeqList is %d\n", ret);
printf("Get Elements of Seqlist: \n");
for(i=0;i<SeqList_Length(list);i++)
{
Teacher *tmp = (Teacher *)SeqList_Get(list, i); //获取线性表第i个位置节点
if (tmp == NULL) //获取节点是否成功
{
printf("func SeqList_Get() err\n");
return;
}
printf("tmp->name:%s\t tmp->age:%d\n", tmp->name, tmp->age);
}
printf("Delete Elements of SeqList:\n");
while (SeqList_Length(list))
{
Teacher *tmp = (Teacher *)SeqList_Delete(list, 0);//删除线性表第0个位置节点
if (tmp == NULL) //删除节点是否成功
{
printf("func SeqList_Get() err\n");
return;
}
printf("tmp->name:%s\t tmp->age:%d\n", tmp->name, tmp->age);
}
SeqList_Clear(list); //清空顺序表
SeqList_Destroy(list); //销毁顺序表
return;
}
- 运行结果