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

简介: 本文档介绍了线性表的基本运算任务,涵盖顺序表和链表的初始化、销毁、判定是否为空、求长度、输出、查找元素、插入和删除元素等内容。通过C++代码示例详细展示了每一步骤的具体实现方法,并提供了测试说明和通关代码。主要内容包括:- **任务描述**:实现顺序表的基本运算。- **相关知识**:介绍线性表的基本概念及操作,如初始化、销毁、判定是否为空表等。- **具体操作**:详述顺序表和链表的初始化、求长度、输出、查找、插入和删除元素的方法,并附有代码示例。- **测试说明**:提供测试输入和预期输出,确保代码正确性。- **通关代码**:给出完整的C++代码实现,帮助完成任务。文档

目录😋

任务描述

相关知识

一、线性表的基本概念

二、初始化线性表

三、销毁线性表

四、判定是否为空表

五、求线性表的长度

六、输出线性表

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

八、按元素值查找

九、插入数据元素

十、删除数据元素

测试说明

通关代码

测试结果


任务描述

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

相关知识

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

  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;
    }
};
  1. image.gif
  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;
  1. image.gif

三、销毁线性表

  • 顺序表销毁
  • 对于顺序表,如果是静态分配的数组(如上述示例),在程序结束时自动销毁。如果是动态分配的数组,需要使用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;
    }
}
image.gif

四、判定是否为空表

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

示例代码:

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

示例代码:

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

五、求线性表的长度

  • 顺序表求长度
  • 直接返回顺序表中记录长度的变量的值,如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;
}
image.gif

六、输出线性表

  • 顺序表输出
  • 遍历顺序表数组中从 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;
}
image.gif
  • 链表输出
  • 从链表头节点的下一个节点(如果有头节点)开始,遍历链表,输出每个节点的数据域内容,直到链表结束。

示例代码:

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;
}
image.gif

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

  • 顺序表求元素值
  • 给定元素的位置(索引)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;
}
image.gif
  • 链表按元素值查找
  • 从链表头节点的下一个节点开始遍历链表,比较每个节点的数据域和目标元素的值。如果找到相等的元素,返回该节点(或者返回节点的索引,这取决于具体要求);如果遍历完整个链表都没有找到,返回一个表示未找到的特殊值。

九、插入数据元素

  • 顺序表插入元素
  • 如果是在位置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++;
}
image.gif
  • 链表插入元素
  • 插入位置分为在头节点后插入、在中间节点插入和在尾节点插入。如果是在头节点后插入,只需修改新节点的指针和头节点的指针;在中间节点插入,需要先找到插入位置的前一个节点,然后修改指针来插入新节点;在尾节点插入,找到链表的最后一个节点,将新节点插入到最后一个节点之后。

十、删除数据元素

  • 顺序表删除元素
  • 给定要删除元素的位置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--;
}
image.gif
  • 链表删除元素
  • 同样需要先找到要删除的节点。如果是删除头节点后的节点,修改头节点的指针;如果是删除中间节点,找到要删除节点的前一个节点,修改指针跳过要删除的节点;如果是删除尾节点,找到倒数第二个节点,将其指针设为 NULL。

测试说明

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

测试输入:

3
4
image.gif

预期输出:

(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
image.gif

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


通关代码

// 请在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 **********/

image.gif


测试结果

image.gif 编辑

image.gif 编辑

目录
相关文章
|
15天前
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
132 77
|
15天前
|
C++ 芯片
【C++面向对象——类与对象】Computer类(头歌实践教学平台习题)【合集】
声明一个简单的Computer类,含有数据成员芯片(cpu)、内存(ram)、光驱(cdrom)等等,以及两个公有成员函数run、stop。只能在类的内部访问。这是一种数据隐藏的机制,用于保护类的数据不被外部随意修改。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。成员可以在派生类(继承该类的子类)中访问。成员,在类的外部不能直接访问。可以在类的外部直接访问。为了完成本关任务,你需要掌握。
56 19
|
15天前
|
C++
【C++数据结构——树】二叉树的性质(头歌实践教学平台习题)【合集】
本文档介绍了如何根据二叉树的括号表示串创建二叉树,并计算其结点个数、叶子结点个数、某结点的层次和二叉树的宽度。主要内容包括: 1. **定义二叉树节点结构体**:定义了包含节点值、左子节点指针和右子节点指针的结构体。 2. **实现构建二叉树的函数**:通过解析括号表示串,递归地构建二叉树的各个节点及其子树。 3. **使用示例**:展示了如何调用 `buildTree` 函数构建二叉树并进行简单验证。 4. **计算二叉树属性**: - 计算二叉树节点个数。 - 计算二叉树叶子节点个数。 - 计算某节点的层次。 - 计算二叉树的宽度。 最后,提供了测试说明及通关代
38 10
|
2月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
291 9
|
2月前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
45 1
|
15天前
|
存储 C++ 索引
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
37 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
|
15天前
|
存储 C语言 C++
【C++数据结构——栈与队列】链栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现链栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储整数,最大
38 9
|
15天前
|
C++
【C++数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】
【数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】(1)遇到左括号:进栈Push()(2)遇到右括号:若栈顶元素为左括号,则出栈Pop();否则返回false。(3)当遍历表达式结束,且栈为空时,则返回true,否则返回false。本关任务:编写一个程序利用栈判断左、右圆括号是否配对。为了完成本关任务,你需要掌握:栈对括号的处理。(1)遇到左括号:进栈Push()开始你的任务吧,祝你成功!测试输入:(()))
30 7
|
2月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
90 5
|
2月前
|
存储 算法 Java
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。
104 21