【数据结构】顺序表的实现——静态分配

在这里插入图片描述

🎈个人主页:豌豆射手^
🎉欢迎 👍点赞✍评论⭐收藏
🤗收录专栏:数据结构
🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步!

【数据结构】顺序表的实现——静态分配

  • 引言
  • 一 静态分配内存的概念
    • 1.1 概念
    • 1.2 类比
    • 1.3 例子
  • 二 顺序表静态分配的概念
    • 2.1 概念
    • 2.2 类比
  • 三 顺序表静态分配的实现方式
    • 3.1 定义顺序表结构体
    • 3.2 初始化顺序表:
    • 3.3 插入元素:
    • 3.4 删除元素:
    • 3.5 查找元素:
    • 3.6 修改元素:
  • 四 静态分配顺序表的优缺点分析
    • 4.1 优点:
    • 4.2 缺点:
  • 五 示例代码
  • 总结

引言

在数据结构的领域中,顺序表是一种基础且重要的线性表实现方式。它采用一段地址连续的存储单元依次存储线性表的数据元素,通过下标进行访问。

本文将重点探讨顺序表的静态分配实现方式,通过对其概念、实现方式以及优缺点的分析,帮助读者深入理解并掌握顺序表的相关知识
在这里插入图片描述

一 静态分配内存的概念

1.1 概念

在数据结构中,静态分配内存是一种在程序编译时确定所需内存大小,并在程序执行之前进行内存分配的方式。

这种分配方式通常在声明变量或数组时进行,它们被存储在程序的静态存储区或栈上。

静态分配内存具有几个特点。

首先,其大小在编译时就已经确定,因此具有固定的位置和生命周期

这意味着一旦分配了内存,其大小在程序运行期间不会改变

其次,静态分配的内存分配和释放是自动进行的,不需要手动管理。

当变量或数组超出其作用域或被销毁时,其占用的内存会自动被释放。

静态分配内存通常用于存储程序中的常量、全局变量和静态局部变量,以及其他需要在程序运行期间保持固定位置和生命周期的数据结构

在C和C++等语言中,静态区和静态内存的使用需要开发者手动控制,通常通过对变量的声明和定义进行修饰实现。

然而,静态分配内存也有一些局限性。

由于其在编译时确定大小,因此无法适应程序运行时可能出现的动态内存需求变化

如果分配的内存过大,可能会浪费系统资源;

如果过小,则可能导致程序运行出错。

为了应对这种局限性,动态内存分配被引入。

动态内存分配允许程序在运行时根据需要分配和释放内存,从而更灵活地管理内存资源。但需要注意的是,动态内存分配需要手动管理,如果管理不当可能导致内存泄漏或其他问题。

总的来说,静态分配内存是一种简单且高效的内存管理方式,适用于那些大小固定且生命周期明确的数据结构。但在处理复杂或动态变化的内存需求时,可能需要结合动态内存分配来使用。

1.2 类比

我们可以用现实中的一个例子来类比数据结构中静态分配内存的概念。

假设你正在策划一场大型活动,如音乐会或运动会。在这个场景中,你可以将静态分配内存类比为提前规划和分配资源的过程

静态分配内存

  • 大小确定:在策划活动时,你需要提前确定一些固定的资源需求,比如座位的数量、舞台的大小、音响设备的配置等。这些资源在活动开始前就已经被确定,并且不会在活动进行过程中改变。
  • 自动管理:一旦你规划了这些资源,它们就会按照你的计划自动存在。你不需要在活动过程中时刻关注这些资源的分配和释放。
  • 固定位置:座位、舞台、设备等在场地内都有固定的位置,它们在活动开始前就已经布置好,并且在活动进行过程中保持不变

类比到数据结构

  • 大小确定:在编程时,当你声明一个静态数组时,你需要在声明时就确定数组的大小。这个大小在程序运行期间不会改变
  • 自动管理:数组的内存分配和释放是由编译器自动管理的。你不需要手动去申请或释放内存
  • 固定位置:数组的元素在内存中也有固定的位置,你可以通过索引直接访问数组中的某个元素

通过这个类比,我们可以看到静态分配内存与现实生活中规划和分配固定资源的过程有很多相似之处。

它们都是在开始前就确定好大小、位置和数量,并且在整个过程中保持不变。

当然,这种固定性也带来了一定的局限性,比如无法应对突发的变化或需求增长。

在编程中,这种局限性可以通过动态内存分配来克服。但在现实生活中,我们也需要灵活应对变化,可能需要一些额外的策略和规划来确保资源的有效利用。

1.3 例子

下面是一个简单的C语言代码示例,展示了静态内存分配的基本用法。在这个例子中,我们将声明一个固定大小的整数数组,然后对其进行初始化,并打印出数组的内容。

#include <stdio.h>

int main() {
    // 静态分配内存,声明一个包含5个整数的数组
    int staticArray[5] = {1, 2, 3, 4, 5};
    
    // 遍历数组并打印每个元素的值
    for (int i = 0; i < 5; i++) {
        printf("staticArray[%d] = %d\n", i, staticArray[i]);
    }
    
    // 静态分配的内存在程序执行完毕后会自动释放
    return 0;
}

代码结果(假设运行在一个标准的终端或控制台):

staticArray[0] = 1
staticArray[1] = 2
staticArray[2] = 3
staticArray[3] = 4
staticArray[4] = 5

代码分析:

  1. main函数中,我们声明了一个名为staticArray的整数数组,并静态分配了5个整数的内存空间。这里的“静态”指的是内存分配是在编译时确定的,并且数组的大小在整个程序执行期间保持不变。

  2. 数组staticArray被初始化为包含5个整数值:1, 2, 3, 4, 5。这些值在编译时就已经确定,并存储在静态存储区。

  3. 通过一个for循环,我们遍历数组并打印出每个元素的值。由于数组是静态分配的,所以我们可以直接通过索引访问其元素。

  4. main函数返回后,由于staticArray是局部变量,其占用的内存会在函数结束时自动释放。然而,由于这是静态分配的内存,实际上编译器在程序编译时就已经确定了这块内存的释放时间,而不是在运行时。

注意:虽然这个例子中的数组名为staticArray,但这里的“静态”并不是指C语言中的static关键字。这里的“静态”仅用于描述内存分配的方式是静态的,即在编译时确定

在C语言中,static关键字用于声明变量的生命周期为整个程序执行期间,而不仅仅是它们所在的函数或代码块

在本例中,即使我们没有使用static关键字,数组仍然是静态分配的,因为它的大小在编译时确定,并且作为局部变量存储在栈上。

如果要使数组的生命周期跨越多个函数调用,可以使用static关键字,但这与静态内存分配的概念是不同的。

二 顺序表静态分配的概念

2.1 概念

在数据结构中,顺序表是一种线性表的存储结构,其中元素在物理内存中以连续的方式存储。

顺序表可以通过两种方式进行实现:静态分配和动态分配

静态分配是指顺序表在声明时其大小就已经确定,且这个大小在程序的整个运行期间都不会改变

在静态分配中,顺序表通常是通过数组来实现的,因为数组的大小在编译时确定,并且一旦确定就不能更改

即静态分配的内存空间在程序执行前就已经分配完毕,并且会在程序执行完毕后自动释放。

静态分配顺序表的主要优点在于其简单性和效率

由于数组的大小在编译时确定,因此编译器可以进行一些优化,提高程序的执行效率。

此外,静态分配的顺序表在访问元素时具有较快的速度,因为可以通过简单的计算(即基址加偏移量)直接定位到元素的存储位置。

然而,静态分配顺序表也存在一些局限性。最主要的问题是其大小固定,无法根据程序运行时的需求进行动态调整

如果预先分配的空间过大,会造成内存资源的浪费;

如果分配的空间过小,则可能导致程序在运行时出现数组越界等错误。

因此,在选择使用静态分配顺序表时,需要根据实际的应用场景和需求进行权衡

如果数据量固定且不大,静态分配是一个简单且高效的选择;

如果数据量可能动态变化,或者需要更灵活的内存管理,那么可能需要考虑使用动态分配或其他数据结构。

2.2 类比

现实中的例子可以类比为在图书馆中分配书架来存储书籍

假设图书馆决定为某个特定类别的书籍分配书架。这个决定是在图书馆规划阶段就做出的,并且书架的数量和位置在规划完成后就固定下来了。这就是类似于数据结构中顺序表的静态分配。

静态分配书架的类比

  1. 大小确定:图书馆根据预计的书籍数量和类别,确定需要多少个书架来存放这些书籍。这些书架的数量和大小在图书馆建设或重新规划时就已经确定,并且在之后的使用过程中不会改变

  2. 位置固定:书架在图书馆内有固定的位置,按照规划好的布局摆放。每个书架都有一个固定的编号或位置标识,方便读者和图书管理员查找和管理。

  3. 连续存储:书架上的格子或层数是连续的,用于存放同一类别的书籍。这种连续存储的方式使得查找和取放书籍变得相对容易,类似于顺序表在内存中的连续存储

  4. 无法动态调整:一旦书架的数量和位置确定后,图书馆就难以根据书籍数量的变化来动态调整书架的配置。如果书籍数量增多,超出了现有书架的容量,图书馆可能需要重新规划并增加书架,这涉及到较大的改动和成本。

类比到数据结构

  1. 大小确定:在编程时,当你静态分配一个顺序表(例如通过数组)时,你需要在声明时就确定顺序表的大小(即数组的长度)。这个大小在程序运行期间不会改变

  2. 位置固定:顺序表的元素在内存中有固定的位置,通过索引可以直接访问到特定的元素

  3. 连续存储:顺序表在内存中占用连续的内存空间,这使得访问元素时可以通过简单的计算来定位到元素的地址。

  4. 无法动态调整:一旦顺序表的大小确定后,如果在程序运行过程中需要增加或减少元素的数量,而原有空间不足或过多,那么就需要进行额外的处理,如重新分配内存或浪费空间

通过这个类比,我们可以看到静态分配书架与静态分配顺序表在概念上有很多相似之处。

它们都是在规划或声明时就确定了大小和位置,并且在之后的使用过程中保持不变

然而,这种固定性也带来了一定的局限性,特别是在需要应对变化或增长的情况时。

因此,在现实中,图书馆可能会根据实际需求进行灵活调整,而在编程中,我们也有动态内存分配等方法来应对类似的问题。

三 顺序表静态分配的实现方式

顺序表静态分配的实现步骤主要涉及以下几个方面:

3.1 定义顺序表结构体

首先,需要定义一个结构体来表示顺序表。这个结构体通常包含两个主要部分:一个是用于存储元素的数组,另一个是用于记录顺序表当前长度的变量。例如,在C语言中,可以这样定义:

#define MAXSIZE 100 // 假设顺序表的最大长度为100

typedef struct {
    int data[MAXSIZE]; // 用于存储元素的数组
    int length;        // 记录顺序表当前长度
} SeqList;

在这个例子中,MAXSIZE 是静态分配的顺序表的最大容量,而 data 数组用于存储顺序表中的元素,length 则记录顺序表当前已存储的元素个数。

具体代码分析:

  1. #define MAXSIZE 100:这行代码定义了一个宏MAXSIZE,其值为100。这个宏在后续的代码中将被用作顺序表的最大长度,也就是数组data的大小。通过宏定义,可以在不修改源代码的情况下,方便地调整顺序表的最大长度。

  2. typedef struct {...} SeqList;:这行代码定义了一个结构体类型SeqList。结构体包含两个成员:

    • int data[MAXSIZE];:这是一个整型数组,用于存储顺序表中的元素。数组的大小由前面定义的宏MAXSIZE确定,即最大可以存储100个整数
    • int length;:这是一个整型变量,用于记录顺序表当前的长度,即当前顺序表中存储的元素的数量。这个长度在初始化时为0,随着元素的插入和删除操作而变化

整个代码段定义了一个简单的顺序表结构,其中使用了静态分配的方式来确定数组的大小。

3.2 初始化顺序表:

在创建顺序表时,需要对其进行初始化。初始化通常包括将顺序表的长度设置为0,以确保它是一个空表

void InitList(SeqList *L) {
    L->length = 0; // 将顺序表长度初始化为0
}

具体代码分析:

这段代码定义了一个名为InitList的函数,它接受一个指向SeqList结构体的指针L作为参数。该函数的主要目的是初始化顺序表,使其处于一个空表的状态。以下是对代码每个步骤的分析:

  1. void InitList(SeqList *L) {:定义了一个返回类型为void的函数InitList,它接受一个指向SeqList结构体的指针L作为参数。通过指针,函数能够访问和修改传入的顺序表实例

  2. L->length = 0;:这行代码通过指针L访问顺序表结构体中的length成员,并将其值设置为0。这个操作表示初始化顺序表,将其长度设置为0,即表示顺序表当前没有任何元素

  3. }:函数体结束。

综上,InitList函数的整个步骤就是接收一个顺序表的指针,然后将其长度初始化为0,从而实现顺序表的初始化。这样的初始化操作是创建新顺序表或重置现有顺序表为空表时的常见步骤。

3.3 插入元素:

向顺序表中插入元素时,需要检查顺序表是否已满(即当前长度是否已经达到最大容量)。如果未满,则将新元素添加到顺序表的末尾,并更新顺序表的长度。

int InsertList(SeqList *L, int elem) {
    if (L->length >= MAXSIZE) {
        // 顺序表已满,无法插入新元素
        return 0; // 返回失败
    }
    L->data[L->length] = elem; // 将新元素添加到顺序表末尾
    L->length++;              // 更新顺序表长度
    return 1;                  // 返回成功
}

具体代码分析:

这段代码定义了一个名为InsertList的函数,用于向顺序表SeqList中插入一个元素。以下是对代码每个步骤的分析:

首先,函数接受两个参数:一个指向SeqList结构体的指针L,以及一个待插入的整数元素elem

接着,函数检查顺序表是否已满,即检查L->length(顺序表的当前长度)是否大于等于MAXSIZE(顺序表的最大容量)。

如果是,说明顺序表已满,无法再插入新元素,因此函数返回0,表示插入失败。

如果顺序表未满,函数执行下一步,将新元素elem插入到顺序表的末尾,具体做法是将elem赋值给L->data[L->length],即顺序表数组中当前长度对应的位置。

然后,函数将顺序表的长度L->length加1,以反映新元素的插入。

最后,函数返回1,表示元素插入成功

整个函数通过检查顺序表是否已满、插入新元素、更新顺序表长度和返回操作结果等步骤,实现了向顺序表中插入新元素的功能。

3.4 删除元素:

从顺序表中删除元素时,通常需要指定要删除元素的位置。删除操作包括将指定位置后的所有元素前移一位,并更新顺序表的长度。

int DeleteList(SeqList *L, int pos) {
    if (pos < 1 || pos > L->length) {
        // 删除位置不合法
        return 0; // 返回失败
    }
    for (int i = pos; i < L->length; i++) {
        L->data[i - 1] = L->data[i]; // 将后续元素前移
    }
    L->length--; // 更新顺序表长度
    return 1;    // 返回成功
}

具体代码分析:

这段代码定义了一个名为DeleteList的函数,用于从顺序表SeqList中删除指定位置的元素。以下是对代码每个步骤的分析:

首先,函数接受两个参数:一个指向SeqList结构体的指针L,以及一个整数pos表示要删除元素的位置。

接着,函数检查删除位置pos是否合法

如果pos小于1或者大于顺序表的当前长度L->length,说明删除位置不合法,因此函数直接返回0,表示删除操作失败。

如果删除位置合法,函数进入循环,从pos位置开始,将顺序表中该位置及之后的每个元素都向前移动一位覆盖掉前一个元素的位置。这样,原来pos位置上的元素就被后续的元素所替代,从而实现了删除操作。

循环结束后,函数将顺序表的长度L->length减1,以反映元素被删除的情况。

最后,函数返回1,表示元素删除成功。

整个函数通过检查删除位置、移动元素和更新顺序表长度等步骤,实现了从顺序表中删除指定位置元素的功能。

在顺序表中,元素是按照数组的形式连续存储的。因此,当要删除某个位置的元素时,我们不能简单地移除那个元素,因为这会导致数组中出现一个“空洞”,即不连续的内存空间。为了维持顺序表的连续性,我们需要将删除位置之后的所有元素都向前移动一位,覆盖掉被删除元素的位置。

在这段代码中,for循环负责执行这个元素前移的操作。它从要删除的位置pos开始,将每个位置的元素值赋给前一个位置,直到到达顺序表的末尾。这样,原来pos位置上的元素就被后面的元素所覆盖,实现了删除的效果。

因此,虽然代码中并没有直接执行一个显式的“删除”操作(比如将某个元素的值设置为一个特殊值或NULL),但通过移动元素和更新长度,已经间接地实现了删除指定位置元素的功能。

3.5 查找元素:

顺序表的查找操作通常通过遍历数组来实现,比较目标值与顺序表中每个元素的值,直到找到目标值或遍历完整个顺序表。

int GetElem(SeqList L, int pos, int *elem) {
    if (pos < 1 || pos > L.length) {
        // 查找位置不合法
        return 0; // 返回失败
    }
    *elem = L.data[pos - 1]; // 返回查找位置的元素值
    return 1;                 // 返回成功
}

具体代码分析:

这段代码定义了一个名为GetElem的函数,用于从顺序表SeqList中获取指定位置的元素值。以下是对代码每个步骤的分析:

首先,函数接受三个参数:

一个SeqList类型的顺序表L,一个整数pos表示要查找的元素位置,以及一个整数指针elem用于返回查找到的元素值。

接着,函数检查查找位置pos是否合法。

如果pos小于1或者大于顺序表的当前长度L.length,说明位置不合法,因此函数直接返回0,表示查找失败。

如果查找位置合法,函数通过指针elem返回顺序表中对应位置的元素值。

这里使用了数组下标pos - 1来访问数组元素,因为数组下标是从0开始的,而位置是从1开始计数的。

最后,函数返回1,表示查找成功,并且已经将查找到的元素值通过指针elem返回给了调用者。

整个函数通过检查位置合法性、返回元素值和返回操作结果等步骤,实现了从顺序表中获取指定位置元素的功能。

3.6 修改元素:

修改顺序表中的元素只需要指定位置和新值,然后直接替换原有元素即可。

int UpdateElem(SeqList *L, int pos, int newElem) {
    if (pos < 1 || pos > L->length) {
        // 修改位置不合法
        return 0; // 返回失败
    }
    L->data[pos - 1] = newElem; // 修改指定位置的元素值
    return 1;                    // 返回成功
}

具体代码分析:

这段代码定义了一个名为UpdateElem的函数,用于更新顺序表SeqList中指定位置的元素值。以下是对代码每个步骤的分析:

首先,函数接受三个参数:

一个指向SeqList结构体的指针L,表示要更新的顺序表;一个整数pos,表示要更新的元素位置;以及一个整数newElem,表示新的元素值。

接着,函数检查更新位置pos是否合法。

如果pos小于1或者大于顺序表的当前长度L->length,说明位置不合法,因此函数直接返回0,表示更新失败。

如果更新位置合法,函数将新元素值newElem赋值给顺序表中对应位置的元素。

这里使用了数组下标pos - 1来访问数组元素,因为数组下标是从0开始的,而位置是从1开始计数的。

最后,函数返回1,表示更新成功。

整个函数通过检查位置合法性、更新元素值和返回操作结果等步骤,实现了顺序表中指定位置元素的更新功能。

这些步骤涵盖了顺序表静态分配的基本操作。

需要注意的是,由于静态分配的顺序表大小在初始化时就已经确定,因此在插入元素时需要检查是否已满,以避免数组越界错误。

同时,由于顺序表在内存中占用的是连续空间,因此插入和删除操作可能会涉及到大量元素的移动,这在某些情况下可能会影响性能。

在实际应用中,如果数据量较大或需要频繁进行插入和删除操作,可能需要考虑使用动态分配或其他数据结构来优化性能。

四 静态分配顺序表的优缺点分析

静态分配顺序表是数据结构中的一种常见形式,它基于数组实现,具有固定的存储空间大小。以下是对其优缺点的详细分析:

4.1 优点:

  1. 存储连续:静态分配顺序表的元素在物理存储上是连续的,这意味着通过下标访问元素的速度非常快,因为可以直接通过计算得出元素的存储位置。

  2. 空间利用率高:因为顺序表是基于数组实现的,其空间利用率通常比链表等结构要高。数组在内存中占用的是一块连续的空间,没有像链表那样的指针占用额外的空间。

  3. 随机访问:顺序表支持随机访问,即可以通过任意位置的索引直接访问该位置的元素,这在某些应用中是非常有用的,如快速查找特定位置的元素。

  4. 操作简单:对于顺序表,插入和删除操作通常只需要移动少量元素即可完成,这使得操作相对简单和高效。

4.2 缺点:

  1. 空间限制:静态分配顺序表的最大缺点是它的空间大小是固定的,一旦初始化后就不能改变。这意味着如果数据量超过了初始分配的空间,就会导致空间溢出,无法继续存储新的数据。

  2. 插入和删除效率:尽管顺序表的插入和删除操作在某些情况下可以高效完成,但在某些特定位置(如头部或中间位置)插入或删除元素时,可能需要移动大量的元素,这会导致效率降低。

  3. 扩展性差:由于静态分配顺序表的空间大小是固定的,因此在面对不断增长的数据量时,需要重新分配更大的空间并复制原有的数据,这不仅增加了操作的复杂性,还可能导致数据丢失或不一致。

  4. 灵活性不足:与链表等动态数据结构相比,静态分配顺序表的灵活性较差。链表可以根据需要动态地分配和释放内存,而顺序表则需要在初始化时就确定空间大小,这在某些应用中可能不够灵活。

综上所述,静态分配顺序表在访问速度快、空间利用率高等方面具有优势,但在空间限制、插入和删除效率、扩展性和灵活性等方面存在不足。因此,在选择使用静态分配顺序表时,需要根据具体的应用场景和需求进行权衡和选择。

五 示例代码

以下是一个静态分配顺序表的简单示例代码,包括初始化、插入、删除、查找和更新元素等基本操作的实现。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define MAXSIZE 100 // 假设顺序表的最大长度为100

typedef struct {
    int data[MAXSIZE]; // 存储元素的数组
    int length;        // 当前顺序表的长度
} SeqList;

// 初始化顺序表
void InitList(SeqList *L) {
    L->length = 0;
}

// 插入元素
bool InsertList(SeqList *L, int elem) {
    if (L->length >= MAXSIZE) {
        // 顺序表已满,无法插入新元素
        return false;
    }
    L->data[L->length] = elem; // 将新元素添加到顺序表末尾
    L->length++;              // 更新顺序表长度
    return true;
}

// 删除指定位置的元素
bool DeleteList(SeqList *L, int pos) {
    if (pos < 1 || pos > L->length) {
        // 删除位置不合法
        return false;
    }
    for (int i = pos; i < L->length; i++) {
        L->data[i - 1] = L->data[i]; // 将后续元素前移
    }
    L->length--; // 更新顺序表长度
    return true;
}

// 查找元素
int GetElem(SeqList L, int pos, int *elem) {
    if (pos < 1 || pos > L.length) {
        // 查找位置不合法
        return 0;
    }
    *elem = L.data[pos - 1]; // 返回查找位置的元素值
    return 1;
}

// 更新指定位置的元素值
bool UpdateElem(SeqList *L, int pos, int newElem) {
    if (pos < 1 || pos > L->length) {
        // 修改位置不合法
        return false;
    }
    L->data[pos - 1] = newElem; // 修改指定位置的元素值
    return true;
}

// 打印顺序表
void PrintList(SeqList L) {
    for (int i = 0; i < L.length; i++) {
        printf("%d ", L.data[i]);
    }
    printf("\n");
}

int main() {
    SeqList L;
    InitList(&L);

    // 插入元素
    InsertList(&L, 10);
    InsertList(&L, 20);
    InsertList(&L, 30);

    // 打印顺序表
    printf("List after insertion: ");
    PrintList(L);

    // 更新元素
    UpdateElem(&L, 2, 25);

    // 打印顺序表
    printf("List after update: ");
    PrintList(L);

    // 删除元素
    DeleteList(&L, 2);

    // 打印顺序表
    printf("List after deletion: ");
    PrintList(L);

    // 查找元素
    int elem;
    if (GetElem(L, 1, &elem)) {
        printf("Element at position 1: %d\n", elem);
    } else {
        printf("Invalid position for element retrieval.\n");
    }

    return 0;
}

以下是该代码在main函数中执行后的输出样子:

List after insertion: 10 20 30 
List after update: 10 25 30 
List after deletion: 10 30 
Element at position 1: 10

解释:

  1. InsertList 函数被调用了三次,将元素 10、20 和 30 插入到顺序表 L 中。

  2. PrintList 函数被调用,输出顺序表的内容,显示 10 20 30

  3. UpdateElem 函数被调用,将顺序表中位置 2(注意位置是从 1 开始的)的元素从 20 更新为 25。

  4. 再次调用 PrintList 函数,输出更新后的顺序表内容,显示 10 25 30

  5. DeleteList 函数被调用,删除顺序表中位置 2 的元素(现在是 25)。

  6. 第三次调用 PrintList 函数,输出删除元素后的顺序表内容,显示 10 30

  7. GetElem 函数被调用,尝试获取位置 1 的元素。因为位置合法,所以函数返回 1,并且通过指针 elem 返回了元素值 10。

  8. 输出通过 GetElem 函数获取到的元素值,显示 Element at position 1: 10

注意,这段代码假设了静态顺序表的最大长度为 MAXSIZE,定义为 100。在实际应用中,这个值可能需要根据具体的应用场景进行调整。此外,这个简单的例子没有包含错误处理,例如当尝试插入超过顺序表最大长度的元素时,InsertList 函数只是简单地返回 false,并没有给出明确的错误信息。在实际应用中,通常会添加更详细的错误处理逻辑。

总结

通过对顺序表静态分配实现方式的详细探讨,我们深入了解了其概念、实现过程以及优缺点。

静态分配顺序表具有存储密度高、空间利用率好等优点,适用于数据元素数量确定且不易发生变化的场景。

然而,其缺点也不容忽视,如空间扩展性差、插入和删除操作效率较低等。

因此,在实际应用中,我们需要根据具体需求和数据特点来选择合适的顺序表实现方式。

示例代码部分展示了静态分配顺序表的基本操作,包括初始化、插入、删除、查找和修改元素等。

这些操作的实现方式简单明了,为读者提供了实践操作的参考。

综上所述,顺序表静态分配实现方式在数据结构领域中具有重要地位。通过本文的学习,相信读者已经对顺序表有了更深入的理解和掌握,能够在实际应用中灵活运用。

这篇文章到这里就结束了

谢谢大家的阅读!

如果觉得这篇博客对你有用的话,别忘记三连哦。

我是豌豆射手^,让我们我们下次再见

在这里插入图片描述

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

matplotlib画图:子图中坐标轴与标题重合...

如下图 只要在代码最后加入 plt.tight_layout() 就可以自动调节

江苏开放大学2024年春《市政管理学050011》第一次形考作业参考答案

答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 电大搜题 多的用不完的题库&#xff0c;支持文字、图片搜题…

C语言编译和链接理解

一. 翻译环境和运行环境 二. 翻译环境&#xff1a;预编译编译汇编链接 三运行环境 一. 翻译环境和运行环境 &#xff1a; 1.翻译环境和运行环境&#xff1a;在ANSI C的任何⼀种实现中&#xff0c;存在两个不同的环境。第1种是翻译环境&#xff0c;在这个环境中源代码被转换为…

散热风扇220v交流12v直流12038轴流风机配电箱机柜散热风扇15050

品牌&#xff1a;威驰 颜色分类&#xff1a;11025风扇220v含油,11025风扇220v纯铜双滚珠,12025风扇220v含油,12025风扇220v纯铜双滚珠,12025风扇24V纯铜双滚珠,12025风扇12V纯铜双滚珠,12038风扇220v含油,12038风扇110V含油,12038风扇220v纯铜双滚珠,12038风扇110v纯铜双滚珠,…

如何把PNG图片转换成CAD图纸DWG格式

环境&#xff1a; CAD2021 PNG图片 问题描述&#xff1a; 如何把PNG图片转换成CAD图纸DWG格式 解决方案&#xff1a; 将PNG图像转换为CAD文件&#xff08;如DXF或DWG格式&#xff09;是设计和工程领域中常见的需求之一。幸运的是&#xff0c;有几种工具和软件可以帮助完成…

幻兽帕鲁服务器多少钱?2024年Palworld服务器价格整理

2024年全网最全的幻兽帕鲁服务器租用价格表&#xff0c;阿里云幻兽帕鲁游戏服务器26元1个月、腾讯云32元一个月、京东云26元一个月、华为云24元1个月&#xff0c;阿腾云atengyun.com整理最新幻兽帕鲁专用4核16G、8核16G、8核32G游戏服务器租用价格表大全&#xff1a; 阿里云幻…

Java异常机制

异常体系图 Throwable Throwable 是 Java 语言中所有错误与异常的超类。 Throwable 包含两个子类&#xff1a;Error&#xff08;错误&#xff09;和 Exception&#xff08;异常&#xff09;&#xff0c;它们通常用于指示发生了异常情况。 Throwable 包含了其线程创建时线程执…

计算机组成原理 浮点数溢出

阶码同样有位数限制 浮点数的溢出并不以尾数溢出来判断&#xff0c;尾数溢出可以通过右规操作得到纠正。运算结果是否溢出主要看结果的指数是否发生了上溢&#xff0c;因此是由指数上溢来判断的。可能导致溢出的情况&#xff1a;即所有涉及阶码运算的情况 右规和尾数舍入&…

HBase Shell基本操作

一、进入Hbase Shell客户端 先在Linux Shell命令行终端执行start-dfs.sh脚本启动HDFS&#xff0c;再执行start-hbase.sh脚本启动HBase。如果Linux系统已配置HBase环境变量&#xff0c;可直接在任意目录下执行hbase shell脚本命令&#xff0c;就可进入HBase Shell的命令行终端环…

【JavaWeb】Day22.maven安装介绍

目录 一.初识Maven 什么是maven? Maven的作用 二.Maven概述 1. Maven介绍 2.Maven模型 3. Maven仓库 三. Maven安装 1.下载 2. 安装步骤 1. 解压安装 2. 配置本地仓库 3.配置阿里云私服 4. 配置Maven环境变量 一.初识Maven 什么是maven? Maven是apache旗下的一个…

2024年数字IC秋招-复旦微电子-数字前端/验证-笔试题

文章目录 前言一、基础题/选做题1、什么是DMA&#xff0c;主要优点是什么&#xff0c;为什么这是它的优点2、SV的代码如下&#xff0c;给出$display中变量的值3、列出4bit格雷码编码&#xff0c;画出二进制码转格雷码电路图4、如何从慢时钟域捕获快时钟域脉冲信号&#xff0c;画…

行为管理设置能监控或者检测哪些东西

3 月 27 日&#xff0c;国新办举行“推动高质量发展”系列主题新闻发布会&#xff0c;浙江省省长王浩&#xff1a;全省市场经营主体 1040 万户&#xff0c;相当于平均每 6.5 个浙江人就有 1 个老板。 不由让小编想到&#xff0c;这么多老板&#xff0c;那么老板创办企业也怪不容…

蓝桥杯省三保底代码——数显+按键功能实现

目录 前言 一、为什么能保底省三 二、数显模块的实现 1.数码管显示​编辑 1&#xff09;断码表 2&#xff09;位选 3&#xff09;段选 4&#xff09;扫描 2.菜单 三、按键功能的实现 1.按键扫描 2.菜单切换 四、完整代码演示 五、结语 前言 上一期介绍全家桶时&…

【容器源码篇】Set容器(HashSet,LinkedHashSet,TreeSet的特点)

文章目录 ⭐容器继承关系&#x1f339;Set容器&#x1f5d2;️HashSet源码解析构造方法public HashSet()public HashSet(Collection<? extends E> c)public HashSet(int initialCapacity, float loadFactor)HashSet(int initialCapacity, float loadFactor, boolean dum…

OpenHarmony实战开发-Web组件的使用

介绍 本篇Codelab使用ArkTS语言实现一个简单的免登录过程&#xff0c;向大家介绍基本的cookie管理操作。主要包含以下功能&#xff1a; 获取指定url对应的cookie的值。设置cookie。清除所有cookie。免登录访问账户中心。 原理说明 本应用旨在说明Web组件中cookie的管理操作。…

蓝桥杯_day6

文章目录 不同路径不同路径II拿金币珠宝的最高价值 不同路径 【题目描述】 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为…

主成成分分析法

问题引入&#xff1a; 公司评价 假设你是一个公司的财务经理&#xff0c;掌握了公司所有数据&#xff0c;如:固定资产、流动资金、借贷的数额和期限、各种税费、工资支出、原料消耗、产值、利润、折扣、职工人数、分工和教育程度等等&#xff0c;你要如何选择关键因素进行汇报…

宝宝灯塔:成都辅助生殖市场研究,海外试管成热门

据宝宝灯塔网介绍&#xff1a;在成都的辅助生殖市场中&#xff0c;生殖医院一直是主体&#xff0c;它们提供专业的医疗服务和治疗&#xff0c;帮助不孕不育人群实现生育梦想。然而&#xff0c;随着科技的进步和市场的变化&#xff0c;互联网企业也开始涉足这一领域&#xff0c;…

盏燕生物科技将出席2024第七届燕窝天然滋补品博览会

参展企业介绍 深圳市盏燕生物科技有限公司&#xff0c;办公室地址位于中国第一个经济特区&#xff0c;鹏城深圳&#xff0c;深圳市龙岗区平湖街道禾花社区富安大道18号亚钢工贸大楼1栋1017A&#xff0c;我公司主要提供一般经营项目是&#xff1a;初级农产品、海产品、化妆品、…

低代码开发能用在哪些行业?

低代码开发平台&#xff08;Low code development platform&#xff09;是无需编码&#xff08;0代码&#xff09;或通过少量代码就可以快速生成应用程序的开发平台。通过可视化进行应用程序开发的方法&#xff0c;使具有不同经验水平的开发人员可以通过图形化的用户界面&#…