IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 基于C语言的顺序表实现 -> 正文阅读

[C++知识库]基于C语言的顺序表实现

->Gitee源代码点击这里<-
顺序表的本质是一个动态开辟的数组
实现数据表,首先需要创建一个结构体,该结构体的成员记录了该数组的信息
以整形顺序表为例,为了方便以后代码的修改和维护,我们将int重命名

typedef int SLDatatype;

typedef struct SeqList
{
	SLDatatype* a;   //指向数组的指针
	int size;		//数组有效数据的长度
	int capacity;	//数组的最大容量
}SeqList;

我们创建一个结构体变量

struct SeqList myseq;

此时,变量下的成员都需要随机值,因此我们需要一个初始化成员变量的接口(即函数)
由于成员的值需要发生改变,所以我们需要传地调用函数
初始化时,我们假设需要给定一个初始的数组大小

void SeqListInit(SeqList* pq); //接口的声明
void SeqListInit(SeqList* pq)
{
	assert(pq);    //防止传给函数的地址为NULL
	pq->a = (SLDatatype*)malloc(sizeof(SLDatatype) * 4); //初始大小为4个整形空间
	if (pq->a == NULL)
	{
		printf("Init Failed\n");
		exit(-1);
	}

	pq->capacity = 4;    //数组的初始最大容量为4
	pq->size = 0;		//初始化时数组内还没有有效数据
}

由于数组的动态开辟的,所以使用完之后需要将空间释放,因此对应的,需要有一个释放动态开辟空间的接口

void SeqListDestroy(SeqList* pq);
void SeqListDestroy(SeqList* pq)
{
	assert(pq);
	free(pq->a);
	pq->a = NULL;
	pq->size = pq->capacity = 0;
}

数组的准备工作已经完成,有了数组,就需要完成数据的处理部分,即数据的增删改查
一、插入数据的接口
①实现任意位置插入
我们需要接口实现能在数组的任意位置 _pos _处插入数据(注意:顺序表的数据必须是连续的,所以任意位置是有限制的,即0<pos<size)
插入数据的原理:从数组的最后一个数据开始,依次往后挪动一个空间,到pos处停止,将pos处原本的数据覆盖成想要插入的数据
而在插入数据之前,我们需要判断数组的容量是否已经满,如果数组满了,再往数组里插入数据显然是不合逻辑的,因此需要对数组进行扩容
所以为了完成插入数据的接口,我们还需要准备一个检查容量判断是否扩容的接口

void CheckCapacity(SeqList* pq);
void CheckCapacity(SeqList* pq)
{
	if (pq->size == pq->capacity) //数组的有效数据个数达到容量大小时则表示数组已满
	{
        //满了则需要对数组扩容
		SLDatatype newa = (SLDatatype*)realloc(pq->a, sizeof(SLDatatype) * 2 * pq->capacity);
		if (newa == NULL)
		{
			printf("Realloc Failed\n");
			exit(-1);
		}
		pq->a = newa;
		pq->capacity *= 2;
	}
}

接下来完成数据插入接口,接口的参数需要结构体变量的地址,插入数据的位置以及插入数据的值

void SeqListPush(SeqList* pq, int pos, SLDatatype data);
void SeqListPush(SeqList* pq, int pos, SLDatatype data)
{
	assert(pq);
	assert(pos >= 0 && pos <= pq->size);
	CheckCapacity(pq);
	int end = 0;
	for (end = pq->size - 1; end >= pos; end--)
	{
		pq->a[end + 1] = pq->a[end];
	}
	pq->a[pos] = data;
	pq->size++;
}

此时可以对改接口进行测试了(测试过程略),为了方便测试,我们可以增加一个打印数组数据的接口以便于我们观察数组中的值

void SeqPrint(SeqList* pq);
void SeqPrint(SeqList* pq)
{
	for (int i = 0; i < pq->size; i++)
	{
		printf("%d ", pq->a[i]);
	}
	printf("\n");
}

②有了上面的任意位置插入的接口,我们可以通过该接口的复用来实现更简便的头插数据和尾插数据接口
头插数据:

void SeqListPushFront(SeqList* pq, SLDatatype data);
void SeqListPushFront(SeqList* pq, SLDatatype data)
{
	SeqListPush(pq, 0, data);
}

尾插数据:

void SeqListPushBack(SeqList* pq, SLDatatype data);
void SeqListPushBack(SeqList* pq, SLDatatype data)
{
	SeqListPush(pq, pq->size, data);
}

二、数据的删除
删除 pos 处数据的原理为:pos 后面的数据整体往前挪动一个空间,以覆盖掉pos处的值
完成删除接口时,我们需要考虑空数组的情况,因此我们需要先添加一个判空接口

bool SeqListIsEmpty(SeqList* pq);
bool SeqListIsEmpty(SeqList* pq)
{
	assert(pq);
	return pq->size == 0;  //如果数组为空,返回true,表示数组确实为空
}

完成删除接口

void SeqListPop(SeqList* pq, int pos);
void SeqListPop(SeqList* pq, int pos)
{
	assert(pq);
	assert(!SeqListIsEmpty(pq));
	int begin = 0;
	for (begin = pos; begin < pq->size-1; begin++)
	{
		pq->a[begin] = pq->a[begin + 1];
	}
	pq->size--;
}

和数据插入同理,可通过函数复用实现头删和尾删接口

//头删
void SeqListPopFront(SeqList* pq);
//尾删
void SeqListPopBack(SeqList* pq);

void SeqListPopFront(SeqList* pq)
{
	SeqListPop(pq, 0);
}

void SeqListPopBack(SeqList* pq)
{
	SeqListPop(pq, pq->size-1);
}

三、数据的修改

void SeqListModify(SeqList* pq,int pos,SLDatatype data);
void SeqListModify(SeqList* pq, int pos, SLDatatype data)
{
	assert(pq);
	assert(pos >= 0 && pos <= pq->size);
	pq->a[pos] = data;	
}

四、数据的查找

int SeqListSearch(SeqList* pq, SLDatatype data);
int SeqListSearch(SeqList* pq, SLDatatype data)
{
	assert(pq);
	for (int i = 0; i < pq->size; i++)
	{
		if (pq->a[i] == data)
		{
			return i;   //查找到则返回下标
		}
	} 
	return -1;   //为查找到则返回-1
}

至此顺序表的实现已经完成

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-04 11:50:13  更:2022-04-04 11:51:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:39:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码