【C++数据结构——线性表】顺序表的基本运算(头歌实践教学平台习题)【合集】

news2025/1/8 19:18:48

目录😋

任务描述

 相关知识

一、线性表的基本概念

二、初始化线性表

三、销毁线性表

四、判定是否为空表

五、求线性表的长度

六、输出线性表

七、求线性表中某个数据元素值

八、按元素值查找

九、插入数据元素

十、删除数据元素

测试说明

通关代码

测试结果


任务描述

本关任务:实现顺序表的基本运算

 相关知识

为了完成本关任务,你需要掌握:

  1. 线性表的基本概念
  2. 初始化线性表
  3. 销毁线性表
  4. 判定是否为空表
  5. 求线性表的长度
  6. 输出线性表
  7. 求线性表中某个数据元素值
  8. 按元素值查找
  9. 插入数据元素
  10. 删除数据元素

一、线性表的基本概念

线性表是一种基本的数据结构,它是由 n(n ≥ 0)个具有相同类型的数据元素组成的有限序列。可以将线性表想象成一个队伍,队伍中的每个人(数据元素)都有自己的位置,并且他们的类型是相同的(比如都是学生)。常见的线性表有顺序表和链表

二、初始化线性表

  1. 顺序表初始化(以 C++ 为例)
    顺序表通常是用数组来实现的。初始化时,需要定义数组的大小,并且可以将线性表的长度(当前存储的元素个数)初始化为 0。
    示例代码:

    #define MAX_SIZE 100  // 假设顺序表最大容量为100
    template <typename T>
    class SeqList {
    public:
        T data[MAX_SIZE];
        int length;
        SeqList() {
            length = 0;
        }
    };
  2. 链表初始化(以单链表为例)
    单链表由节点组成,每个节点包含数据域和指针域。初始化时,头节点(如果有)的指针通常设为 NULL,表示链表为空。
    示例代码:

    template <typename T>
    struct ListNode {
        T data;
        ListNode<T> *next;
        ListNode(T x) : data(x), next(NULL) {}
    };
    // 初始化一个空链表,只需要定义头节点并将其next指针设为NULL
    ListNode<int> *head = new ListNode<int>(0);
    head->next = NULL;

三、销毁线性表

  • 顺序表销毁
    • 对于顺序表,如果是静态分配的数组(如上述示例),在程序结束时自动销毁。如果是动态分配的数组,需要使用delete[]来释放内存。不过一般简单的顺序表在程序结束时会自动回收内存,不需要手动销毁。
  • 链表销毁
    • 对于链表,需要遍历链表,逐个释放节点占用的内存。从链表的头节点开始,先保存下一个节点的指针,然后释放当前节点,再将指针指向下一个节点,直到链表为空。

示例代码:

template <typename T>
void destroyList(ListNode<T> *head) {
    ListNode<T> *current = head;
    ListNode<T> *next;
    while (current!= NULL) {
        next = current->next;
        delete current;
        current = next;
    }
}

四、判定是否为空表

  • 顺序表判定
    • 只需检查线性表的长度是否为 0。如果length == 0,则顺序表为空。

示例代码:

template <typename T>
bool isEmpty(SeqList<T> list) {
    return list.length == 0;
}
  • 链表判定
    • 对于链表,检查头节点的下一个节点是否为 NULL。如果head->next == NULL,则链表为空。

示例代码:

template <typename T>
bool isEmpty(ListNode<T> *head) {
    return head->next == NULL;
}

五、求线性表的长度

  • 顺序表求长度
    • 直接返回顺序表中记录长度的变量的值,如return length;
  • 链表求长度
    • 需要遍历链表,从链表头节点开始(不计算头节点本身,如果有头节点的话),每经过一个节点,长度加 1,直到链表结束。

示例代码:

template <typename T>
int length(ListNode<T> *head) {
    int len = 0;
    ListNode<T> *current = head->next;
    while (current!= NULL) {
        len++;
        current = current->next;
    }
    return len;
}

六、输出线性表

  • 顺序表输出
    • 遍历顺序表数组中从 0 到length - 1的元素,逐个输出元素。

示例代码:

template <typename T>
void printSeqList(SeqList<T> list) {
    for (int i = 0; i < list.length; i++) {
        std::cout << list.data[i] << " ";
    }
    std::cout << std::endl;
}
  • 链表输出
    • 从链表头节点的下一个节点(如果有头节点)开始,遍历链表,输出每个节点的数据域内容,直到链表结束。

示例代码:

template <typename T>
void printList(ListNode<T> *head) {
    ListNode<T> *current = head->next;
    while (current!= NULL) {
        std::cout << current->data << " ";
        current = current->next;
    }
    std::cout << std::endl;
}

七、求线性表中某个数据元素值

  • 顺序表求元素值
    • 给定元素的位置(索引)i,如果0 <= i < length,则返回data[i],否则可能需要根据具体情况返回错误信息(如抛出异常或者返回一个特殊值表示位置无效)。
  • 链表求元素值
    • 首先遍历链表,当遍历到第i个节点(假设链表头节点不算在内,从 0 开始计数)时,返回该节点的数据域的值。这可能需要一个计数器来记录当前遍历到的节点位置。

八、按元素值查找

  • 顺序表按元素值查找
    • 遍历顺序表数组,从 0 到length - 1,比较每个元素和目标元素的值。如果找到相等的元素,返回该元素的索引;如果遍历完整个顺序表都没有找到,可能返回一个特殊值(如 - 1)表示未找到。

示例代码:

template <typename T>
int findElement(SeqList<T> list, T target) {
    for (int i = 0; i < list.length; i++) {
        if (list.data[i] == target) {
            return i;
        }
    }
    return -1;
}
  • 链表按元素值查找
    • 从链表头节点的下一个节点开始遍历链表,比较每个节点的数据域和目标元素的值。如果找到相等的元素,返回该节点(或者返回节点的索引,这取决于具体要求);如果遍历完整个链表都没有找到,返回一个表示未找到的特殊值。

九、插入数据元素

  • 顺序表插入元素
    • 如果是在位置i插入元素,需要先判断i的合法性(如0 <= i <= length)。如果i合法,将i及以后的元素向后移动一位(从最后一个元素开始移动),然后将新元素插入到i位置,最后长度加 1。

示例代码:

template <typename T>
void insertElement(SeqList<T> &list, T element, int i) {
    if (i < 0 || i > list.length) {
        std::cout << "插入位置无效" << std::endl;
        return;
    }
    if (list.length == MAX_SIZE) {
        std::cout << "顺序表已满" << std::endl;
        return;
    }
    for (int j = list.length; j > i; j--) {
        list.data[j] = list.data[j - 1];
    }
    list.data[i] = element;
    list.length++;
}
  • 链表插入元素
    • 插入位置分为在头节点后插入、在中间节点插入和在尾节点插入。如果是在头节点后插入,只需修改新节点的指针和头节点的指针;在中间节点插入,需要先找到插入位置的前一个节点,然后修改指针来插入新节点;在尾节点插入,找到链表的最后一个节点,将新节点插入到最后一个节点之后。

十、删除数据元素

  • 顺序表删除元素
    • 给定要删除元素的位置i,先判断i的合法性(如0 <= i < length)。如果i合法,将i + 1位置的元素向前移动到i位置,直到最后一个元素,然后长度减 1。

示例代码:

template <typename T>
void deleteElement(SeqList<T> &list, int i) {
    if (i < 0 || i >= list.length) {
        std::cout << "删除位置无效" << std::endl;
        return;
    }
    for (int j = i; j < list.length - 1; j++) {
        list.data[j] = list.data[j + 1];
    }
    list.length--;
}
  • 链表删除元素
    • 同样需要先找到要删除的节点。如果是删除头节点后的节点,修改头节点的指针;如果是删除中间节点,找到要删除节点的前一个节点,修改指针跳过要删除的节点;如果是删除尾节点,找到倒数第二个节点,将其指针设为 NULL。

测试说明

平台会对你编写的代码进行测试:

测试输入:

3
4

预期输出: 

(1)初始化顺序表L
(2)依次插入a,b,c,d,e元素
(3)输出顺序表L:a b c d e
(4)顺序表L长度:5
(5)顺序表L为非空
(6)顺序表L的第3个元素:c
(7)元素a的位置:1
(8)在第4个元素位置上插入f元素
(9)输出顺序表L:a b c f d e
(10)删除L的第3个元素
(11)输出顺序表L:a b f d e
(12)释放顺序表L

开始你的任务吧,祝你成功!


通关代码

// 请在Begin-End之间添加你的代码,
//实现顺序表的如下基本运算,假设顺序表的元素类型为char//
//(1)初始化顺序表L//
//(2)依次插入a,b,c,d,e元素//
//(3)输出顺序表L//
//(4)输出顺序表L的长度//
//(5)判断顺序表L是否为空,输出判断结果//
//(6)输出顺序表L的第m个元素,m由用户输入//
//(7)输出元素a的位置//
//(8)在第n个元素位置上插入f元素,n由用户输入//
//(9)输出顺序表L//
//(10)删除顺序表L的第m个元素,延用第(6)的m//
//(11)输出顺序表L//
//(12)释放顺序表L//
/********** Begin *********/
#include <iostream>
#include <string>

using namespace std;

#define MAX_SIZE 100

typedef char ElemType;

typedef struct {
  ElemType data[MAX_SIZE];
  int length;
} SeqList;

void InitList(SeqList &L) { L.length = 0; }

void PrintList(SeqList L) {
  for (int i = 0; i < L.length; i++) {
    cout << L.data[i] << " ";
  }
  cout << endl;
}
int InsertList(SeqList *L, int i, ElemType e) {
  if (i < 1 || i > L->length + 1 || L->length >= MAX_SIZE)
    return 0;
  for (int j = L->length; j >= i; j--) {
    L->data[j] = L->data[j - 1];
  }
  L->data[i - 1] = e;
  L->length++;
  return 1;
}

bool GetElem(SeqList L, int i, ElemType &e) {
  if (i < 1 || i > L.length)
    return false;
  e = L.data[i - 1];
  return true;
}

int LocateElem(SeqList L, ElemType e) {
  for (int i = 0; i < L.length; i++) {
    if (L.data[i] == e)
      return i + 1;
  }
  return 0;
}

bool ListInsert(SeqList &L, int i, ElemType e) {
  if (i < 1 || i > L.length + 1)
    return false;
  for (int j = L.length; j >= i; j--) {
    L.data[j] = L.data[j - 1];
  }
  L.data[i - 1] = e;
  L.length++;
  return true;
}

bool ListDelete(SeqList &L, int i, ElemType &e) {
  if (i < 1 || i > L.length)
    return false;
  e = L.data[i - 1];
  for (int j = i; j < L.length; j++) {
    L.data[j - 1] = L.data[j];
  }
  L.length--;
  return true;
}

int main() {
  SeqList L;
  InitList(L);
  int pos1, pos2;
  cin >> pos1 >> pos2;
  cout << "(1)初始化顺序表L" << endl;

  char elements[] = {'a', 'b', 'c', 'd', 'e'};
  for (int i = 0; i < 5; i++) {
    InsertList(&L, i + 1, elements[i]);
  }
  cout << "(2)依次插入a,b,c,d,e元素" << endl;
  cout << "(3)输出顺序表L:";
  PrintList(L);

  cout << "(4)顺序表L长度:" << L.length << endl;
  cout << "(5)顺序表L为非空" << endl;

  ElemType e;
  if (GetElem(L, pos1, e)) {
    cout << "(6)顺序表L的第" << pos1 << "个元素:" << e << endl;
  }
  int pos = LocateElem(L, 'a');
  cout << "(7)元素a的位置:" << pos << endl;

  ListInsert(L, pos2, 'f');
  cout << "(8)在第" << pos2 << "个元素位置上插入f元素" << endl;
  cout << "(9)输出顺序表L:";
  PrintList(L);

  ListDelete(L, pos1, e);
  cout << "(10)删除L的第" << pos1 << "个元素" << endl;
  cout << "(11)输出顺序表L:";
  PrintList(L);

  cout << "(12)释放顺序表L";

  return 0;
}
/********** End **********/

测试结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2272790.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++数据结构——查找】二分查找(头歌实践教学平台习题)【合集】

目录&#x1f60b; 任务描述 相关知识 一、根据键盘输入的一组有序数据建立顺序表 二、顺序表的输出 三、二分查找算法 测试说明 通关代码 测试结果 任务描述 本关任务&#xff1a;实现二分查找的算法。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a; …

20250103在Ubuntu20.04.5的Android Studio 2024.2.1.12中跑通Hello World

20250103在Ubuntu20.04.5的Android Studio 2024.2.1.12中跑通Hello World 2025/1/3 14:06 百度&#xff1a;android studio helloworld android studio hello world kotlin helloword kotlin 串口 no run configurations added android studio no run configurations added 1、…

卸载干净 IDEA(图文讲解)

目录 1、卸载 IDEA 程序 2、注册表清理 3、残留清理 1、卸载 IDEA 程序 点击屏幕左下角 Windows 图标 -> 设置-控制面板->intellij idea 勾选第一栏 Delete IntelliJ IDEA 2022.2 caches and local history&#xff0c;表示同时删除 IDEA 本地缓存以及历史。 Delete I…

【HarmonyOS】鸿蒙应用实现屏幕录制详解和源码

【HarmonyOS】鸿蒙应用实现屏幕录制详解和源码 一、前言 官方文档关于屏幕录制的API和示例介绍获取简单和突兀。使用起来会让上手程度变高。所以特意开篇文章&#xff0c;讲解屏幕录制的使用。官方文档参见&#xff1a;使用AVScreenCaptureRecorder录屏写文件(ArkTS) 二、方…

我的创作纪念日——《惊变128天》

我的创作纪念日——《惊变128天》 机缘收获日常成就憧憬 机缘 时光飞逝&#xff0c;转眼间&#xff0c;我已在这条创作之路上走过了 128 天。回顾起 2024 年 8 月 29 日&#xff0c;我满怀忐忑与期待&#xff0c;撰写了第一篇技术博客《讲解LeetCode第1题&#xff1a;两数之和…

stm32第一次烧录或者上电运行卡死问题分析

问题描述 单片机烧录代码&#xff08;刚上电&#xff09;无法立即运行&#xff0c;必须要复位一次或多次才能运行&#xff1b;跟踪调试会进入HardFault_Handler中断。 问题分析 烧录配置如下图&#xff0c;首先排除配置问题那么该问题就比较让人头大了&#xff0c;理论上&am…

YOLOV8训练好的best.pt模型转best.onnx并部署成python可调用

今天这篇博文是学习大佬作品以后&#xff0c;执行我的需求后的总结&#xff0c;做了一些代码调整&#xff0c;就此记录一下&#xff0c;非常感谢大佬提供如此好的输出。 已知yolov8 训练好的模型一般是pt格式&#xff0c;比如best.pt&#xff0c;现在我期望这个模型可以转成可以…

君正T41交叉编译ffmpeg、opencv并做h264软解,利用君正SDK做h264硬件编码

目录 1 交叉编译ffmpeg----错误解决过程&#xff0c;不要看 1.1 下载源码 1.2 配置 1.3 编译 安装 1.3.1 报错&#xff1a;libavfilter/libavfilter.so: undefined reference to fminf 1.3.2 报错&#xff1a;error: unknown type name HEVCContext; did you mean HEVCPr…

基于ASP.NET的动漫网站

一、系统架构与技术实现 系统架构&#xff1a;基于ASP.NET的MVC框架构建&#xff0c;实现网站的层次结构&#xff0c;使得网站更加易于维护和扩展。 技术实现&#xff1a;利用ASP.NET的技术特点&#xff0c;如强大的后端开发能力、丰富的UI控件等&#xff0c;结合前端技术如HT…

「Java 数据结构全面解读」:从基础到进阶的实战指南

「Java 数据结构全面解读」&#xff1a;从基础到进阶的实战指南 数据结构是程序设计中的核心部分&#xff0c;用于组织和管理数据。Java 提供了丰富的集合框架和工具类&#xff0c;涵盖了常见的数据结构如数组、链表、栈、队列和树等。本文将系统性地介绍这些数据结构的概念、…

安卓NDK视觉开发——手机拍照文档边缘检测实现方法与库封装

一、项目创建 创建NDK项目有两种方式&#xff0c;一种从新创建整个项目&#xff0c;一个在创建好的项目添加NDK接口。 1.创建NDK项目 创建 一个Native C项目&#xff1a; 选择包名、API版本与算法交互的语言&#xff1a; 选择C版本&#xff1a; 创建完之后&#xff0c;可…

MATLAB仿真:基于GS算法的经大气湍流畸变涡旋光束波前校正仿真

GS算法流程 GS&#xff08;Gerchberg-Saxton&#xff09;相位恢复算法是一种基于傅里叶变换的最速下降算法&#xff0c;可以通过输出平面和输入平面上光束的光强分布计算出光束的相位分布。图1是基于GS算法的涡旋光束畸变波前校正系统框图&#xff0c;在该框图中&#xff0c;已…

【React+TypeScript+DeepSeek】穿越时空对话机

引言 在这个数字化的时代&#xff0c;历史学习常常给人一种距离感。教科书中的历史人物似乎永远停留在文字里&#xff0c;我们无法真正理解他们的思想和智慧。如何让这些伟大的历史人物"活"起来&#xff1f;如何让历史学习变得生动有趣&#xff1f;带着这些思考&…

深入刨析数据结构之排序(上)

目录 1.内部排序 1.1概述 1.2插入排序 1.2.1其他插入排序 1.2.1.1 折半插入排序 1.2.1.2 2-路插入排序 1.3希尔排序 1.4快速排序 1.4.1起泡排序 1.4.2快速排序 1.4.2.1hoare版本 1.4.2.2挖坑版本 1.4.2.3前后指针版本 1.4.2.4优化版本 1.4.2.4.1小区间插入排序优…

AIA - APLIC之三(附APLIC处理流程图)

本文属于《 RISC-V指令集基础系列教程》之一,欢迎查看其它文章。 1 APLIC复位 APLIC复位后,其所有状态都变得有效且一致,但以下情况除外: 每个中断域的domaincfg寄存器(spec第 4.5.1 节);可能是machine-level interrupt domain的MSI地址配置寄存器(spec第4.5.3 和4.5…

openwrt 清缓存命令行

一、查看缓存 &#xff1a; free -m 二、清缓存&#xff1a;echo 3 > /proc/sys/vm/drop_caches  三、详解。 释放物理页缓存 echo 1 > /proc/sys/vm/drop_caches 释放可回收的slab对象&#xff0c;包含inode and dentry echo 2 > /proc/sys/vm/drop_caches 同时…

Linux -- 端口号、套接字、网络字节序、sockaddr 结构体

目录 什么是端口号&#xff1f; 什么是套接字&#xff1f; 网络字节序 struct sockaddr 结构体 什么是端口号&#xff1f; 我们日常上网的时候&#xff0c;主机其实是在进行两种操作&#xff1a; 1、把远端的数据拉取到本地&#xff0c;比如刷抖音的时候&#xff0c;手机向…

《数据结构》期末考试测试题【中】

《数据结构》期末考试测试题【中】 21.循环队列队空的判断条件为&#xff1f;22. 单链表的存储密度比1&#xff1f;23.单链表的那些操作的效率受链表长度的影响&#xff1f;24.顺序表中某元素的地址为&#xff1f;25.m叉树第K层的结点数为&#xff1f;26. 在双向循环链表某节点…

实际开发中,常见pdf|word|excel等文件的预览和下载

实际开发中,常见pdf|word|excel等文件的预览和下载 背景相关类型数据之间的转换1、File转Blob2、File转ArrayBuffer3、Blob转ArrayBuffer4、Blob转File5、ArrayBuffer转Blob6、ArrayBuffer转File 根据Blob/File类型生成可预览的Base64地址基于Blob类型的各种文件的下载各种类型…

《Opencv》基础操作详解(4)

接上篇&#xff1a;《Opencv》基础操作详解&#xff08;3&#xff09;-CSDN博客 目录 22、图像形态学操作 &#xff08;1&#xff09;、顶帽&#xff08;原图-开运算&#xff09; 公式&#xff1a; 应用场景&#xff1a; 代码示例&#xff1a; &#xff08;2&#xff09;…