数据结构(一)顺序表

目录

  • 一、概念
    • (一)数据结构的三元素
      • 1. 逻辑结构
        • (1)线性结构
        • (2)非线性结构
      • 2. 存储结构
        • (1)顺序存储
        • (2)链式存储
        • (3)索引存储
      • 3. 运算
    • (二)时间复杂度
      • 1. 线性阶
      • 2. 常数阶
      • 3. 平方阶
      • 4. 三次方阶
      • 5. 对数阶
      • 6. 时间复杂度排序
  • 二、顺序表
    • (一)逻辑结构
    • (二)存储结构
    • (三)操作
      • 1. 创建顺序表
        • (1)返回值是创建的顺序表
        • (2)参数传入想要创建的顺序表
          • ① 函数声明
          • ② 注意点:
          • ③代码实现
      • 2. 插入元素(尾插、任意位置插入)
        • (1)尾插
          • ① 函数声明
          • ② 注意点:
          • ③代码实现
        • (2)任意位置插入
          • ① 函数声明
          • ② 注意点:
          • ③代码实现
      • 3. 删除元素(尾删、任意位置删除)
        • (1)尾删
          • ① 函数声明
          • ② 注意点:
          • ③代码实现
        • (2)任意位置删除
          • ① 函数声明
          • ② 注意点:
          • ③代码实现
      • 4. 修改指定位置
          • ① 函数声明
          • ② 注意点:
          • ③代码实现
      • 5. 查找指定位置
          • ① 函数声明
          • ② 注意点:
          • ③代码实现
      • 6. 清空顺序表
          • ① 函数声明
          • ② 注意点:
          • ③代码实现
      • 7. 销毁顺序表
          • ① 函数声明
          • ② 注意点:
          • ③代码实现
      • 8. 排序
          • ① 函数声明
          • ② 注意点:
          • ③代码实现
      • 9. 翻转
          • ① 函数声明
          • ② 注意点:
          • ③代码实现
      • 10. 剔重
          • ① 函数声明
          • ② 注意点:
          • ③代码实现
      • 11. 打印所有元素
          • ① 函数声明
          • ② 注意点:
          • ③代码实现
    • (四)使用C语言实现的顺序表的源代码已上传资源

一、概念

可以更合理使用内存
提高程序的执行效率

C语言本质是操作内存

数据对象、数据元素、数据项
图片

(一)数据结构的三元素

1. 逻辑结构

(1)线性结构

一对一的关系
数据连续

(2)非线性结构

树型:
一对多

图:
多对多

2. 存储结构

数据在计算机尤其是内存中的存储方式

(1)顺序存储
(2)链式存储
(3)索引存储

3. 运算

算法:有限步骤内解决问题的方法
算法不依赖于编程语言
特点:

  1. 有穷性
  2. 确定性
  3. 可行性
  4. 有0个或多个输入,有一个或多个输出

标准:

  1. 正确性
  2. 易读性
  3. 健壮性:对非法数据的处理能力
  4. 高效性
  5. 低存储

(二)时间复杂度

算法的时间复杂度定义为算法中可执行语句的频度之和 记作 T(n)
语句频度是指同一代码执行的次数
T(n)是算法所需时间的一种估值,n 表示问题的规模

算法的时间复杂度的表示方式为:
O(频度); ----------称为 大 O 表示法

假设有三段代码:
a 的时间复杂度为 2
b 的时间复杂度为 2n
c 的时间复杂度为2n^2
如果a、b、c组成一段程序,
那么算法的时间复杂度为
T(n) =T (2+2n+2n^2)
业内表示方法 还需T (2+2n+2n^2)要对进行简化

使用大O表示法的简化流程:
1.去掉运行时间中的所有常数项。
(例如 2+2n+2n^2,直接变为 2n+2n^2)
2.保留最高次幂项。
(2n^2+2n 变成 2n^2)
3.最高项存在但是系数不是1,则把系数置为1。
(2n^2 系数为2 去掉系数 n^2 )

所以,最终a、b和c合并而成的代码的时间复杂度为O(n^2)。

1. 线性阶

O(n)

2. 常数阶

O(1)

3. 平方阶

O(n^2)

4. 三次方阶

O(n^3)

5. 对数阶

O(logn)

6. 时间复杂度排序

O(1)< O(logn) < O(n) < O(nlogn) < O(n^2) <O(n^3) <O(2^n) <O(n!) < O(n^n)

可以带一个数测试,如问题规模n是16
1 < 4 < 16 < 64 < 256 < 4096 < 65536 < 16! < 16^16

二、顺序表

(一)逻辑结构

线性结构

(二)存储结构

顺序存储
内存中连续的空间

(三)操作

  • 目的:封装成函数,供他人使用
  • 结构体定义:
//节点结构体定义
typedef struct node
{int data; //此处以int为例,可自行添加其他成员
}Nd_t;
//列表结构体定义
typedef struct list
{int count; //记录当前存入了多少个值Nd_t listArr[MAX_SIZE]; 
}Ls_t;

1. 创建顺序表

(1)返回值是创建的顺序表

list_t *create_list_1();

(2)参数传入想要创建的顺序表
① 函数声明

int create_list(Ls_t **list);

② 注意点:
  1. 参数必须传入二级指针(需要改变main函数中的指针的值)
  2. 首先需要判定传入函数的指针是否为一个空指针(因为接下来第一件事是要使用*list来接malloc的返回值,如果传入的是一个空指针,会报段错误,所以需要提前检查)
  3. 需要判定申请空间是否成功(申请失败会返回NULL)
③代码实现
//创建顺序表并初始化
int create_list(Ls_t **list)
{if(NULL==list)//判定传入的指针是否是一个空指针{printf("申请空间失败\n");return -1;}//申请内存空间*list=(Ls_t *)malloc(sizeof(Ls_t));if(NULL==*list)//申请空间失败{printf("申请空间失败\n");return -1;}//初始化(*list)->count=0; memset(*list,0,sizeof(Ls_t));return 0;
}
  • 补充:memset函数
#include <string.h>
void *memset(void *s, int c, size_t n);
//s 要置值的内存首地址
//c 用于置值的值
//n 置值的大小

2. 插入元素(尾插、任意位置插入)

(1)尾插
① 函数声明

int insert_list_by_tail(Ls_t *list,int num);

② 注意点:
  1. 需要判定传入的顺序表指针是否是空指针
  2. 需要判定顺序表是否已满
  3. 插入成功后,count++
③代码实现
//在尾部插入数据
int insert_list_by_tail(Ls_t *list,int num)
{if(NULL == list) {printf("操作的表不存在\n");return -1;}if(MAX_SIZE == list->count){printf("顺序表已满\n");return -1;}//插入数据list->listArr[list->count].data=num;//顺序表存入数据的数量+1list->count++;return 0;
}
(2)任意位置插入
① 函数声明

int insert_list(Ls_t *list,int pos,int num);

② 注意点:
  1. 需要判定传入的顺序表指针是否是空指针
  2. 需要判定顺序表是否已满
  3. 判定插入位置是否合法,需要大于零,且需要保证顺序表内存空间连续
  4. 插入成功后,count++
③代码实现
int insert_list(Ls_t *list,int pos,int num)
{if(NULL == list) {printf("操作的表不存在\n");return -1;}if(MAX_SIZE == list->count){printf("顺序表已满\n");return -1;}if(pos < 0 || pos > list->count){printf("插入位置违法\n");return -1;}//从后往前,依次向后移动一位,直到到达插入位置int i=list->count;while(i!=pos){list->listArr[i]=list->listArr[i-1];i--;}//插入数据list->listArr[pos].data=num;//顺序表存入数据的数量+1list->count++;return 0;
}

3. 删除元素(尾删、任意位置删除)

(1)尾删
① 函数声明

int delete_list_by_tail(Ls_t *list);

② 注意点:
  1. 需要判定传入的顺序表指针是否是空指针
  2. 需要判定顺序表是否已满
  3. 直接count–即可,不必去清空值,此时原来的位置相当于已经声明可以继续写入数据
③代码实现
int delete_list_by_tail(Ls_t *list)
{if(NULL == list) {printf("操作的表不存在\n");return -1;}if(0==list->count){printf("顺序表为空\n");return -1;}list->count--;return 0;
}
(2)任意位置删除
① 函数声明

int delete_list(Ls_t *list,int pos);

② 注意点:
  1. 需要判定列表指针是否是空指针
  2. 判断表是否为空
  3. 判定删除位置是否合法,需要大于零,且小于顺序表当前容纳值的数量;
  4. 删除成功后,count需要减一
③代码实现
int delete_list(Ls_t *list,int pos)
{if(NULL == list) {printf("操作的表不存在\n");return -1;}if(0==list->count){printf("顺序表为空\n");return -1;}if(pos<0||pos>=list->count){printf("删除位置违法\n");return -1;}for(int i=pos;i<list->count;i++){list->listArr[i]=list->listArr[i+1];}list->count--;return 0;
}

4. 修改指定位置

① 函数声明

int modify_list(Ls_t *list,int pos,int num);

② 注意点:
  1. 需要判定列表指针是否是空指针
  2. 判断表是否为空
  3. 判定修改位置是否合法,需要大于零,且小于顺序表当前容纳值的数量;
③代码实现
int modify_list(Ls_t *list,int pos,int num)
{if(NULL == list) {printf("操作的表不存在\n");return -1;}if(0==list->count){printf("顺序表为空\n");return -1;}if(pos<0||pos>=list->count){printf("修改位置违法\n");return -1;}list->listArr[pos].data=num;return 0;
}

5. 查找指定位置

① 函数声明

int search_list(Ls_t *list,int pos,int *num);

② 注意点:
  1. 需要判定列表指针是否是空指针
  2. 判定查询位置是否合法,需要大于零,且小于顺序表当前容纳值的数量;
③代码实现
int search_list(Ls_t *list,int pos,int *num)
{if(NULL == list) {printf("操作的表不存在\n");return -1;}if(0==list->count){printf("顺序表为空\n");return -1;}if(pos<0||pos>=list->count){printf("查询位置违法\n");return -1;}*num=list->listArr[pos].data;return 0;
}

6. 清空顺序表

① 函数声明

int clean_list(Ls_t *list);

② 注意点:
  1. 需要判定列表指针是否是空指针
  2. 只需将count置0即可,各函数都是根据count来进行操作,因此即使原来顺序表的值并未清空也不影响
③代码实现
int clean_list(Ls_t *list)
{if(NULL == list) {printf("操作的表不存在\n");return -1;}list->count=0;return 0;
}

7. 销毁顺序表

① 函数声明

int destroy_list(Ls_t **list);

② 注意点:
  1. 需要先确保传入的指针并非空指针,再去判断*list是否为空
  2. 释放完堆区的空间后,再将main函数中的指针置为NULL
③代码实现
int destroy_list(Ls_t **list)
{if(NULL == list) {printf("操作的指针不存在\n");return -1;}if(NULL == *list) {printf("操作的表不存在\n");return -1;}free(*list);*list=NULL;return 0;
}

8. 排序

① 函数声明

int sort_list(Ls_t *list,int s);

② 注意点:
  1. 先确保传入的指针并非空指针
  2. 判断表是否为空
  3. 第二个参数为0是正序排序,否则倒序排序
③代码实现
int sort_list(Ls_t *list,int s)
{if(NULL == list) {printf("操作的表不存在\n");return -1;}if(0==list->count){printf("顺序表为空\n");return -1;}int flag=0;for(int i=0;i<list->count-1;i++){flag=0;for(int j=0;j<list->count-1-i;j++){if(0==s){ //正序排序if(list->listArr[j].data>list->listArr[j+1].data){Nd_t temp=list->listArr[j];list->listArr[j]=list->listArr[j+1];list->listArr[j+1]=temp;flag=1;}}else{if(list->listArr[j].data<list->listArr[j+1].data){Nd_t temp=list->listArr[j];list->listArr[j]=list->listArr[j+1];list->listArr[j+1]=temp;flag=1;}}}if(0==flag) break;}return 0;
}

9. 翻转

① 函数声明

int overturn_list(Ls_t *list);

② 注意点:
  1. 先确保传入的指针并非空指针
  2. 判断表是否为空
③代码实现
int overturn_list(Ls_t *list){if(NULL == list) {printf("操作的表不存在\n");return -1;}if(0==list->count){printf("顺序表为空\n");return -1;}int i=0,j=list->count-1;Nd_t temp;while(i<j){temp=list->listArr[i];list->listArr[i]=list->listArr[j];list->listArr[j]=temp;i++;j--;}printf("翻转完成\n");return 0;
}

10. 剔重

① 函数声明

int dedup_list(Ls_t *list);

② 注意点:
  1. 先确保传入的指针并非空指针
  2. 判断表是否为空
  3. 两侧遍历,第一层是从第一个元素遍历到倒数第二个元素(j=i+1);第二层是从第i+1个开始遍历,然后比较与当前第i个元素是否相等,相等就删除第j个元素,后面的元素依次向前移动一个位置,此时j无需再自加1
③代码实现
int dedup_list(Ls_t *list)
{if(NULL == list) {printf("操作的表不存在\n");return -1;}if(0==list->count){printf("顺序表为空\n");return -1;}int i,j;for(i=0;i<list->count-1;i++){for(j=i+1;j<list->count;j){if(list->listArr[j].data==list->listArr[i].data){for(int k=j;k<list->count-1;k++){list->listArr[k]=list->listArr[k+1];}list->count--;}else{j++;}}}return 0;
}

11. 打印所有元素

① 函数声明

int show_list(Ls_t *list);

② 注意点:
  1. 需要判定列表指针是否是空指针
③代码实现
int show_list(Ls_t *list)
{if(NULL == list) {printf("操作的表不存在\n");return -1;}for(int i=0;i<list->count;i++){printf("%d ",list->listArr[i].data);}putchar(10);return 0;
}

(四)使用C语言实现的顺序表的源代码已上传资源

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

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

相关文章

Linux下Git的基本使用

认识Git 先基于Windows下的git操作&#xff0c;熟悉了git的基本概念和使用&#xff0c;直接参考这几篇文章&#xff1a; Git概述、安装与本地仓库的基本操作-CSDN博客 Git本地仓库与远程仓库的交互-CSDN博客 GtiHub远程仓库之间的交互-CSDN博客 Git仓库的分支操作-CSDN博客 仓库…

服装服饰商城小程序的作用是什么

要说服装商家&#xff0c;那数量是非常多&#xff0c;厂家/经销门店/小摊/无货源等&#xff0c;线上线下同行竞争激烈&#xff0c;虽然用户群体广涵盖每个人&#xff0c;但每个商家肯定都希望更多客户被自己转化&#xff0c;渠道运营方案营销环境等不可少。 以年轻人为主的消费…

国产PS插件新选择;StartAI平替中的佼佼者!

前言 在设计的世界里&#xff0c;每一个细节都至关重要。设计师们常常面临时间紧迫、创意受限、工具复杂等挑战。Photoshop虽强大&#xff0c;但繁琐的操作和高昂的成本往往令人望而却步。今天我就为大家介绍一款PSAI插件——StartAI&#xff0c;一款专为Photoshop设计的国产A…

【Linux终端探险】:从入门到熟练,玩转基础命令的秘密(一)

文章目录 &#x1f680;Linux基础命令⭐1. 查看目录命令&#x1f4a5;2. 切换目录&#x1f44a;3. 创建目录❤️4. 删除目录/文件&#x1f6b2;5. 修改目录/文件&#x1f308;6. 拷贝目录/文件 &#x1f680;Linux基础命令 ⭐1. 查看目录命令 在Linux中&#xff0c;查看目录的…

C语言⾼位优先与低位优先的不同之处是什么?

一、问题 C语⾔的最⼤特⾊就是可移植性好。根据机器类型的不同&#xff0c;⾼位优先与低位优先也不同。那么&#xff0c;最好的可移植的 C 程序应该同时适⽤这两种类型的计算机。下⾯了解⼀下⾼位优先与低位优先的不同之处。 二、解答 所谓的⾼位优先&#xff0c;就是最低的地…

AUS GLOBAL 荣获 Brokersview 颁奖盛典多项殊荣

2024年1月31日在迪拜 Sheikh Zayed Rd - Trade Centre - Trade Centre 1 举行的 Brokersview 颁奖盛典上&#xff0c;AUS GLOBAL&#xff08;澳洲环球&#xff09;再次展现了其在金融行业的卓越实力&#xff0c;并荣获多项殊荣。 AUS GLOBAL 作为一家全球领先的金融服务提供商…

一个交易者的自白:念念不忘的交易,10个日内9个亏

一、新手: 面对爆仓,我像个白痴 我是在2012年开始接触的&#xff0c;这些年里我尝到了残酷失败的滋味&#xff0c;更品尝过胜利带来的喜悦。刚刚接触时很自信&#xff0c;总想着自己有一天一定会变成千万富翁的&#xff0c;用杠杆获取暴利。 在我首次爆仓的时候&#xff0c;我的…

如何衡量安全阀检测的价格与价值?一文揭晓答案

安全阀作为工业设备中的重要组件&#xff0c;其性能的稳定性和可靠性直接影响着整个系统的安全运行。因此&#xff0c;对安全阀进行定期检测和维护显得尤为重要。 那么&#xff0c;安全阀检测一个需要多少钱呢&#xff1f; 在这篇文章中&#xff0c;佰德将从检测费用构成、市…

8086 汇编笔记(一):寄存器

前言 8086 CPU 有 14 个寄存器&#xff0c;每个寄存器有一个名称。这些寄存器是&#xff1a;AX、BX、CX、DX、SI、DI、SP、BP、IP、CS、SS、DS、ES、PSW 一、通用寄存器 8086 CPU 的所有寄存器都是 16 位的&#xff0c;可以存放两个字节。AX、BX、CX、DX 这 4个寄存器通常用…

Adobe Bridge BR v14.0.3 安装教程 (多媒体文件组织管理工具)

Adobe系列软件安装目录 一、Adobe Photoshop PS 25.6.0 安装教程 (最流行的图像设计软件) 二、Adobe Media Encoder ME v24.3.0 安装教程 (视频和音频编码渲染工具) 三、Adobe Premiere Pro v24.3.0 安装教程 (领先的视频编辑软件) 四、Adobe After Effects AE v24.3.0 安装…

mysql手动新建数据库

点击号输入数据库名&#xff0c;端口号&#xff0c;密码&#xff0c;连接到sa数据库新建数据库&#xff0c;语言必须选择utf8mb4新建数据库用户给数据库用户设置对应权限给数据库用户勾选权限

登峰造极,北斗相伴——纪念人类首次登顶珠穆朗玛峰71周年

71年前的今天&#xff0c;1953年5月29日11时30分&#xff0c;人类实现了一个伟大的壮举&#xff1a;首次登上了珠穆朗玛峰&#xff0c;这座海拔8848.86米的世界最高峰。这是一次充满了艰辛、勇气和智慧的探险&#xff0c;也是一次改变了人类历史和文化的探险。 自那以后&#…

【全球展会招商】2025COSP深圳国际户外展乘风而至,启赴新程!

展会介绍 “2025-COSP深圳国际户外展览会”将于展出面积达40,000㎡&#xff0c;展出品牌60家包含户外露营展区、 车旅生活展区 、户外运动展区、水上运动展区 、 民宿旅居展区等热门产品专区&#xff0c;充分满足供应商及采购商、行业人士及运动爱好者的需求&#xff0c;打造展…

于AI对话 --如何更好的使用AI工具

文章目录 于AI对话 --如何更好的使用AI工具1、认识AI工具&#xff1a;2、对话原则&#xff1a;3、提问步骤&#xff1a;4、AI可以学习什么&#xff1f;5、提问技巧&#xff1a;1、提出假设性问题:2、&#xff08;鼓励引导式提问&#xff09;跨学科思考:举个例子&#xff1a; 3、…

删除的短信怎么恢复?专业与非专业方法的全面比较

在日常清理手机内存的过程中&#xff0c;我们可能会不小心删除短信。这些短信可能包含重要的数据和联系人信息。面对这种情况&#xff0c;许多人会感到困惑和无助。那么&#xff0c;删除的短信怎么恢复呢&#xff1f;本文将为您全面比较专业与非专业的方法&#xff0c;帮助您找…

扬腾创新golang2轮面试,二面相当硬核。我差点崩溃。。

一面 1、自我介绍&#xff0c;换工作的原因是什么&#xff1f; 2、物流开发平台是做什么&#xff1f;链路上都有哪些核心模块&#xff1f; 一个单下过来&#xff0c;分配给哪个3PL&#xff1f;有什么要求吗&#xff1f;是怎么设计的&#xff1f; 保证履约系统稳定性方面有做…

【大数据面试题】33 手写一个 Flink SQL 样例

一步一个脚印&#xff0c;一天一道大数据面试题 博主希望能够得到大家的点赞收&#xff0c;藏支持&#xff01;非常感谢~ 点赞&#xff0c;收藏是情分&#xff0c;不点是本分。祝你身体健康&#xff0c;事事顺心&#xff01; 我们来看看 Flink SQL大概流程和样例&#xff1a; …

基于双向长短时记忆网络的ECG心电信号识别(包括原始时域信号与时频域特征提取,MATLAB R2021B)

循环神经网络RNN&#xff0c;是一种链式结构&#xff0c;能够对连续输入的序列同时处理&#xff0c;且有不错的效果。RNN具有记忆功能且能够随时接受并处理输入数据&#xff0c;这得益于其特殊的连接方式&#xff0c;即神经元之间以一定的方向互相连接构成环&#xff0c;内部时…

如何使用宝塔面板搭建Tipask问答社区网站并发布公网远程访问

文章目录 前言1.Tipask网站搭建1.1 Tipask网站下载和安装1.2 Tipask网页测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar临时数据隧道2.2 Cpolar稳定隧道&#xff08;云端设置&#xff09;2.3 Cpolar稳定隧道&#xff08;本地设置&#xff09; 3. 公网访问测试4.结语 前…

摸鱼大数据——Hive表操作——复杂类型

1、hvie的SerDe机制 其中ROW FORMAT是语法关键字&#xff0c;DELIMITED和SERDE二选其一。本次我们主要学习DELIMITED关键字相关知识点 如果使用delimited: 表示底层默认使用的Serde类:LazySimpleSerDe类来处理数据。 如果使用serde:表示指定其他的Serde类来处理数据,支持用户自…