【数据结构】顺序表:随机访问的速度快到飞起

news/2024/12/4 23:35:17/

在这里插入图片描述

  • 👑专栏内容:数据结构
  • ⛪个人主页:子夜的星的主页
  • 💕座右铭:日拱一卒,功不唐捐

文章目录

  • 一、前言
  • 二、线性表
  • 三、顺序表
    • 1、定义
    • 2、静态顺序表
    • 3、动态顺序表
    • 4、接口实现
      • Ⅰ、初始化
      • Ⅱ、销毁
      • Ⅲ、增容
      • Ⅳ、插入
      • Ⅴ、删除
      • Ⅵ、查找
      • Ⅶ、打印
  • 四、总结
    • 1、分类
    • 2、特点
    • 3、缺陷


一、前言

前面介绍了如何分析一个算法的时间复杂度和空间复杂度,但那些都是数据结构学习的预备工作。而本文介绍的顺序表,则是数据结构中较为基础的类型。虽然基础,但也有它自己独有的特性,具体是那些特性,就让我们往下看吧。

在这里插入图片描述

二、线性表

再介绍顺序表之前,我们先认识一下线性表。

线性表,全名为线性存储结构。即 “ 把所有数据用一根线儿串起来,再存储到物理空间中 ”。如下图所示,既然线性表是排成像一条线一样的结构,那么每个线性表上的数据最多只有前和后两个方向。

顺序表、链表、栈、队列等都属于线性表中的一种。

在这里插入图片描述

而与线性表的概念相对应的是非线性表。
非线性表里的数据之间并不是一对一关系,而是一对多或多对多关系。

树、图、堆等都属于非线性表中的一种。

在这里插入图片描述

三、顺序表

1、定义

维基百科:顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构,使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系。

好吧,那就直接看定义里面的重点。
顺序表是用一段连续的存储单元依次存储数据元素的线性结构

在这里插入图片描述

2、静态顺序表

静态顺序表就是,使用定长数组存储元素。再简单点说,就是数组的容量是固定的,用完就没了。少了不够,多了浪费。

#define N 100   		 //(0)
typedef int SLDataType;  //(1)
typedef struct SeqList   
{SLDataType arr[N];	 //(2)size_t size;		 //(3)
}SeqList;				 //(4)

(0)规定N等于100
(1)重新定义int类型名为SLDataType(便于后面修改类型)
(2)静态数组来保存顺序表中的元素,一共N个位置(最多存入N个元素)
(3)顺序表当前长度
(4)定义SeqList代表这个结构体类型名

3、动态顺序表

动态顺序表,是先开辟一块小空间,然后利用realloc函数或malloc函数按需开辟空间,空间不够了,就开辟,多了就不开辟。

typedef int SLDataType;
typedef struct SeqList
{SLDataType* array;//(0)size_t size;	  //(1)size_t capicity;  //(2)
}SeqList;

(0)指向动态开辟的数组
(1)顺序表当前长度
(2)容量空间的大小

在这里插入图片描述
额…那是因为开辟空间的接口函数还都没写呢。

4、接口实现

静态顺序表只适用于确定知道需要存多少数据的场景。
静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。
所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以下面我们实现动态顺序表的各种接口。

typedef int SLDataType;
typedef struct SeqList
{SLDataType* array;size_t size;	 size_t capicity;  
}SeqList;

Ⅰ、初始化

初始化的目的就是清理内存中可能遗留的“脏数据”。

void SeqListInit(SeqList* psl)
{assert(psl);//断言防止其为空指针psl->array=NULL;//讲该指针置空psl->size = 0;//设置有效数据个数为0psl->capacity = 0;//设置空间容量为0
}

assert函数的作用就是:求表达式的值,当结果为假时,打印诊断消息并中止程序。它的作用就像是下面这个if函数。

if(假设成立)
{程序正常运行;
}
else
{报错&&终止程序!(避免由程序运行引起更大的错误)  
}

Ⅱ、销毁

void SeqListDestory(SeqList* psl)
{assert(psl);//释放动态开辟的空间if (psl->array){free(psl->array);psl->array = NULL;psl->capacity = 0;psl->size = 0;}
}

Ⅲ、增容

利用realloc函数或者malloc函数给一个表增容,最先做的就是先检查顺序表内元素个数是否已达顺序表容量上限。若已达上限,那么我们就需要先对顺序表进行扩容,然后才能增加数据。

void SeqListCheckCapacity(SeqList* psl)
{assert(psl);if (psl->size == psl->capacity){int newCapacity = psl->capacity == 0 ? 4 : psl->capacity * 2;SeqListDataType* tmp = (SeqListDataType*)realloc(psl->array, newCapacity * sizeof(SeqListDataType));if (tmp == NULL){perror("realloc fail");exit(-1);}psl->array = tmp;psl->capacity = newCapacity;}
}

在这里插入图片描述

Ⅳ、插入

因为顺序表中每个数据元素在内存中是连续存储的,所以如果要在某个位置插入一个元素,则需要把原来该位置的元素依次向后移动。
在这里插入图片描述

  • 头插
void SeqListPushFront(SeqList* psl, SeqListDataType x)
{assert(psl);SeqListCheckCapacity(psl);int end = psl->size - 1;while (end >= 0){psl->array[end + 1] = psl->array[end];end--;}//或者用for循环//	for (int i = psl->size - 1; i >= 0; i--)  //顺序表中[0,size-1]的元素依次向后挪动一位//{//	psl->array[i + 1] = psl->array[i];//}psl->array[0] = x;psl->size++;
}
  • 中间插
void SeqListInsert(SeqList* psl, int pos, SeqListDataType x)
{assert(psl);assert(pos >= 0);assert(pos <= psl ->size);SeqListCheckCapacity(psl);int end = psl->size - 1;while (end >= pos){psl->array[end + 1] = psl->array[end];end--;}psl->array[pos] = x;psl->size++;
}
  • 尾插
void SeqListPushBack(SeqList* psl, SeqListDataType x)
{assert(psl);SLCheckCapacity(psl);psl->array[psl->size] = x;psl->size++;
}

在这里插入图片描述

  • 中插改头插
void SeqListPushFront(SeqList* psl, SeqListDataType x)
{SeqListInsert(psl, 0, x);
}
  • 中插改尾插
void SeqListPushBack(SeqList*psl,SeqListDataType X)
{SLInsert(psl, ps->size, x);
}

Ⅴ、删除

因为顺序表中每个数据元素在内存中是连续存储的,所以如果删除某个位置的元素,则需要依次把该位置后面的元素依次向前移动。
在这里插入图片描述

  • 头删
void SeqListPopFront(SeqList* psl)
{assert(psl);  //断言assert(psl->size>0);//防止数据为0时还删数据assert(psl->size > 0);  //顺序表不能为空int begin = 1;while(begin<ps->size){psl->array[begin-1]=psl->array[begin];begin++;}
//	int i = 0;
//	for (i = 1; i < psl->size; i++)  //顺序表中[1,size-1]的元素依次向前挪动一位
//	{
//		psl->array[i - 1] = psl->array[i];
//	}psl->size--;  //有效数据个数-1
}
  • 中删
void SeqListErase(SeqList* psl, int pos)
{assert(psl);assert(pos >= 0);assert(pos < psl->size);int begin = pos + 1;while (begin < psl->size){psl->array[begin - 1] = psl->array[begin];begin++;}psl->size--;
}
  • 尾删
void SeqListPopBack(SeqList* psl)
{assert(ps);assert(ps->size > 0);psl->array[ps->size - 1] = 0;psl->size--;
}

在这里插入图片描述

  • 中删改头删
void SeqListPopFront(SeqList* psl)
{SeqListErase(psl, 0);//直接调用
}
  • 中删改尾删
void SeqListPopBack(SeqList*psl)
{SeqListErase(psl, psl->size-1);//直接调用
}

Ⅵ、查找

int SeqListFind(SeqList* psl, SeqListDataType x, int begin)
{assert(psl);for (int i = begin; i < psl->size; i++) //遍历顺序表{if (ps->array[i] == x){return i; //找到了返回下表}}return -1; //没找到
}

Ⅶ、打印

void SeqListPrint(SeqList* psl)
{assert(psl);if (psl->size == 0){printf("空表");return;}for (int i = 0; i < psl->size; i++){printf("%d ", psl->array[i]);}printf("\n");
}

四、总结

顺序表的实际应用:C语言顺序表实现学生管理系统

在这里插入图片描述

1、分类

顺序表是线性表中的一种,顺序表可以分为:
1.静态顺序表:使用定长数组存储元素。
2.动态顺序表:使用动态开辟的数组存储。

2、特点

顺序表的特点:
①随机访问,即可以在 O(1) 时间内找到第 i 个元素。(访问速度极快)
②存储密度高,每个节点只存储数据元素
③拓展容量不方便(即便采用动态分配的方式实现,拓展长度的时间复杂度也比较高)
④插入、删除操作不方便,需要移动大量元素

3、缺陷

1.空间不够,需要扩容。扩容是有代价的,并且会存在空间浪费。
2.头部或者中部的插入删除,需要挪动数据,效率低。

在这里插入图片描述


http://www.ppmy.cn/news/26235.html

相关文章

Debian/Ubuntu 安装和使用 perf 调试工具

为操作系统安装基本依赖环境&#xff1a;apt-get update -y apt-get upgrade -y apt-get install lrzsz zip unzip libkrb5-dev libicu-dev screen iftop openssl libssl-dev libunwind8 iftop net-tools gcc gdb cmake curl wget -y apt-get install gcc gdb cmake python-dev…

算法笔记(九)—— 暴力递归

暴力递归&#xff08;尝试&#xff09; 1. 将问题转化为规模缩小了的同类问题子问题 2. 有明确的不需要的继续递归的条件 3. 有当得到子问题结果之后的决策过程 4. 不记录每一个子问题的解 Question&#xff1a;经典汉诺塔问题 1. 理解清楚&#xff0c;基础三个圆盘的移动…

产品经理知识体系:5.如何做好产品数据分析?

数据分析 思考 笔记 数据分析 思路 基于用户路径&#xff1a;用户的活动路径&#xff0c;操作流程等行为数据。 基于产品节点&#xff1a;转化率、占比 分析类型 先定性&#xff1a;先抛出问题、提出假设 再定量&#xff1a;数据验证问题、验证假设 先定性、再定量、最后得…

linux xargs 删除名字中包含某字符串的文件

xargs的作用 格式化输出 可以把多行文本变成一行&#xff0c;或者指定行数和列数。每一列用空格作分隔符号。 test.txt中的内容 例子1&#xff1a; 用xargs格式化输出后,多行变成了一行&#xff0c;而且多个空格变成了一个空格。 cat test|xargs例子2&#xff1a; 当然也可…

「可信计算」助力TLS 传输更安全

序言背景&#xff08;Satuation&#xff09;&#xff1a;TLS 是 TCP/IP 上的传输层安全协议&#xff0c;保护着数以亿万级的数据安全&#xff0c;我们在浏览器中输入的 https&#xff0c;就是受到 TLS 保护的。冲突&#xff08;complication&#xff09;&#xff1a;从可信计算…

并查集(高级数据结构)-蓝桥杯

一、并查集并查集(Disioint Set)&#xff1a;一种非常精巧而实用的数据结构用于处理不相交集合的合并问题。用于处理不相交集合的合并问题。经典应用&#xff1a;连通子图。最小生成树Kruskal算法。最近公共祖先。二、应用场景有n个人&#xff0c;他们属于不同的帮派。 已知这些…

sql语句 两值对比返回true 或者false 关于程序的题目

解法一: create table DemoTable (FirstName varchar(100),LastName varchar(100) );insert into DemoTable values(Chris,Brown);insert into DemoTable values(David,Miller);insert into DemoTable values(Adam,Smith); 查询判断返回相关内容 select if(LastName=Miller…

超详细讲解文件函数

超详细讲解文件函数&#xff01;&#xff01;&#xff01;&#xff01;字符输入/输出函数fgetcfputc文本行输入/输出函数fgetsfputs格式化输入/输出函数fscanffprintf二进制输入/输出函数freadfwrite打开/关闭文件函数fopenfclose字符输入/输出函数 fgetc fgetc函数可以从指定…