数据结构<一>顺序表

目录

一、线性表的定义

二、顺序表的定义

三、顺序表的定义及初始化

四、顺序表的插入

五、顺序表的删除

六、顺序表的修改

七、顺序表的查找

八、顺序表的显示

九、测试主程序

一、线性表的定义
复制代码
线性表是一种基本的数据结构,它是由n个数据元素a[1]、a[2]、...、a[n]组成的有限序列。
线性表中的数据元素之间呈现出一对一的顺序关系,每个元素都有一个前驱和后继元素,除了第一个元素没有前驱,最后一个元素没有后继,它可以用顺序存储结构和链式存储结构来实现。
举一个例子,一个班级的学生名单可以看作是一个线性表,其中每一个学生都是一个数据元素,学生名单中的数据元素之间存在一定的顺序关系,每个学生都有一个前一个和后一个学生,除了第一个学生没有前一个学生,最后一个学生没有后一个学生。如果使用顺序存储结构来实现学生名单,那么每个学生的信息将被存储在一个数组中,如果使用链式存储结构,可以将每个学生的信息存储在一个链表的节点中。无论是使用数组还是链表,都可以对学生名单进行插入、删除、查找和遍历等常见的操作,这些操作都是线性表的基本操作。
线性表作为一种基本的数据结构类型,在计算机存储器中的表示一般有两种形式,一种是顺序存储,一种是链式存储。
二、顺序表的定义
复制代码
线性表的顺序存储又叫顺序表。线性表的顺序存储是指将数据元素按照其逻辑顺序依次存储在一组连续的物理位置上,通过数组来实现。顺序存储结构以连续的存储单元顺序存放线性表的元素,可以直接访问元素,查找和遍历较快,但插入和删除操作需要移动大量元素,效率较低。
线性表的顺序存储可以用一维数组来实现。数组的下标从0开始,表示元素在数组中的位置。
具体实现步骤如下:
1. 定义一个数组,用来存储线性表中的元素,数组大小为线性表的长度;
2. 将线性表中的元素按照逻辑顺序存储在数组中,即将第i个元素存储在数组中下标为i-1的位置上;
3. 可以通过下标访问具体的元素,数组下标从0开始,第i个元素的下标为i-1;
4. 可以通过数组下标修改或者查询元素的值;
5. 插入元素时,需要将插入点之后的元素依次后移,然后在插入点处插入新元素;
6. 删除元素时,需要将删除点之后的元素依次前移,然后删除最后一个元素。
顺序表具有随机存取的优点,可以直接按照下标访问任意位置的元素。但是因为删除或插入操作时需要移动大量元素,所以其插入和删除操作效率较低。
三、顺序表的定义及初始化
cpp 复制代码
//顺序表的定义
#define MAXSIZE 100
​
typedef struct
{
    int data[MAXSIZE]; // 存储顺序表的数组
    int length;        // 顺序表长度
} sqlist_t;    
​
//顺序表的初始化
sqlist_t *sqlist_init(void)
{
    sqlist_t *list = (sqlist_t *)malloc(sizeof(sqlist_t));
    list->length = 0;                          // 顺序表的长度初始化为0
    memset(list->data, 0, sizeof(list->data)); // 清空数组的值
    return list;
}
四、顺序表的插入
复制代码
插入元素时,需要将插入点之后的元素依次后移,然后在插入点处插入新元素;
例如,在 {1,2,3,4,5} 的第 3 个位置上插入元素 6,实现过程如下:1. 遍历至顺序表存储第 3 个数据元素的位置,如图所示:
复制代码
2. 将元素 3 以及后续元素 4 和 5 整体向后移动一个位置,如图所示:
复制代码
3.将新元素 6 放入腾出的位置,如图所示:
cpp 复制代码
// 顺序表的插入
int sqlist_insert(sqlist_t *list, int index, int val)
{
    // index < 1  , index 是从1 开始的
    // index > list->length + 1  大于顺序表的长度是 list->length
    if (index < 1 || index > list->length + 1)
    {
        return -1; // 失败 -1
    }
    //  最后一个元素开始往后移动
    //  倒数第二个元素 移动到倒数第一个元素的位置, 一直移动到index 的位置
    //  index 指向的元素也要往后移动
    for (int i = list->length - 1; i >= index - 1; i--)
    {
        // 4 3 2
        list->data[i + 1] = list->data[i]; // 往后移动1个元素
    }
    list->data[index - 1] = val; // 插入元素
    list->length++;              // 顺序表的长度增加1
    return 0;
}
五、顺序表的删除
复制代码
删除元素时,需要将删除点之后的元素依次前移,然后删除最后一个元素。例如,从 {1,2,3,4,5} 中删除元素 3 的过程如图所示:
cpp 复制代码
// 顺序表的删除
int sqlist_delete(sqlist_t *list, int index, int *pval)
{
    // index < 1  , index 是从1 开始的
    // index > list->length + 1  大于顺序表的长度是 list->length
    if (index < 1 || index > list->length + 1)
    {
        return -1; // 失败 -1
    }
    *pval = list->data[index - 1]; //  先将删除的元素赋值给pval
​
    // 把后面的元素往前移动
    for (int i = index - 1; i < list->length - 1; i++)
    {
        list->data[i] = list->data[i + 1]; // 往前移动1个元素
    }
    list->length--; // 顺序表的长度减少1
    return 0;
}
六、顺序表的修改
cpp 复制代码
// 顺序表的修改
int sqlist_modify(sqlist_t *list, int index, int newval)
{
    // index < 1  , index 是从1 开始的
    // index > list->length + 1  大于顺序表的长度是 list->length
    if (index < 1 || index > list->length + 1)
    {
        return -1; // 失败 -1
    }
    list->data[index - 1] = newval; // 把newval 的值更新到数组内
    return 0;
}
七、顺序表的查找
cpp 复制代码
// 顺序表的查找
int sqlist_search(sqlist_t *list, int val)
{
    for (int i = 0; i < list->length; i++)
    {
        if (val == list->data[i]) // 查找元素
        {
            return i + 1; // 找到返回元素的位置
        }
    }
    return 0; // 没有找到返回0
}
八、顺序表的显示
cpp 复制代码
// 顺序表的显示
int sqlist_print(sqlist_t *list)
{
    for (int i = 0; i < list->length; i++)
    {
        printf("%d ", list->data[i]);
    }
    printf("\n");
    return 0;
}
九、测试主程序
cpp 复制代码
//测试主程序
int main(int argc, char const *argv[])
{
    sqlist_t *L = sqlist_init();
    for (int i = 0; i < 5; i++)
    {
        sqlist_insert(L, i + 1, i + 1);
    }
    sqlist_print(L);
    sqlist_insert(L, 3, 6);
    sqlist_print(L);
    int value;
    sqlist_delete(L, 3, &value);
    printf("删除的元素是:%d\n", value);
    sqlist_print(L);
    sqlist_delete(L, 3, &value);
    printf("删除的元素是:%d\n", value);
    sqlist_print(L);
    sqlist_modify(L, 3, 40);
    sqlist_print(L);
    int pos = sqlist_search(L, 4);
    if (pos > 0) // 查找元素
    {
        printf("%d 查找的元素在第%d个位置\n", 4, pos);
    }
    else
    {
        printf("%d 查找的元素不存在\n", 4);
    }
​
    pos = sqlist_search(L, 40);
    if (pos > 0) // 查找元素
    {
        printf("%d 查找的元素在第%d个位置\n", 40, pos);
    }
    else
    {
        printf("%d 查找的元素不存在\n", 40);
    }
​
    return 0;
}
​
相关推荐
CHANG_THE_WORLD1 小时前
Linux C 多线程 TCP 并发服务器:从 `accept()` 到工作线程的完整解析
linux·服务器·c语言
敲上瘾1 小时前
Linux系统调用mmap文件映射与malloc简单模拟实现指南
linux·服务器·c语言·缓存
Fairy要carry1 小时前
面试-训练显存占用估计
算法
触底反弹1 小时前
💥 暴力解 LeetCode 导致 OOM:10000 行数据撑爆 V8 堆内存的完整排查
javascript·算法·面试
cheems95272 小时前
[算法手记]二叉树中序,层序遍历,统计树高
算法
wdfk_prog11 小时前
嵌入式面试真题第 11 题:RTOS 优先级翻转与实时任务阻塞的通用治理
c语言·缓存·面试·职场和发展·架构
QXWZ_IA13 小时前
1库1图1批是什么?千寻位置公安地图数据体系详解
科技·算法·能源·媒体·交通物流·政务
c2385614 小时前
Bug 猎手入门指南
c++·算法·bug