您的位置:首页 > 其它

线性表的顺序存储

2016-10-29 22:36 253 查看

线性表的顺序存储

线性表的顺序存储
基本概念

设计和实现
1 插入元素算法

2 获取元素操作

3 删除元素算法

4 具体代码

优缺点

1.基本概念



2.设计和实现

2.1 插入元素算法

判断线性表是否合法

判断插入位置是否合法

把最后一个元素到插入位置的元素后移一个位置

将新元素插入

线性表长度加1

2.2 获取元素操作

判断线性表是否合法

判断位置是否合法

直接通过数组下标的方式获取元素

2.3 删除元素算法

判断线性表是否合法

判断删除位置是否合法

将元素取出

将删除位置后的元素分别向前移动一个位置

线性表长度减1

2.4 具体代码:

头文件:

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

/*数据类型的封装--使用void类型*/
typedef void SeqList;
typedef void SeqListNode;//接受任意类型的数据元素,
//存放的是具体数据元素的首地址,
//不是直接存放数据元素

/*顺序存储各个函数*/
SeqList* SeqList_Create(int capacity);

void SeqList_Destroy(SeqList* list);

void SeqList_Clear(SeqList* list);

int SeqList_Length(SeqList* list);

int SeqList_Capacity(SeqList* list);

int SeqList_Insert(SeqList* list, SeqListNode* node, int pos);

SeqListNode* SeqList_Get(SeqList* list, int pos);

SeqListNode* SeqList_Delete(SeqList* list, int pos);


实现文件

#include "seqlist.h"

/*表头数据结构*/
typedef struct _MyStruct
{
int length;//当前实际长度
int capacity;//容量
unsigned int * node;//线性表的起始位置,线性表里的每一个节点存放的是地址值,
//该地址是每个数据元素的起始地址,类似于Linux内核里面的链表思想
}TSeqList;

/*创建线性表*/
SeqList* SeqList_Create(int capacity)
{
TSeqList * tmp = NULL;//表头

tmp = (TSeqList*)malloc(sizeof(TSeqList));//为表头分配内存
if (NULL == tmp)
{
printf("Sorry!\n");
return NULL;
}
memset(tmp, 0, sizeof(TSeqList));//初始化表头

/*根据容量分配内存*/
tmp->node = (unsigned int *)malloc(sizeof(unsigned int )*capacity);
if (tmp->node == NULL)
{
printf("sorry!!\n");
return NULL;
}

/*初始化容量和长度*/
tmp->capacity = capacity;
tmp->length = 0;

/*返回表头*/
return tmp;
}

/*销毁线性表*/
void SeqList_Destroy(SeqList* list)
{
TSeqList * tmp = NULL;
/*合法性检测*/
if (list == NULL)
{
return ;
}

tmp = (TSeqList*)list;
/*先释放线性表*/
if (tmp->node != NULL)
{
free(tmp->node);
}
/*再释放表头*/
free(tmp);

return ;
}

/*清空线性表*/
void SeqList_Clear(SeqList* list)
{
TSeqList * tmp = NULL;
if (list == NULL)
{
return ;
}
tmp = (TSeqList*)list;
tmp->length = 0;//清空长度即可

return ;
}

/*获取线性表长度*/
int SeqList_Length(SeqList* list)
{

TSeqList * tmp = NULL;
if (list == NULL)
{
return -1;
}
tmp = (TSeqList*)list;

return tmp->length;
}

/*获取容量*/
int SeqList_Capacity(SeqList* list)
{

TSeqList * tmp = NULL;
if (list == NULL)
{
return -1;
}
tmp = (TSeqList*)list;

return tmp->capacity;
}

/*插入元素:把数据元素的首地址放进线性表的节点*/
int SeqList_Insert(SeqList* list, SeqListNode* node, int pos)
{
TSeqList * tmp = NULL;
int i = 0;

/*合法性判断*/
if (list == NULL || node == NULL || pos < 0)
{
printf("argv is error\n");
return -1;
}

tmp = (TSeqList*)list;

/*线性表是否已满*/
if (tmp->capacity <= tmp->length)
{
printf("is full\n");
return -2;
}

/*给出的目标位置是否合理*/
if (pos >= tmp->length)
{
pos = tmp->length;//容错纠正
}

/*元素后移*/
for (i = tmp->length; i > pos;i--)
{
tmp->node[i] = tmp->node[i - 1];
}

tmp->node[i] = (unsigned int)node;//将数据元素首地址直接存入线性表节点中
tmp->length++;//长度修改
return 1;
}

/*获取指定位置的元素*/
SeqListNode* SeqList_Get(SeqList* list, int pos)
{
TSeqList * tmp = NULL;

if (list == NULL || pos < 0)
{
printf("argv is error\n");
return NULL;
}

tmp = (TSeqList*)list;

return (void *)(tmp->node[pos]);//返回数据元素的首地址
}

/*从线性表删除指定位置的数据元素*/
SeqListNode* SeqList_Delete(SeqList* list, int pos)
{
TSeqList * tmp = NULL;
SeqListNode * ret = NULL;
int i = 0;
if (list == NULL || pos < 0)
{
printf("argv is error\n");
return NULL;
}

tmp = (TSeqList*)list;

/*容错纠正*/
if (pos >= tmp->length)
{
pos = tmp->length;
}

/*获取要删除的数据元素的首地址*/
ret = (void*)(tmp->node[pos]);

/*元素前移*/
for (i = pos + 1; i < tmp->length; i++)
{
tmp->node[i - 1] = tmp->node[i];
}

tmp->length--;//修改长度
return ret;//返回被删除的数据元素首地址
}


测试文件

#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 = 31;
t2.age = 32;
t3.age = 33;
t4.age = 34;
t5.age = 35;

list = SeqList_Create(10);
if (list == NULL)
{
printf("func SeqList_Create() ret :%d \n", ret);
return;
}

ret = SeqList_Insert(list, (SeqListNode*)&t1, 0); //头插法
ret = SeqList_Insert(list, (SeqListNode*)&t2, 0); //头插法
ret = SeqList_Insert(list, (SeqListNode*)&t3, 0); //头插法
ret = SeqList_Insert(list, (SeqListNode*)&t4, 0); //头插法
ret = SeqList_Insert(list, (SeqListNode*)&t5, 0); //头插法

//遍历
for (i = 0; i<SeqList_Length(list); i++)
{
Teacher*  tmp = (Teacher *)SeqList_Get(list, i);
if (tmp == NULL)
{
return;
}
printf("tmp->age:%d ", tmp->age);
}
int var = 190;//同时插入Teacher和int类型的数据
ret = SeqList_Insert(list, (SeqListNode*)&var, 0); //再次证明该顺序表可以插入任意类型的数据元素
printf("%d\n%d\n",(*(int *)SeqList_Get(list, 0)) + 1,SeqList_Length(list));

//删除链表中的节点
while (SeqList_Length(list) > 0)
{
SeqList_Delete(list, 0);
}
SeqList_Destroy(list);
system("pause");
return;
}


3. 优缺点

优点:

无需为线性表中的逻辑关系增加额外的空间

可以快速的获取表中合法位置的元素

缺点:

插入和删除操作需要移动大量元素

当线性表长度变化较大时难以确定存储空间的容量
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  线性表 算法