基本概念

设计与实现

插入元素算法

判断线性表是否合法

判断插入位置是否合法

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

将新元素插入

线性表长度加1

获取元素操作

判断线性表是否合法

判断位置是否合法

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

删除元素算法

判断线性表是否合法

判断删除位置是否合法

将元素取出

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

线性表长度减1

代码:

</pre><pre name="code" class="cpp">// seqlist.h
#ifndef  __MY_SEQLIST_H__
#define __MY_SEQLIST_H__

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

#endif  //__MY_SEQLIST_H__
// seqList.cpp
#include <iostream>
#include <cstdio>
#include "seqlist.h"

using namespace std;

typedef struct _tag_SeqList
{
	int capacity;
	int length;
	int **node;
}TSeqList;

//链表 创建
SeqList* SeqList_Create(int capacity)
{
	int ret = -1;
	TSeqList *tmp = NULL;
	tmp = (TSeqList *)malloc(sizeof(TSeqList));
	if (tmp == NULL) {
		ret = 1;
		printf("function SeqList_Create() err:%d\n", ret);
		return NULL;
	}
	memset(tmp, 0, sizeof(TSeqList));
	tmp->capacity = capacity;
	tmp->length = 0;
	tmp->node = (int **)malloc(sizeof(void *) * capacity);
	if (tmp->node == NULL) {
		ret = 2;
		printf("function SeqList_Create() err:%d\n", ret);
		return NULL;
	}
	memset(tmp->node, 0, sizeof(void *) * capacity);

	return tmp;
}

//链表 创建
int SeqList_Create2(int capacity, SeqList**handle)
{
	int			ret = 0;
	TSeqList	*tmp = NULL;
	tmp = (TSeqList *)malloc(sizeof(TSeqList));
	if (tmp == NULL)
	{
		ret = 1;
		printf("func SeqList_Create2() err :%d \n", ret);
		return ret;
	}
	memset(tmp, 0, sizeof(TSeqList));
	tmp->capacity = capacity;
	tmp->length = 0;
	tmp->node = (int **)malloc(sizeof(void *) * capacity);
	if (tmp->node == NULL)
	{
		ret = 2;
		printf("func SeqList_Create2() malloc err :%d \n", ret);
		return ret;
	}

	*handle = tmp;
	return ret;
}

//链表 销毁
void SeqList_Destroy(SeqList* list)
{
	if (list == NULL) {
		return;
	}

	TSeqList *tmp = (TSeqList *)list;
	if (tmp->node != NULL) {
		free(tmp->node);
	}
	free(tmp);

	return;
}

////链表 清空
void SeqList_Clear(SeqList* list)
{
	if (list == NULL) {
		return;
	}

	TSeqList *tmp = (TSeqList *)list;
	tmp->length = 0;
	memset(tmp->node, 0, sizeof(tmp->node));

	return;
}

//链表 长度
int SeqList_Length(SeqList* list)
{
	if (list == NULL) {
		return -1;
	}

	TSeqList *tmp = (TSeqList *)list;
	return tmp->length;
}

//链表 容量
int SeqList_Capacity(SeqList* list)
{
	if (list == NULL) {
		return -1;
	}

	TSeqList *tmp = (TSeqList *)list;
	return tmp->capacity;
}

//链表 在某一个位置 插入元素
int SeqList_Insert(SeqList* list, SeqListNode* node, int pos)
{
	if (list == NULL || node == NULL || pos < 0) {
		return -1;
	}

	TSeqList *tList = (TSeqList *)list;

	// 如果满了
	if (tList->length >= tList->capacity) {
		return -2;
	}

	// 如果pos的位置超出了length,即中间空了一些位置
	if (pos > tList->length) {
		pos = tList->length;
	}

	for (int i = tList->length; i > pos; --i) {
		tList->node[i] = tList->node[i - 1];
	}
	tList->node[pos] = (int *)node;
	++tList->length;

	return 0;
}

//获取某一个位置的链表结点
SeqListNode* SeqList_Get(SeqList* list, int pos)
{
	TSeqList *tList = (TSeqList *)list;
	if (list == NULL || pos < 0 || pos >= tList->length)
	{
		return NULL;
	}

	SeqListNode *tListNode = NULL;
	tListNode = (int *)tList->node[pos];

	return tListNode;
}

//删除某一个位置的结点
SeqListNode* SeqList_Delete(SeqList* list, int pos)
{
	TSeqList *tList = (TSeqList *)list;
	SeqListNode *tListNode = NULL;
	if (list == NULL || pos < 0 || pos >= tList->length) {
		return NULL;
	}

	tListNode = tList->node[pos];
	for (int i = pos + 1; i < tList->length; ++i) {
		tList->node[i - 1] = tList->node[i];
	}
	--tList->length; // 别忘了长度减一

	return tListNode;
}
// main.cpp
#include <iostream>
#include <cstdio>
#include "seqlist.h"

using namespace std;

struct Student
{
	char name[32];
	int age;
};

int main()
{
	Student s1, s2, s3;
	s1.age = 21;
	s2.age = 22;
	s3.age = 23;

	int ret = 0;
	SeqList *list;

	list = SeqList_Create(10);

	ret = SeqList_Insert(list, (SeqListNode *)&s1, 0); // 头插法
	ret = SeqList_Insert(list, (SeqListNode *)&s2, 0); // 头插法
	ret = SeqList_Insert(list, (SeqListNode *)&s3, 0); // 头插法

	// 遍历链表
	for (int i = 0; i < SeqList_Length(list); ++i) {
		Student *tmp = (Student *)SeqList_Get(list, i);
		if (tmp == NULL) {
			printf("function SeqList_Get() err: %d\n", ret);
			return 0;
		}
		printf("age:%d\n", tmp->age);
	}

	// 销毁链表
	while (SeqList_Length(list)) {
		Student *tmp = (Student *)SeqList_Delete(list, 0);
		if (tmp == NULL) {
			printf("function SeqList_Delete() err: %d\n", ret);
			return 0;
		}
		printf("age:%d\n", tmp->age);
	}

	SeqList_Destroy(list);

	return 0;
}

优点:

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

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

缺点:

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

当线性表长度变化较大时难以确定存储空间的容量

代码详情:Github

线性表的顺序存储设计和实现 - API函数实现的更多相关文章

  1. 队列顺序存储 - 设计与实现 - API函数

    队列是一种特殊的线性表 队列仅在线性表的两端进行操作 队头(Front):取出数据元素的一端 队尾(Rear):插入数据元素的一端 队列不允许在中间部位进行操作! queue常用操作 销毁队列 清空队 ...

  2. 队列链式存储 - 设计与实现 - API函数

    队列相关基础内容参我的博文:队列顺序存储 - 设计与实现 - API函数 队列也是一种特殊的线性表:可以用线性表链式存储来模拟队列的链式存储. 主要代码: // linkqueue.h // 队列链式 ...

  3. C 线性表的顺序存储实现及插入、删除等操作示例

    一.线性表的定义 线性表(Linear List)是由同一类型元素构成的有序序列的线性结构.线性表中元素的个数称为线性表的长度:线性表内没有元素(长度为0)时,称为空表:表的起始位置称为表头,表的结束 ...

  4. 2.2_线性表的顺序存储结构_参考集合ArrayList

    [线性表的顺序存储从结构] 指的是用一段连续的存储单元一次储存线性表的数据元素. [线性表的顺序存储的结构代码 C语言版] #define MAXSIZE 20 /*存储空间初始分配量*/ typed ...

  5. 线性表之顺序存储结构(C语言动态数组实现)

    线性表的定义:N个数据元素的有限序列 线性表从存储结构上分为:顺序存储结构(数组)和 链式存储结构(链表) 顺序存储结构:是用一段连续的内存空间存储表中的数据 L=(a1,a2,a3....an) 链 ...

  6. 线性表的顺序存储结构——java

    线性表的顺序存储结构:是指用一组地址连续的存储单元一次存放线性表的元素.为了使用顺序结构实现线性表,程序通常会采用数组来保存线性中的元素,是一种随机存储的数据结构,适合随机访问.java中ArrayL ...

  7. C++编程练习(1)----“实现简单的线性表的顺序存储结构“

    线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素. 故可以用数组来实现顺序存储结构. 用C++编写的利用数组实现简单的读取.插入和删除功能的线性表. #include< ...

  8. 算法与数据结构(一) 线性表的顺序存储与链式存储(Swift版)

    温故而知新,在接下来的几篇博客中,将会系统的对数据结构的相关内容进行回顾并总结.数据结构乃编程的基础呢,还是要不时拿出来翻一翻回顾一下.当然数据结构相关博客中我们以Swift语言来实现.因为Swift ...

  9. 线性表的顺序存储结构之顺序表类的实现_Java

    在上一篇博文——线性表接口的实现_Java中,我们实现了线性表的接口,今天让我们来实现线性表的顺序存储结构——顺序表类. 首先让我们来看下顺序表的定义: 线性表的顺序存储是用一组连续的内存单元依次存放 ...

随机推荐

  1. Ubuntu批量修改文件名后缀

    比如把当前文件夹下所有scss文件后缀改为less rename 's/\.scss/\.less/' ./*

  2. Eclipse调试(1)——基础篇

    作为使用Eclipse的程序员都会使用它的Debug.但是有不少人只会用F6.F8,其他功能知之甚少.今天我就来总结一下我在使用eclipse的debug时的一些个人经验.水平有限,不足之处还请赐教. ...

  3. Android图表库MPAndroidChart(三)——双重轴线形图的实现,这次就so easy了

    Android图表库MPAndroidChart(三)--双重轴线形图的实现,这次就so easy了 在学习本课程之前我建议先把我之前的博客看完,这样对整体的流程有一个大致的了解 Android图表库 ...

  4. 我的第一个RootKit,支持XP、Vista、Win7、Win8 RTM 32位

    只有写过一个BootKit,才能比较深刻的理解其整个过程与机制,也能加深对Windows系统引导各个过程的熟悉和理解. 我写的这个bootkit,暂时还没想到一个比较好的名字,它 1.  支持xp到w ...

  5. Java并发框架——AQS中断的支持

    线程的定义给我们提供了并发执行多个任务的方式,大多数情况下我们会让每个任务都自行执行结束,这样能保证事务的一致性,但是有时我们希望在任务执行中取消任务,使线程停止.在java中要让线程安全.快速.可靠 ...

  6. Android Studio 使用wifi调试插件

    由于手机亦或是数据线的问题,在应用开发过程中会时不时地遇到手机突然连不上电脑的尴尬时刻,于是就学习了如何使用wifi进行应用调试.下面就具体介绍一下adb wifi插件的安装和使用.其实我们只需要安装 ...

  7. Linux Debugging (九) 一次生产环境下的“内存泄露”

    一个偶然的机会,发现一个进程使用了超过14G的内存.这个进程是一个RPC server,只是作为中转,绝对不应该使用这么多内存的.即使并发量太多,存在内存中的数据太多,那么在并发减少的情况下,这个内存 ...

  8. SSH架构实现在线支付功能

    在线支付是指卖方与卖方通过因特网上的电子商务网站进行交易时,银行为其提供网上资金结算服务的一种业务,她为企业和个人提供了一个安全.快捷.方便的电子商务应用环境和网上资金结算工具,在线支付不仅帮助企业实 ...

  9. 带你深入理解STL之List容器

    上一篇博客中介绍的vector和数组类似,它拥有一段连续的内存空间,并且起始地址不变,很好的支持了随机存取,但由于是连续空间,所以在中间进行插入.删除等操作时都造成了内存块的拷贝和移动,另外在内存空间 ...

  10. UNIX环境高级编程——实现uid to name

    setpwent()用来将getpwent()的读写地址指回文件开头,即从头读取密码文件中的账号数据. strcut passwd * getpwent(void); getpwent()用来从密码文 ...