【数据结构】 顺序表的基本操作 (C语言版)

news2024/11/26 14:40:45

一、顺序表

1、顺序表的定义:

线性表的顺序存储结构,即将表中的结点按逻辑顺序依次存放在一组地址连续的存储单元里。这种存储方式使得在逻辑结构上相邻的数据元素在物理存储上也是相邻的,可以通过数据元素的物理存储位置来反映其逻辑关系。

数据结构中的顺序表是一种线性表,它在计算机内存中以数组的形式保存。顺序表采用顺序存储结构,即将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。这种存储方式使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系。

2、顺序表的优缺点:

顺序表的优点是便于随机访问查找,时间复杂度为O(1)。缺点是不便于插入和删除操作,尤其是中间或头部的插入和删除操作,时间复杂度为O(n)。因此,顺序表适用于需要大量访问元素,尾部插入和删除较多的场景。

顺序表的优点:
  1. 存储密度大:数据元素在内存中紧密排列,空间利用率高。
  2. 存取速度快:可以通过下标直接访问任意位置的元素,时间复杂度为O(1)。
  3. 空间连续:一次性申请一定大小的存储空间,便于管理和控制。
顺序表的缺点:
  1. 插入和删除操作效率低下:需要移动大量数据元素,特别是当插入或删除的位置位于中间或头部时,时间复杂度为O(N)。
  2. 长度固定:无法自由扩展或收缩,当元素个数超过预先分配的空间时会导致溢出,而元素个数远少于预先分配的空间时则会造成空间浪费。
  3. 动态调整困难:顺序表的空间必须预先分配,无法根据实际需求动态调整。

二、顺序表的基本操作算法(C语言)

1、宏定义
typedef int Status;
typedef char ElemType;
2、创建结构体
//定义类型
typedef struct {
    char *elem;
    int length;
}SqList;
3、顺序表初始化
//初始化
Status InitList_sq(SqList &L){//引用型参数
//	L.elem=new char[10];
    L.elem=new ElemType[10];
    if(!L.elem){
        //exit (-1);
        exit (OVERFLOW);
    }
    L.length=0;
    return OK;
}
4、顺序表插入

在顺序表L的第 i 个元素之前插入新的元素e

1.找到第i-1个位置   

2.将元素e插入

时间复杂度T(n)=O(n)

顺序表的空间复杂度S(n)=O(1)    没有占用辅助空间

//插入
Status InsertList_sq(SqList &L,int i,ElemType e){
    if(i<1 || i>L.length+1){
        return ERROR;
    }
    if(L.length==MAXSIZE){
        return ERROR;
    }
    for (int j=L.length-1;j>=i-1;j--){
        L.elem[j+1]=L.elem[j];
    }
    L.elem[i-1] = e;
    L.length++;
    return OK;
}
4、顺序表取值 
//取值
Status GetElem(SqList L, int i, ElemType &e){
    if(i<1 || i>L.length) {
        return ERROR;
    }
    e = L.elem[i-1];
    return OK;
}
5、求顺序表的长度
//求长度
int GetLength(SqList L){
    return L.length;
}
6、顺序表查找

//查找
Status LocateElem(SqList L,ElemType e)
{
    for (int i = 0; i < L.length; i++) {
        if (L.elem[i] == e)
            return i + 1;
    }
    return 0;
}
7、顺序表删除

插入i-1个位置,删除第i个位置的元素

//删除
Status ListDelete(SqList &L,int i,ElemType &e)
{
    if ((i<1) || (i>L.length+1)) return ERROR;
//    if (L.length==MAXSIZE) return 0;       //不用判空
    e = L.elem[i - 1];
    for (int j=i;j<=L.length-1;j++)             //for (j=i-1;j<=L.length-1;j++)
        L.elem[j-1]=L.elem[j];             // L.elem[j]=L.elem[j+1];
    --L.length;
    return  OK;
}

四、顺序表的全部代码(C语言)

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

#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define MAXSIZE 10


typedef int Status;
typedef char ElemType;

//定义类型
typedef struct {
    char *elem;
    int length;
} SqList;

//顺序表初始化
//int InitList_sq(SqList &L){   //引用型参数
Status InitList_sq(SqList &L) {
//	L.elem=new char[10];
    L.elem = new ElemType[10];
    if (!L.elem) {
        //exit (-1);
        exit(OVERFLOW);
    }
    L.length = 0;
//	return 1;
    return OK;
}

//功能菜单
int choice() {
    printf("==================================\n");
    printf("         顺序表操作功能菜单        \n");
    printf("          1、插入元素            \n");
    printf("          2、查询表长            \n");
    printf("          3、按位查找            \n");
    printf("          4、按值查找            \n");
    printf("          6、批量插入            \n");
    printf("          7、退出程序            \n");
    printf("==================================\n");
    return 0;
}

//顺序表插入
Status InsertList_sq(SqList &L, int i, ElemType e) {
    if (i < 1 || i > L.length + 1) {
        return ERROR;
    }
    if (L.length == MAXSIZE) {
        return ERROR;
    }
    for (int j = L.length - 1; j >= i - 1; j--) {
        L.elem[j + 1] = L.elem[j];
    }
    L.elem[i - 1] = e;
    L.length++;
    return OK;
}

//顺序表取值
Status GetElem(SqList L, int i, ElemType &e) {
    if (i < 1 || i > L.length) {
        return ERROR;
    }
    e = L.elem[i - 1];
    return OK;
}

//求顺序表长度
int GetLength(SqList L) {
    return L.length;
}

//顺序表查找
Status LocateElem(SqList L, ElemType e) {
    for (int i = 0; i < L.length; i++) {
        //printf("%c",L.elem[i]);
        if (L.elem[i] == e)
            return i + 1;
    }
    return 0;
}

//顺序表删除
Status ListDelete(SqList &L, int i, ElemType &e) {
    if ((i < 1) || (i > L.length + 1)) return ERROR;
    e = L.elem[i - 1];
    for (int j = i; j <= L.length - 1; j++)         //j=i-1
        L.elem[j - 1] = L.elem[j];             // L.elem[j]=L.elem[j+1];
    L.length--;
    return OK;
}


int main() {
    //printf("Hell Word");
    //struct List list;
    SqList sqList;

    printf("顺序表正在初始化....\n");
    Status returnStatus = InitList_sq(sqList);
    if (returnStatus == OK) {
        printf("顺序表初始化成功!\n");
    } else {
        printf("顺序表初始化失败!\n");
    }

    choice();

    while (1) {

        int flag;
        printf("请输入所需的功能编号:\n");
        scanf("%d", &flag);

        switch (flag) {
            case 1: {//插入
                // printf("length = %d \n", sqList.length);
                // int listLength = GetLength(sqList);
                // printf("%d ", listLength);
                int insertLocation;
                ElemType insertElem;
                printf("请输入插入元素位置及插入元素(请在英文状态下输入例如:1,a): \n");
                scanf("%d,%c", &insertLocation, &insertElem);
                Status insertStatus = InsertList_sq(sqList, insertLocation, insertElem);
                if (insertStatus == OK) {
                    printf("向顺序表中第%d个位置,插入元素%c成功!\n", insertLocation, insertElem);
                } else {
                    printf("向顺序表中插入元素失败!\n");
                }
                choice();
            }
                break;
            case 2: {//求顺序表的长度
                printf("顺序表的长度为:%d  。\n", GetLength(sqList));
                choice();
            }
                break;
            case 3: {//取值
                Status no;
                printf("请输入需要查询的元素的位置:\n");
                scanf("%d", &no);
                ElemType element;
                Status GetElemStatus = GetElem(sqList, no, element);
                //printf("element = %c ", element);
                printf("在顺序表中第%d个元素为:%c 。 \n", no, element);
                if (GetElemStatus = OK) {
                    printf("在顺序表中第%d个元素为:%c 。 \n", no, element);
                } else {
                    printf("查找顺序表中第%d个元素失败。 \n", no);
                }
                choice();
            }
                break;
            case 4: {//查找
                ElemType findElem;
                printf("请输入想要查找元素:\n");
                getchar();    //用于接收回车
                scanf("%c", &findElem);
                int locate = LocateElem(sqList, findElem);
                if (locate != 0) {
                    printf("所需查找的元素%c存在于顺序表中,它的在第%d位置。  \n", findElem, locate);
                } else {
                    printf("所需查找的元素%c不存在于顺序表中!  \n", findElem);
                }
                //printf("locate = %d ", locate);
                choice();
            }
                break;
            case 5: {//删除
                //ListDelete_DuL(list,1);
                Status delindex;
                ElemType delElem;
                printf("请输入想要删除元素的位置:\n");
                scanf("%d", &delindex);
                Status delreturn = ListDelete(sqList, delindex, delElem);
                if (delreturn == OK) {
                    printf("在顺序表中删除第%d个元素为:%c 。 \n", delindex, delElem);
                } else {
                    printf("在顺序表中删除第%d个元素失败! \n", delindex);
                }
                printf("顺序表的长度为:%d  \n", GetLength(sqList));
                //printf("delindex = %d ", delindex);
                choice();
            }
                break;
            case 6: {//批量插入
                int on;
                printf("请输入想要插入的元素个数:\n");
                scanf("%d", &on);
                ElemType array[on];
                for (int i = 1; i <= on; i++) {
                    getchar();
                    printf("向顺序表第%d个位置插入元素为:", (i));
                    scanf("%c", &array[i]);
                }

                for (int i = 1; i <= on; i++) {
                    Status insertStatus = InsertList_sq(sqList, i, array[i]);
                    if (insertStatus == OK) {
                        printf("向顺序表中第%d个位置,插入元素%c成功!\n", i, array[i]);
                    } else {
                        printf("向顺序表中第%d个位置插入元素失败!\n", i);
                    }
                }
                choice();
            }
                break;
            case 7: {//退出程序
                return 0;
            }
                break;
            default: {
                printf("输入错误,无此功能,请检查输入:\n\n");
            }
        }
    }
}

五、结果

 

 

 

 

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

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

相关文章

【Go面试向】实现map稳定的有序遍历的方式

问题 大家好 我是寸铁&#x1f44a; 总结了一篇实现map稳定的有序遍历的方式探讨的文章✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 你对 map 了解多少&#xff1f;如果要实现第一个稳定的有序遍历有哪些方式&#xff1f; 回答 你对 map 了解多少&#xff1f; 我对map有一定的…

20234.1.20 使用idea进行Java的helloworld程序开发

20234.1.20 使用idea进行Java的helloworld程序开发 idea毕竟是jtbrain的产品&#xff0c;整体和pycharm相同&#xff0c;初步使用感受比eclipse更亲切 一、程序结构 project&#xff08;项目&#xff0c;工程&#xff09; module&#xff08;模块&#xff09; package&…

Halcon基于描述符的模板匹配

Halcon基于描述符的模板匹配 与基于透视形变的模板匹配类似&#xff0c;基于描述符的模板匹配能够在物体处于透视形变的状态下进行匹配&#xff0c;并且已标定和未标定的相机图像都适用。与透视形变不同的是&#xff0c;它的模板不是根据边缘轮廊创建的&#xff0c;而是根据特…

【每日一题】1. 牛客网——合并两个有序数组

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ &#x1f64f;小杨水平有限&#xff0c;欢迎各位大佬指点&…

hot100:06三数之和

题目链接&#xff1a; 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 算法思想&#xff1a; 使用双指针的思想&#xff0c;首先需要先对数组进行排序&#xff0c;让数组满足单调性&#xff0c;这样在相加的时候更加方便更新条件&#xff1b;再遍历…

代码随想录二刷 | 二叉树 | 修剪二叉搜索树

代码随想录二刷 | 二叉树 | 修剪二叉搜索树 题目描述解题思路代码实现 题目描述 669.修剪二叉搜索树 给定一个二叉搜索树&#xff0c;同时给定最小边界 L 和最大边界 R。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[L, R]中 (R>L) 。你可能需要改变树的根节点&…

Spring RabbitMQ那些事(3-消息可靠传输和订阅)

目录 一、序言二、生产者确保消息发送成功1、为什么需要Publisher Confirms2、哪些消息会被确认处理成功 三、消费者保证消息被处理四、Spring RabbitMQ支持代码示例1、 application.yml2、RabbigtMQ配置3、可靠生产者配置4、可靠消费者配置5、测试用例 一、序言 在有些业务场…

安装MySQL8.0

安装MySQL8.0 第一步我们先把MySQL8.0的镜像拉一下&#xff08;建议在网络好的情况下 下拉镜像&#xff09; 之后我们在创造一个容器 conf目录 必须提前上传my.cnf文件到/data/conf目录 并且它与window中的配置文件my.ini后缀名是不一样 data目录 数据保存到宿主机中&#x…

Laya3.0 相机使用

摄像机&#xff0c;是3D场景里边最经常使用的对象了。 官方文档&#xff1a;点击这里学习 1.投影 Projection 透视&#xff1a; 模拟人眼的视觉效果&#xff0c;近大远小。模拟物理世界的规律&#xff0c;将眼睛或相机抽象成一个点&#xff0c;此时视锥体内的物体投影到视平…

logstack 日志技术栈-04-opensource 开源工具 Syslog-ng+Highlight.io

5. Syslog-ng Syslog-ng 是一个开源的日志管理解决方案&#xff0c;主要用于收集和处理日志数据。它可以从多种源收集日志&#xff0c;包括系统日志、网络设备日志和第三方应用日志。 然后将日志解析、分类、重写和关联到统一格式中&#xff0c;然后将其存储或安全地传输到不同…

【C/Python】用GTK实现多文档窗体程序

一、用C语言 在GTK&#xff08;GIMP Toolkit&#xff09;中实现多文档接口&#xff08;MDI&#xff09;程序可以使用多种方法。GTK本身并没有提供专用的MDI窗口小部件&#xff0c;但可以使用标签页&#xff08;Notebook&#xff09;或多个窗口&#xff08;Window&#xff09;来…

力扣精选算法100题——串联所有单词的字串(滑动窗口专题)

本题链接——串联所有单词的字串 本题和找到字符串中所有字母异位词题目非常相似&#xff0c;思路都是一样。通过自己的大脑能发现其中的相似之处。 第一步&#xff1a;了解题意 就按实例来分析吧&#xff0c;这样更通俗易懂。 words["ab","cd","ef…

小程序学习-19

Vant Weapp - 轻量、可靠的小程序 UI 组件库 ​​​​​ Vant Weapp - 轻量、可靠的小程序 UI 组件库 安装出现问题&#xff1a;rollbackFailedOptional: verb npm-session 53699a8e64f465b9 解决办法&#xff1a;http://t.csdnimg.cn/rGUbe Vant Weapp - 轻量、可靠的小程序…

如何证明一个矩阵是可逆矩阵?

想要证明一个矩阵是可逆矩阵&#xff0c;其实就是要知道可逆矩阵具有哪些性质。荒原之梦考研数学网把线性代数中可逆矩阵的常用性质都整理在下面了&#xff1a;

供应链安全项目in-toto开源框架详解

引言&#xff1a;in-toto 是一个开源框架&#xff0c;能够以密码学的方式验证构件生产路径上的每个组件和步骤。它可与主流的构建工具、部署工具进行集成。in-toto已经被CNCF技术监督委员会 (Technical Oversight Committee&#xff0c;TOC)接纳为CNCF孵化项目。 1. 背景 由于…

String在VS与Linux下的区别

目录 一、string的成员 1.VS 2.Linux 二、string的扩容机制 1. VS 2.Linux 一、string的成员 string是C标准库中的一个类模板&#xff0c;用于表示和操作字符串 string在 Windows 与 Linux 中的成员不是相同的 1.VS 4个成员&#xff1a;_str , _size , _capacity 和…

第三课:GPT

文章目录 第三课&#xff1a;GPT1、学习总结&#xff1a;GPT出现的原因GPT的方法原理目前存在的问题无监督的预训练优化目标模型结构 监督微调课程ppt及代码地址 2、学习心得&#xff1a;3、经验分享&#xff1a;4、课程反馈&#xff1a;5、使用MindSpore昇思的体验和反馈&…

SpringMVC(八)处理AJAX请求

一、处理AJAX之准备工作: 首先我们创建一个新的工程: 我们将pom.xml复制过来: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-in…

JVM之java内存区域[1](程序计数器、栈)

文章目录 版权声明零 运行时数据区一 程序计数器1.1 加载阶段1.2 执行阶段1.3 多线程情况 二 栈2.1 java虚拟机栈2.2 java虚拟机栈帧的组成2.2.1 局部变量表2.2.2 操作数栈2.2.3 帧数据 2.3 栈内存溢出2.4 设置帧大小2.5 本地方法栈 版权声明 本博客的内容基于我个人学习黑马程…

OCS2 入门教程(六)- Double Integrator

系列文章目录 前言 双积分器示例是我们最简单的问题。它模拟了一个沿 x 方向移动的一维点质量。模型是线性的&#xff0c;成本函数是二次函数。目标点通过参考管理器模块设置为二次成本。 一、查看文件结构 1.1 ocs2_double_integrator 文件夹 . ├── auto_generated ├─…