首页 > 其他分享 >顺序表的基本操作以应用

顺序表的基本操作以应用

时间:2024-10-31 12:47:12浏览次数:10  
标签:顺序 线性表 元素 length L3 SqList 基本操作 data 应用

顺序表的基本操作

任务描述
本关任务:要求针对顺序存储的线性表完成四个操作函数,分别实现线性表中数据的插入、删除与查找等功能。

相关知识
为了完成本关任务,你需要掌握:顺序表的基本操作。

顺序表的基本操作
线性表是最基本、最简单、也是最常用的一种数据结构。线性表结构中,数据元素之间通过一对一首尾相接的方式连接起来。具体实现时,线性表可以采用不同的存储策略。下面给出了两种基于顺序存储的线性表实现方案:

 图 1:静态数组数组实现
 图 2:动态数组数组实现
本任务关卡采用第二种动态数组将线性表存储在一片连续空间里,并通过 elem 以及 length 这两个属性元素。组织成为一个结构:

elem: 给出线性表存储空间的起始地址
length: 保存线性表中最后一个元素所在的位置
为了讨论简化,我们假设每个数据元素是一个整数:

typedef int ElementType;// 数据元素的数据类型
该线性表的结构定义如下:

typedef struct LNode {
    ElementType *elem;
    int length;  /* 保存线性表中数据元素个数 */
} SqList;
程序中使用到的常量:

#define MAXSIZE 100 /* MAXSIZE,指明线性表存储空间最多可存储的数据元素个数 */
#define ERROR 0 
对数据元素进行操作处理是一个数据结构的重要组成部分。线性表涉及的主要操作如下:

创建线性表:创建一个最多可存储 MAXSIZE 个数据元素的顺序存储的线性表,并将其初始状态设置为 length=0。如果申请存储空间失败返回 false,否则返回 true;该操作函数具体定义如下,其返回值为 bool 型:
bool MakeEmpty(SqList &L);

释放线性表存储空间:释放 L.elem 所指向的用于存储线性表数据元素的存储空间。该操作函数具体定义如下:
void Free(SqList &L)

判断线性表是否为空:若当前线性表是空表,则返回 true,否则返回 false。该操作函数具体定义如下:
bool IsEmpty(SqList &L)

判断线性表是否已满:若线性表达到最大长度,则返回 true,否则返回 false。该操作函数具体定义如下:
bool IsFull(SqList &L)

在线性表位置 P 插入数据元素 x: 将 X 插入在位置 P(1≤P≤L.legnth) 并返回true。若空间已满,则打印 FULL 并返回 false;如果参数 P 指向非法位置,则打印 ILLEGAL POSITION 并返回 false;该操作函数具体定义如下:
bool Insert( SqList &L, ElementType X, int P )

删除线性表位置 P 处的数据元素: 删除线性表第 P 个数据元素。将位置 P P(1≤P≤L.length) 的元素删除并返回 true。若参数 P 指向非法位置,则打印 POSITION P EMPTY(其中 P 是参数值)并返回 false。该操作函数具体定义如下:
bool Delete( SqList &L, int P )

查找线性表中第一个值为 x 的数据元素的位置: 找到线性表中第一个值为 x 的数据元素所在下标。若找不到则返回 ERROR。该操作函数具体定义如下:
int Find( SqList L, ElementType X )

删除线性表中第一个值为 x 的数据元素: 删除第一个值为 x 的数据元素,返回该数据元素所在位置 [1,L.length]。如果不存在值为 x 的数据元素,则打印“FINDING ERROR X”(其中 X 是参数值)则返回 ERROR。该操作函数具体定义如下: 
int DelValue(SqList &L, ElementType X)

打印线性表: 打印整个线性表。该操作函数具体定义如下:
void Print(SqList &L)

编程要求
根据提示,在右侧编辑器代码文件中的 Begin-End 区间内补充代码,实现 step1/Seqlist.h 中的 Insert、Delete、DelValue 和 Find 四个操作函数,以实现线性表中数据的插入、删除与查找等功能。具体要求如下:

Insert 函数:在线性表位置 P 插入数据元素 x, 将X插入在位置 P(1≤P≤L.length+1) 并返回 true。若空间已满,则打印 FULL 并返回false;如果参数 P 指向非法位置,则打印 ILLEGAL POSITION 并返回 false;

Delete 函数:删除线性表位置 P 处的数据元素,删除线性表第 P 个数据元素。将位置 P P(1≤P≤L.length) 的元素删除并返回 true。若参数 P 指向非法位置,则打印 POSITION P EMPTY(其中 P 是参数值)并返回 false。

Find 函数:查找线性表中第一个值为 x 的数据元素的位置,找到线性表中第一个值为 x 的数据元素所在下标。若找不到则返回 ERROR。

DelValue 函数:删除线性表中第一个值为 x 的数据元素: 删除第一个值为 x 的数据元素,返回该数据元素所在位置 [1,L.length]。如果不存在值为 x 的数据元素,则打印“ FINDING ERROR X ”(其中 X 是参数值)则返回 ERROR。

#include <iostream>
using namespace std;

#define MAXSIZE 100
#define ERROR 0

typedef int ElementType;
typedef struct LNode {
	ElementType *elem;
	int length;  /* 保存线性表中数据元素个数 */
} SqList;

/*顺序表的初始化*/
bool MakeEmpty(SqList &L);
/*释放线性表存储空间:*/
void Free(SqList &L) ;
/* 判断线性表是否为空 */
bool IsEmpty(SqList &L);
/* 判断线性表是否已满*/
bool IsFull(SqList &L);
/* 打印线性表*/
void Print(SqList &L);
/*返回线性表中X第一次出现的位置*/
int Find( SqList L, ElementType X );
/*将X插入在位置P(1≤P≤L.length+1)*/
bool Insert( SqList &L, ElementType X, int P );
/* 删除线性表中第一个值为`x`的数据元素 */
int DeleteValue(SqList &L, ElementType X);
/*将位置P(1≤P≤L.length的元素删除*/
bool Delete( SqList &L, int P ) ;



/*返回线性表中X第一次出现的位置,从1开始。若找不到则返回ERROR;*/
int Find( SqList L, ElementType X ) {

	// 请在这里补充代码,完成本关任务
    /********** Begin *********/
for (int i = 0; i < L.length; i++) {
        if (L.elem[i] == X) {
            return i + 1; // 数组索引从0开始,位置从1开始
        }
    }
    return ERROR;

    /********** End **********/
}
/*将X插入在位置P((1≤P≤L.length+1))并返回true。若空间已满,则打印“FULL”并返回false;
如果参数P指向非法位置,则打印“ILLEGAL POSITION”并返回false;*/
bool Insert( SqList &L, ElementType X, int P ) {
	// 请在这里补充代码,完成本关任务
    /********** Begin *********/
  if (IsFull(L)) {
        cout << "FULL" ;
        return false;
    }
    if (P < 1 || P > L.length + 1) {
        cout << "ILLEGAL POSITION" ;
        return false;
    }
    for (int i = L.length; i >= P; i--) {
        L.elem[i] = L.elem[i - 1];
    }
    L.elem[P - 1] = X;
    L.length++;
    return true;

    /********** End **********/
}
/*将位置P((1≤P≤L.length)的元素删除并返回true。若顺序表是空的,则打印“LIST EMPTY” ,并返回false;
若参数P指向非法位置,则打印“POSITION P EMPTY”(其中P是参数值)并返回false。*/
bool Delete( SqList &L, int P ) {
	// 请在这里补充代码,完成本关任务
    /********** Begin *********/
if (IsEmpty(L)) {
        cout << "LIST EMPTY" ;
        return false;
    }
    if (P < 1 || P > L.length) {
        cout << "POSITION " << P << " EMPTY" ;
        return false;
    }
    for (int i = P; i < L.length; i++) {
        L.elem[i - 1] = L.elem[i];
    }
    L.length--;
    return true;

    /********** End **********/
}
/* 删除线性表中第一个值为`x`的数据元素: 删除第一个值为`x`的数据元素,
返回该数据元素所在位置`[1,L.length]`。如果不存在值为`x`的数据元素,则打印“FINDING ERROR X”(其中X是参数值)则返回`ERROR`。*/


int DeleteValue(SqList &L, ElementType X){	
	// 请在这里补充代码,完成本关任务
    /********** Begin *********/
int pos = Find(L, X);
    if (pos == ERROR) {
        cout << "FINDING ERROR " << X;
        return ERROR;
    }
    Delete(L, pos);
    return pos;

    /********** End **********/
}

两个有序顺序表的归并(不含重复元素)

任务描述
本关任务:已知顺序表 L1,L2 中数据由小到大有序,请用尽可能快的方法将 L1 与 L2 中的数据合并到 L3 中,使数据在 L3 中按升序排列。

注意:本关必读中提及的其他操作已经由平台实现,你只要实现本关任务的 Merge 函数即可。

相关知识
为了完成本关任务,你需要掌握:就地归并两个有序顺序表。

就地归并两个有序顺序表
该方案将线性表存储在一片连续空间里,并通过 data 以及 length 这两个属性元素。组织成为一个结构:

data: 给出线性表存储空间的起始地址
length: 保存线性表中数据元素的个数
为了讨论简化,我们假设每个数据元素是一个整数:

typedef int ElementType;// 数据元素的数据类型
该线性表的结构定义如下:
typedef struct LNode {
    ElementType *data;
    int length; /* 保存线性表中数据元素的个数 */
} SqList;
程序中使用到的常量:
#define MAXSIZE 100 /* MAXSIZE,指明线性表存储空间最多可存储的数据元素个数 */
以下三个函数程序中已经给出,不需要读者完成:
//顺序表初始化
bool MakeEmpty(SqList &L);
//整体建立有序顺序表
void CreateList(SqList &L) ;
//输出顺序表
void Print(SqList L) ;
本关涉及的代码文件 merge.h 中作函数的代码框架如下:
/* 实现将从小到大有序顺序表L1和L2中的数据合并到L3中,使数据在L3中按升序排列,
并不含重复元素。(其中L1和L2是严格地递增)*/
void Merge(SqList L1,SqList L2,SqList &L3) {
    // 请在这里补充代码,完成本关任务
    /********** Begin *********/
    /********** End **********/
}
注意:

已有的两个有序表顺序存储方式进行存储;
归并以后不允许表中有重复元素;
异地归并。
编程要求
根据提示,在右侧编辑器代码文件中的 Begin-End 区间内补充代码,完成函数:
void Merge(SqList L1,SqList L2,SqList &L3)
 Merge 函数:实现将从小到大有序顺序表 L1 和 L2 中的数据合并到 L3 中,使数据在 L3 中按升序排列,并不含重复元素。(其中 L1 和 L2 是严格地递增)。

 

#include <iostream>
using namespace std;
#define MAXSIZE 50000
typedef int ElementType;
typedef struct LNode {
	ElementType *data;
	int length; /* 保存线性表中数据元素的个数 */
} SqList;



/* 实现将从小到大有序顺序表L1和L2中的数据合并到L3中,使数据在L3中按升序排列,
并不含重复元素。(其中L1和L2是严格地递增)*/
void Merge(SqList L1,SqList L2,SqList &L3) {
	// 请在这里补充代码,完成本关任务
    /********** Begin *********/
// 初始化L3
    L3.data = new ElementType[MAXSIZE];
    L3.length = 0;
    
    int i = 0, j = 0, k = 0; // i, j分别是L1和L2的索引,k是L3的索引
    
    // 遍历L1和L2,将较小的元素添加到L3中
    while (i < L1.length && j < L2.length) {
        if (L1.data[i] < L2.data[j]) {
            if (k == 0 || L1.data[i] != L3.data[k - 1]) { // 检查是否重复
                L3.data[k++] = L1.data[i];
            }
            i++;
        } else if (L1.data[i] > L2.data[j]) {
            if (k == 0 || L2.data[j] != L3.data[k - 1]) { // 检查是否重复
                L3.data[k++] = L2.data[j];
            }
            j++;
        } else { // L1.data[i] == L2.data[j]
            if (k == 0 || L1.data[i] != L3.data[k - 1]) { // 检查是否重复
                L3.data[k++] = L1.data[i];
            }
            i++;
            j++;
        }
    }
    
    // 将L1剩余的元素添加到L3中
    while (i < L1.length) {
        if (k == 0 || L1.data[i] != L3.data[k - 1]) { // 检查是否重复
            L3.data[k++] = L1.data[i];
        }
        i++;
    }
    
    // 将L2剩余的元素添加到L3中
    while (j < L2.length) {
        if (k == 0 || L2.data[j] != L3.data[k - 1]) { // 检查是否重复
            L3.data[k++] = L2.data[j];
        }
        j++;
    }
    
    // 设置L3的长度
    L3.length = k;

    /********** End **********/
}

标签:顺序,线性表,元素,length,L3,SqList,基本操作,data,应用
From: https://blog.csdn.net/lightfuturezyx99/article/details/143376468

相关文章

  • Nuxt.js 应用中的 components:dirs 事件钩子详解
    title:Nuxt.js应用中的components:dirs事件钩子详解date:2024/10/31updated:2024/10/31author:cmdragonexcerpt:components:dirs是Nuxt.js中的一个生命周期钩子,用于在app:resolve期间扩展自动导入组件的目录。通过这个钩子,开发者可以动态地添加新的组件......
  • Spring Boot应用MongoDB
    1.添加Maven依赖在SpringBoot项目中,引入spring-boot-starter-data-mongodb依赖:<dependencies><!--MongoDBstarterdependencyforSpringBoot--><dependency><groupId>org.springframework.boot</groupId><......
  • CMDB平台(进阶篇):CMDB的应用场景剖析
    配置管理数据库(ConfigurationManagementDatabase,简称CMDB)是IT服务管理(ITSM)中的核心组件。随着信息技术的快速发展,大型企业的IT环境变得越来越复杂,为了更好地管理和维护这些复杂的IT基础设施,近些年来国内CMDB平台越来越多,如乐维CMDB、华为CMDB等。CMDB不仅是一个存储系统,用于记录......
  • 基于Java+SpringBoot+Vue+HTML5社团管理系统(源码+LW+调试文档+讲解等)/社团管理软件/
    博主介绍......
  • 基于密码学技术的创新应用研究报告
    基于密码学技术的创新应用研究报告竞赛认知内容要求:介绍对全国密码技术竞赛(作品赛或科普赛均可)和参赛作品内容的认知。全国密码技术竞赛由国家密码管理局指导,中国密码学会主办。竞赛旨在“提高密码意识、普及密码知识、实践密码技术、发现密码人才”,主要面向全国高等院校学生,是国......
  • 京准时钟:子母钟系统是什么?应用场景是?
    京准时钟:子母钟系统是什么?应用场景是?京准时钟:子母钟系统是什么?应用场景是?京准电子官微——ahjzsz在信息时代的今天,准确统一的时钟系统已广泛的应用在车站、医院、学校、机场等公共服务场所。因此完善的时钟系统对医院来说,是至关重要的。按照医院等智能化楼宇工程对时钟系统的......
  • 2024年信号处理与神经网络应用国际学术会议(SPNNA 2024) 2024 International Conferenc
    @目录一、会议详情二、重要信息三、大会介绍四、出席嘉宾五、征稿主题六、咨询一、会议详情二、重要信息大会官网:https://ais.cn/u/vEbMBz提交检索:EICompendex、IEEEXplore、Scopus三、大会介绍2024年信号处理与神经网络应用国际学术会议(SPNNA2024)将于2024年12月13日......
  • 【鸿蒙HarmonyOS实战:通过华为应用市场上架测试版App实现HBuilder X打包的UniApp项目的
    鸿蒙HarmonyOS实战:通过华为应用市场上架测试版App实现HBuilderX打包的UniApp项目的app转hap教程(邀请码)方式详解在使用uniapp打包的鸿蒙项目的过程中,由于生成的是app文件,而hdc传给鸿蒙HarmonyOS系统需要的是hap文件,hdc不能上传app文件,需要hap格式,或者通过华为应用市场下......
  • C++多线程应用
    一个进程就是一个程序,一个程序里不止一个功能,每个功能的实现就可以交给一个线程去完成。一个进程就像是一个工程,这个工程里,有设计,有监理,有施工,就相当于三个线程,各干各的又相互配合。https://cplusplus.com/reference/thread/thread/thread/是C++的官方参考,个人觉得比较权威,比经......
  • 基于深度学习的舆论分析与检测系统应用与研究
    【1】系统介绍研究背景随着互联网技术的迅猛发展和社会媒体平台的普及,信息传播的速度和范围达到了前所未有的水平。这一变化不仅极大地丰富了人们的社交生活,也为社会科学研究提供了新的视角和工具。舆论分析作为社会科学研究的一个重要分支,其目的是通过收集和分析网络上的......