【数据结构和算法】实现线性表中的静态、动态顺序表(上)

简介: 【数据结构和算法】实现线性表中的静态、动态顺序表

本文是数据结构的开篇,上文学习了关于使用C语言实现静态、动态、文件操作的通讯录,其中使用到了结构体这一类型,实际上,是可以属于数据结构的内容,接下来我们来了解一下顺序表的相关内容。

前言

数据结构是什么?

对于大家来说,这是一个全新的内容模块,数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法索引技术有关。

我们接下来是对于数据结构的顺序表的实现的讲解


一、线性表

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

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

实际上,学会了顺序表和链表,自然栈、队列、二叉树等各种结构就好学啦,又称顺序表和链表是数据结构的基础,是实现后序内容的基础。

一、顺序表是什么?

1.将表中元素一个接一个的存入一组连续的存储单元中,这种存储结构顺序结构

2.使用顺序结构存储的线性表叫做顺序表

总结:

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

二、分析顺序表的实现

顺序表,分为动态和静态两种顺序表,顺序表的实际操作功能大致为,增删改查,又细分为头尾增删,初始化、摧毁顺序表等操作。

我们接下来分别介绍静态和动态顺序表是如何实现的!!!

三、静态顺序表

使用结构体为:

1.顺序表初始化

如图所示:

代码演示:

//初始化函数
void InitSeqtable(Seqtable* st) {
  //for (int i = 0; i < MAX; i++) {
  //  st->date[i] = 0;//初始化为0  实际上可以不用初始化数组
  //}
  st->size = 0;
}

2.增加元素

分为头插入、尾插入

1.尾插

如图所示:

代码演示:

//尾插入
void BackSeqtable(Seqtable* st, int data) {
  //尾部插入的时候要进行判别是否为满
  if (st->size == MAX) {
    //表示满了
    perror("顺序表已经满员,无法插入新数据\n");
    exit(-1);//退出就可以
  }
  //没有满员,就加入数据即可
  st->date[st->size++] = data;
}

2.头插

如图所示:

代码如下:

//头插入
void FrontSeqtable(Seqtable* st, int data) {
  //一样先进行判断是否满员
  if (st->size == MAX) {
    perror("满员无法插入");
    exit(-1);
  }
  //头部插入。就是将原有数据向后移动一个位置
  int num = st->size - 1;
  for (int i = num; i>=0; i--) {
    st->date[i + 1] = st->date[i];
  }
  //while (num>=0) {
  //  st->date[num + 1] = st->date[num];
  //  num--;
  //}
  //最后插入数据
  st->date[0] = data;
  st->size++;
}

3.删除元素

分为头删、尾删

1.尾删

如图所示:

代码如下:

//尾删除
void SeqtablePopBack(Seqtable* st) {
  //尾删除,需要判断是否为空
  assert(st->size > 0);//断言判断
  st->size--;//直接元素个数减去一个就可以
}

2.头删

如图所示:

代码如下:

//头删除
void SeqtablePopFront(Seqtable* st) {
  //头部删除,也要判空
  assert(st->size > 0);//断言
  //将后面的数据覆盖前面的数据
  for (int i = 0; i < st->size-1; i++) {
    st->date[i] = st->date[i + 1];
  }
  st->size--;//size减去一个元素即可
}

4.改变数据和查找

想要改变指定下标的数据,输入要查找的元素,更改这个的数据,要先查找到对应坐标,简易的更改数值,不考虑重复的问题,从左向右的顺序查询

代码如下:

//查找
int SearchSeqtable(Seqtable* st) {
  assert(st->size > 0);//如果为空,不用查找,直接报错
  int num = 0;
  scanf("%d", &num);//输入查找的元素
  for (int i = 0; i < st->size; i++) {
    if (st->date[i] == num) {
      return i;//找到返回下标
    }
  }
  return -1;//没找到返回-1
}
void ChangeSeqtable(Seqtable* st) {
  int num=SearchSeqtable(st);//进入查找,返回下标
  if (num == -1) {
    printf("顺序表中没有该元素,无法修改\n");
    return;
  }
  int a = 0;
  scanf("%d", &a);//输入想要更改的数据
  st->date[num] = a;
}

5.打印和销毁顺序表

代码如下:

//摧毁顺序表
void SeqtableDestory(Seqtable* st) {
  //摧毁的话,静态表直接初始化为0
  st->size = 0;
}
//打印
void PrintSeqtable(Seqtable* st) {
  for (int i = 0; i < st->size; i++) {
    printf("%d ", st->date[i]);
  }
}

四、动态顺序表

动态顺序表和静态顺序表的差别就是结构体、初始化、摧毁顺序表、扩容

结构体如下:

//动态顺序表
typedef struct Seqtable {
  int* data;//数据域
  int size;//个数
  int capacity;//容量
}Seqtable;
//实际上动态顺序表和静态顺序表,只有在初始化、销毁、扩容的时候不一样

1.初始化

//初始化顺序表
void InitSeqtable(Seqtable* st) {
  st->size = st->capacity = 0;
  st->data = NULL;
}

2.扩容

如图所示:

代码演示:

//扩容
void Expansion(Seqtable* st) {
  //1.直接扩容二倍,这样防止后序一致扩容
  int newcapacity = st->capacity = 0 ? 4 : st->capacity * 2;
  int* tmp = (int*)realloc(st->data, newcapacity * sizeof(int));
  if (tmp == NULL) {
    //表示创建失败
    perror("realloc fail\n");
    exit(-1);
  }
  //创建成功  tmp给data
  st->data = tmp;
  st->capacity = newcapacity;
}

如图上,另外一种扩容方法,可以看这篇文章中动态通讯录扩容,里面有介绍(24条消息) 【C语言】使用C语言实现静态、动态的通讯录(简单易懂)_小王学代码的博客-CSDN博客

3.销毁顺序表

void SeqListDestory(Seqtable* ps) {
  free(ps->data);//直接释放a的空间 
  ps->data = NULL;//然后指向NULL
  ps->capacity = ps->size = 0;
}

除此之外,和静态顺序表都差不多一样了

相关文章
|
3月前
|
机器学习/深度学习 传感器 算法
【无人车路径跟踪】基于神经网络的数据驱动迭代学习控制(ILC)算法,用于具有未知模型和重复任务的非线性单输入单输出(SISO)离散时间系统的无人车的路径跟踪(Matlab代码实现)
【无人车路径跟踪】基于神经网络的数据驱动迭代学习控制(ILC)算法,用于具有未知模型和重复任务的非线性单输入单输出(SISO)离散时间系统的无人车的路径跟踪(Matlab代码实现)
244 2
|
4月前
|
传感器 算法 Python
【电机矢量控制算法】基于线性死区补偿的永磁同步电机矢量控制算法仿真
【电机矢量控制算法】基于线性死区补偿的永磁同步电机矢量控制算法仿真
129 3
|
4月前
|
机器学习/深度学习 人工智能 算法
【多智能体编队】基于自适应控制算法非线性输入的多智能体系统编队控制研究(Matlab代码复现)
【多智能体编队】基于自适应控制算法非线性输入的多智能体系统编队控制研究(Matlab代码复现)
142 0
|
4月前
|
机器学习/深度学习 算法 数据格式
MARS算法理论和Python代码实现:用分段回归解决非线性时间序列预测问题
本文将深入探讨MARS算法的核心原理,并详细阐述其在时间序列预测任务中的应用策略与技术实现。
270 0
|
8月前
|
存储 前端开发 Java
线性数据结构详解
本文介绍了线性数据结构中的核心概念——节点,以及基于节点构建的链表、队列和栈等重要数据结构。节点是计算机科学中基本的构建单元,包含数据和指向其他节点的链接。通过添加约束或行为,可以构建出单向链表、双向链表、队列和栈等复杂结构。
241 1
|
11月前
|
存储 算法 测试技术
【C++数据结构——线性表】求集合的并、交和差运算(头歌实践教学平台习题)【合集】
本任务要求编写程序求两个集合的并集、交集和差集。主要内容包括: 1. **单链表表示集合**:使用单链表存储集合元素,确保元素唯一且无序。 2. **求并集**:遍历两个集合,将所有不同元素加入新链表。 3. **求交集**:遍历集合A,检查元素是否在集合B中存在,若存在则加入结果链表。 4. **求差集**:遍历集合A,检查元素是否不在集合B中,若满足条件则加入结果链表。 通过C++代码实现上述操作,并提供测试用例验证结果。测试输入为两个集合的元素,输出为有序集合A、B,以及它们的并集、交集和差集。 示例测试输入: ``` a c e f a b d e h i ``` 预期输出:
342 7
|
11月前
|
机器学习/深度学习 存储 C++
【C++数据结构——线性表】单链表的基本运算(头歌实践教学平台习题)【合集】
本内容介绍了单链表的基本运算任务,涵盖线性表的基本概念、初始化、销毁、判定是否为空表、求长度、输出、求元素值、按元素值查找、插入和删除数据元素等操作。通过C++代码示例详细解释了顺序表和链表的实现方法,并提供了测试说明、通 - **任务描述**:实现单链表的基本运算。 - **相关知识**:包括线性表的概念、初始化、销毁、判断空表、求长度、输出、求元素值、查找、插入和删除等操作。 - **测试说明**:平台会对你编写的代码进行测试,提供测试输入和预期输出。 - **通关代码**:给出了完整的C++代码实现。 - **测试结果**:展示了测试通过后的预期输出结果。 开始你的任务吧,祝你成功!
555 5
|
11月前
|
机器学习/深度学习 存储 C++
【C++数据结构——线性表】顺序表的基本运算(头歌实践教学平台习题)【合集】
本文档介绍了线性表的基本运算任务,涵盖顺序表和链表的初始化、销毁、判定是否为空、求长度、输出、查找元素、插入和删除元素等内容。通过C++代码示例详细展示了每一步骤的具体实现方法,并提供了测试说明和通关代码。 主要内容包括: - **任务描述**:实现顺序表的基本运算。 - **相关知识**:介绍线性表的基本概念及操作,如初始化、销毁、判定是否为空表等。 - **具体操作**:详述顺序表和链表的初始化、求长度、输出、查找、插入和删除元素的方法,并附有代码示例。 - **测试说明**:提供测试输入和预期输出,确保代码正确性。 - **通关代码**:给出完整的C++代码实现,帮助完成任务。 文档
392 5
|
12月前
|
数据库
数据结构中二叉树,哈希表,顺序表,链表的比较补充
二叉搜索树,哈希表,顺序表,链表的特点的比较
数据结构中二叉树,哈希表,顺序表,链表的比较补充
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习之顺序表【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找等具体详解步骤以及举例说明

热门文章

最新文章