广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++ 数据结构超详细讲解顺序表
  • 398
分享到

C++ 数据结构超详细讲解顺序表

2024-04-02 19:04:59 398人浏览 独家记忆
摘要

目录前言一、顺序表是什么概念及结构二、顺序表的实现顺序表的缺点几道练手题总结(●’◡’●) 前言 线性表是n个具有相同特性的数据元素的有限序列。线性表是一种

(●’◡’●)

前言

线性表是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串

线性表在逻辑上是线性结构,也就是说连续的一条直线,但是在物理结构并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。

本章我们来深度初体验顺序表

一、顺序表是什么

概念及结构

顺序表是一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。

1.静态顺序表:使用定长数组存储元素

2.动态顺序表:使用动态开辟的数组存储

二、顺序表的实现

基本结构

typedef int SLDataType;
// 顺序表的动态存储
typedef struct SeqList
{
SLDataType* array; // 指向动态开辟的数组
size_t size ; // 有效数据个数
size_t capicity ; // 容量空间的大小
}SeqList;

接口实现

静态顺序表只适用于确定知道需要多少数剧的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以我们基本使用动态顺序表

typedef int SLDataType;
// 顺序表的动态存储
typedef struct SeqList
{
SLDataType* array; // 指向动态开辟的数组
size_t size ; // 有效数据个数
size_t capicity ; // 容量空间的大小
}SeqList;
// 基本增删查改接口
// 顺序表初始化
void SeqListInit(SeqList* psl, size_t capacity);
// 检查空间,如果满了,进行增容
void CheckCapacity(SeqList* psl);
// 顺序表尾插
void SeqListPushBack(SeqList* psl, SLDataType x);
// 顺序表尾删
void SeqListPopBack(SeqList* psl);
// 顺序表头插
void SeqListPushFront(SeqList* psl, SLDataType x);
// 顺序表头删
void SeqListPopFront(SeqList* psl);
// 顺序表查找
int SeqListFind(SeqList* psl, SLDataType x);
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* psl, size_t pos);
// 顺序表销毁
void SeqListDestory(SeqList* psl);
// 顺序表打印
void SeqListPrint(SeqList* psl);

顺序表打印

普通的通过链表的数组打印

void SeqListPrint(SeqList* ps1)
{
	assert(ps1);

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

顺序表初始化

置空

void SeqListInit(SeqList* ps1)
{
	assert(ps1);
	ps1->a = NULL;
	ps1->size = 0;
	ps1->capacity = 0;
}

顺序表销毁

顺序表本质是数组,是一片连续的存储空间,头部操作置空即可

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

动态扩容

由于是动态顺序表,就是为了控制长度来解决问题,对顺序表的操作大多离不开扩容

由于顺序表是连续的如果使用malloc会出现异地扩容的现象,realloc虽然也存在异地扩,但会返回一片连续空间的首地址.

void SeqListCheckCapacity(SeqList* ps1)
{
	assert(ps1);
	if (ps1->size == ps1->capacity)//满了
	{
		size_t newCapacity = ps1->capacity == 0 ? 4 : ps1->capacity * 2;//两倍扩容
		SLDateType* tmp = realloc(ps1->a, sizeof(SLDateType) * newCapacity);
		if (tmp == NULL)//扩容失败
		{
			printf("realloc fail\n");
			exit(-1);
		}
		else//扩容成功
		{
			ps1->a = tmp;
			ps1->capacity = newCapacity;
		}
	}
}

在pos位置插入x

对头插尾插帮助极大

要判断是否可以插入以及有没有必要插入

过程图示

void SeqListInsert(SeqList* ps1, size_t pos, SLDateType x)
{
	if (pos > ps1->size)//如图
	{
		printf("越界:pos %d\n", pos);
		return;
	}
	SeqListCheckCapacity(ps1);//插入即要扩容
	size_t end = ps1->size;
	while (end > pos)
	{
		ps1->a[end] = ps1->a[end - 1];//数据后挪,腾出空间
		--end;
	}
	//end=pos
	ps1->a[pos] = x;
	ps1->size++;//添加数据,需要增长
}

删除pos位置

对头删尾删帮助极大

//注意,顺序表只注意size以前,size以后无硬性要求可以宽容对待

void SeqListErase(SeqList* ps1, size_t pos)
{
	assert(ps1);
	assert(pos < ps1->size);//同插入,需要有东西可删

	size_t begin = pos + 1;
	while (begin < ps1->size)//由后向前覆盖
	{
		ps1->a[begin - 1] = ps1->a[begin];
		++begin;
	}
	ps1->size--;
}

顺序表尾插

相当于上文在size处插入数据,调用即可

void SeqListPushBack(SeqList* ps1, SLDateType x)
{
	assert(ps1);
	SeqListInsert(ps1, ps1->size, x);
}

顺序表尾删

注意辨别size的位置

void SeqListPopBack(SeqList* ps1)
{
	assert(ps1);
	SeqListErase(ps1, ps1->size-1);
}

顺序表头插

void SeqListPushFront(SeqList* ps1, SLDateType x)
{
	assert(ps1);
	SeqListInsert(ps1, 0, x);
}

顺序表头删

//只需考虑size有效数据前

void SeqListPopFront(SeqList* ps1)
{
	assert(ps1);
	SeqListErase(ps1, 0);
}

查找数据x

int SeqListFind(SeqList* ps1, SLDateType x)
{
	assert(ps1);
	for (int i = 0; i < ps1->size; ++i)
	{
		if (ps1->a[i] == x)
		{
			return i;//返回下标
		}
	}
	return -1;//没找到
}


顺序表的缺点

1. 中间/头部的插入删除,时间复杂度为O(N)
2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
3. 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间

由此,前辈们总结出了链表

几道练手题

原地移除数组中所有的元素val,要求时间复杂度为O(N),空间复杂度为O(1)。题目链接

删除排序数组中的重复项。链接

合并两个有序数组.题目链接

总结

学习编程,解决问题,数据结构与算法正是非常好的工具。模拟实现正是对自身代码能力的锻炼提升,也对其有了更深的理解.竞赛的话,我认为要先对知识进行系统深度的学习,才可随机应变。不可盲目刷题,有些深层原理可能与做题所理解出的出入极大。

到此这篇关于c++ 数据结构超详细讲解顺序表的文章就介绍到这了,更多相关C++ 顺序表内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C++ 数据结构超详细讲解顺序表

本文链接: https://www.lsjlt.com/news/143882.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++ 数据结构超详细讲解顺序表
    目录前言一、顺序表是什么概念及结构二、顺序表的实现顺序表的缺点几道练手题总结(●’◡’●) 前言 线性表是n个具有相同特性的数据元素的有限序列。线性表是一种...
    99+
    2022-11-13
  • Java数据结构顺序表的详细讲解
    目录写在前面1.线性表2.顺序表的实现2.1增加数据2.1.1尾部增加数据2.1.2任意位置增加数据2.2查找数据2.3删除数据2.4修改数据3.ArrayList3.1ArrayL...
    99+
    2022-11-13
  • C++ 数据结构超详细讲解单链表
    目录前言一、链表是什么链表的分类二、链表的实现总结(❁´◡`❁) 单链表 前言 上篇顺序表结尾了解了顺序表的诸多缺点,链表的特性很好的解决了这些问题,本期我们来认识单链表...
    99+
    2022-11-13
  • C语言数据结构超详细讲解单向链表
    目录1.链表概况1.1 链表的概念及结构1.2 链表的分类2. 单向链表的实现2.1 SList.h(头文件的汇总,函数的声明)2.2 SList.c(函数的具体实现逻辑)2.2.1...
    99+
    2022-11-13
  • C++primer超详细讲解顺序容器
    目录顺序容器概述容器库概览迭代器容器定义和初始化赋值和swap顺序容器操作向顺序容器添加元素访问元素删除元素特殊的forwa_list单向链表操作改变容器大小vector对象是如何增...
    99+
    2022-11-13
  • C语言超详细讲解数据结构中的线性表
    目录前言一、分文件编写1、分文件编写概念2、代码展示二、动态分布内存malloc1、初识malloc2、使用方法三、创建链表并进行增删操作1、初始化链表2、在链表中增加数据3、删除链...
    99+
    2022-11-13
  • C语言数据结构顺序表的进阶讲解
    目录前言一、顺序表的构造VS功能1.顺序表的构造2.接口实现(功能)二、功能具体分析1.初始化2.销毁3.检查size与capacity是否溢出4.尾增功能(实现)5.打印三、实现具...
    99+
    2022-11-13
  • C++实现数据结构的顺序表详解
    目录前言:代码1.SeqList.h2.SeqList.cpp3.test.cpp总结 前言: hello,大家好,这篇文章博主来分享一下C++实现数据结构中的顺序表的代码。希望对大...
    99+
    2022-11-12
  • C语言超详细讲解顺序表的各种操作
    目录顺序表是什么顺序表的结构体顺序表的接口函数顺序表相关操作的菜单顺序表的初始化添加元素陈列元素往最后加元素往前面加元素任意位置加元素删除最后元素删除前面元素 删除任意元素...
    99+
    2022-11-13
  • C语言结构体超详细讲解
    目录前言1、结构体的声明1.1 结构的基础知识1.2 结构的声明1.3 结构成员的类型1.4 结构体变量的定义和初始化2、结构体成员的访问2.1 点操作符访问2.2 ->操作符...
    99+
    2022-11-13
  • C++超详细分析顺序表
    本次我们解剖顺序表将从以下三个结构: 1、静态顺序表和动态顺序表 2、顺序表实现增删查改等常见接口 3、顺序表相关OJ题练习 什么是顺序表 顺序表是用一段物理地址连续的存储单元依次存...
    99+
    2022-11-13
  • C++详细讲解对象的构造顺序
    目录一、局部对象的构造顺序二、堆对象的构造顺序三、全局对象的构造顺序命令行四、小结一、局部对象的构造顺序 对于局部对象 当程序执行流到达对象的定义语句时进行构造 下面看一个局部对象的...
    99+
    2022-11-13
  • C语言 struct结构体超详细讲解
    目录一、本章重点二、创建结构体三、typedef与结构体的渊源四、匿名结构体五、结构体大小六、结构体指针七、其他一、本章重点 创建结构体typedef与结构体的渊源匿名结构体结构体大...
    99+
    2022-11-13
  • C++超详细讲解析构函数
    目录特性析构函数处理自定义类型编译器生成的默认析构函数特性 析构函数是特殊的成员函数 特征如下: 析构函数名是~类名;无参数无返回值;一个类有且只有一个析构函数;对象声明周期结束,编...
    99+
    2022-11-13
  • C++超详细讲解构造函数
    目录类的6个默认成员函数构造函数特性编译器生成的默认构造函数成员变量的命名风格类的6个默认成员函数 如果我们写了一个类,这个类我们只写了成员变量没有定义成员函数,那么这个类中就没有函...
    99+
    2022-11-13
  • Java超详细讲解ArrayList与顺序表的用法
    目录简要介绍Arraylist容器类的使用Arraylist容器类的构造ArrayList的常见方法ArrayList的遍历ArrayList中的扩容机制简要介绍 顺序表是一段物理地...
    99+
    2022-11-13
  • Java超详细讲解数据结构的应用
    目录一.bfs二.双端队列三.算法题1.kotori和迷宫2.小红找红点3.小红玩数组 一.bfs bfs(广度优先搜索),类似二叉树的层序遍历,利用队列完成。一般用于求最短路。 图...
    99+
    2022-11-13
  • C语言超详细讲解数据结构中双向带头循环链表
    目录一、概念二、必备工作2.1、创建双向链表结构2.2、初始化链表2.3、动态申请节点2.4、打印链表2.5、销毁链表三、主要功能3.1、在pos节点前插入数据尾插头插3.2、删除p...
    99+
    2022-11-13
  • Java数据结构顺序表用法详解
    目录1.什么是顺序表2.顺序表的基本功能和结构3.顺序表基本功能的实现和解析1.判断线性表是否为空2.获取指定位置的元素3.向线性表表添加元素4.在位置i处插入元素5.删除指定位置的...
    99+
    2022-11-12
  • C语言线性表中顺序表超详细理解
    目录一、本章重点二、线性表三、顺序表四、静态顺序表接口实现4.1顺序表初始化4.2顺序表打印4.3顺序表尾插4.4顺序表尾删4.5顺序表头插4.6顺序表头删4.7顺序表任意位置插入4...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作