[考研数据结构]第2章之顺序表的基本知识与操作

前言

        从本篇文章开始,正式开启考研专业课之一的数据结构的复习之旅,数学与专业课并驾齐驱,早开始,后期才能游刃有余。另外博客重点分享数据结构需要动手实践的代码部分,对于概念的解释将被一笔带过或者忽略,望周知。

文章目录

顺序表的定义

顺序表的基本操作

静态分配

定义存储结构

 初始化顺序表

 插入元素

 删除元素

 修改元素

查找元素

测试

动态分配

定义存储结构

 初始化顺序表

 数组动态扩容

内存分配函数malloc()

测试

总结


顺序表的定义

        线性表的顺序存储又称为顺序表。它是一种使用一组地址连续的存储单元依次存储线性表中的数据元素,从而使得逻辑上相邻的元素在物理位置上也是相邻的。第1个元素存储在线性表中的起始位置,第i个元素的存储位置后面紧跟着存储的是第i+1个元素,称i为元素ai在线性表中的位序


顺序表的基本操作

静态分配

静态分配,顾名思义,数组在运行之前的大小是固定好的,无法更改。

定义存储结构

//定义顺序表的存储结构 
typedef struct {int data[MaxSize];//顺序表的元素 int length;//顺序表的当前长度 
}SqlList;//顺序表的类型定义

 初始化顺序表

//初始化
void InitList(SqlList &L){for(int i=0;i<MaxSize;i++){L.data[i]=0;}L.length=0;
} 

 插入元素

//插入元素 
bool ListInsert(SqlList &L,int i,int e){//判断插入位置i是否合法if(i<1||i>L.length+1) return false;//判断当前存储空间是否已满,已满则不能插入if(L.length>=MaxSize) return false;//从第i个位置往后依次移动元素,空出第i个位置给待插入的元素 for(int j=L.length;j>=i;j--){L.data[j]=L.data[j-1];}L.data[i-1]=e;//在位置i处插入该元素,下标为i-1 L.length++;//插入后长度加一return true; 
}

 删除元素

//删除元素
bool ListDelete(SqlList &L,int i,int &e){//判断删除位置i是否合法if(i<1||i>L.length) return false;e=L.data[i-1];//将要删除的元素 存入e带回、//从第i个位置开始后面元素依次向前移动,从而覆盖掉要删除的元素 for(int j=i;j<L.length;j++){L.data[j-1]=L.data[j]; } L.length--;return true; 
} 

 修改元素

//修改元素(按值修改) 按下标修改很简单,只需L.data[i-1]=e 即可 
bool ListChange(SqlList &L,int oldNumber,int newNumber){int flag=0;for(int j=0;j<L.length;j++){if(L.data[j]==oldNumber){L.data[j]=newNumber;flag=1;}}if(flag!=0)return true;else return false;
} 

查找元素

//查找元素(按值查找)  按照下标查找直接返回L.data[i-1] 查找时间复杂度为O(1) 即随机存取 
int ListSearch(SqlList &L,int target){for(int i=0;i<L.length;i++){if(L.data[i]==target){return i+1;			}}return 0;
} 

测试

#include"stdio.h"
#define MaxSize 20
//定义顺序表的存储结构 
typedef struct {int data[MaxSize];//顺序表的元素 int length;//顺序表的当前长度 
}SqlList;//顺序表的类型定义//初始化
void InitList(SqlList &L){for(int i=0;i<MaxSize;i++){L.data[i]=0;}L.length=0;
} //插入元素 
bool ListInsert(SqlList &L,int i,int e){//判断插入位置i是否合法if(i<1||i>L.length+1) return false;//判断当前存储空间是否已满,已满则不能插入if(L.length>=MaxSize) return false;//从第i个位置往后依次移动元素,空出第i个位置给待插入的元素 for(int j=L.length;j>=i;j--){L.data[j]=L.data[j-1];}L.data[i-1]=e;//在位置i处插入该元素,下标为i-1 L.length++;//插入后长度加一return true; 
}//删除元素
bool ListDelete(SqlList &L,int i,int &e){//判断删除位置i是否合法if(i<1||i>L.length) return false;e=L.data[i-1];//将要删除的元素 存入e带回、//从第i个位置开始后面元素依次向前移动,从而覆盖掉要删除的元素 for(int j=i;j<L.length;j++){L.data[j-1]=L.data[j]; } L.length--;return true; 
} //修改元素(按值修改) 按下标修改很简单,只需L.data[i-1]=e 即可 
bool ListChange(SqlList &L,int oldNumber,int newNumber){int flag=0;for(int j=0;j<L.length;j++){if(L.data[j]==oldNumber){L.data[j]=newNumber;flag=1;}}if(flag!=0)return true;else return false;
} //查找元素(按值查找)  按照下标查找直接返回L.data[i-1] 查找时间复杂度为O(1) 即随机存取 
int ListSearch(SqlList &L,int target){for(int i=0;i<L.length;i++){if(L.data[i]==target){return i+1;			}}return 0;
} //打印顺序表
void PrintList(SqlList &L){for(int i=0;i<L.length;i++){printf("%d\t",L.data[i]);}printf("\n");
} //测试 
int main(){SqlList p;InitList(p);//初始化顺序表//插入元素 for(int i=1;i<=10;i++){ListInsert(p,i,2*i);}printf("1.插入元素后顺序表为:");PrintList(p);//删除元素 int location,e;//location表示要删除元素的位序,e存放被删除元素的值 printf("\n请输入你想要删除的元素的位置:");scanf("%d",&location);if(ListDelete(p,location,e)){printf("2.删除成功,删除的元素为:%d\n",e);printf("删除元素后顺序表为:");PrintList(p); }else{printf("2.删除失败,请检查你输入的位序是否合法!\n");}//查找元素int target;printf("\n请输入你要查找的元素:");scanf("%d",&target);int index=ListSearch(p,target);if(index!=0){printf("3.查询成功,该元素的位序为:%d\n",index);} else{printf("3.查询失败,顺序表中不存在该元素!\n");}//修改元素int oldNum,newNum;printf("\n请输入你要修改的元素的值:");scanf("%d",&oldNum);printf("请输入其修改后的值:");scanf("%d",&newNum);if(ListChange(p,oldNum,newNum)){printf("4.修改元素后顺序表为:");PrintList(p);}else {printf("修改失败,顺序表中不存在该元素!\n");}return 0;
} 

正常测试

异常测试


动态分配

        动态分配,顾名思义,可以在程序运行时动态地改变数组的大小,使用malloc函数动态地向内存申请额外的内存空间达到扩容的目的,较为灵活,但在复制原来的数组内容时,时间复杂度较高。

定义存储结构

//定义存储结构 
typedef struct {int *data;//指向动态数组的指针int MaxSize;//顺序表的最大容量 int length; //顺序表的当前长度 
}SqlList;

 初始化顺序表

//初始化
void InitList(SqlList &L){//使用malloc函数向内存申请一整片连续的存储空间L.data=(int *)malloc(InitSize*sizeof(int));L.length=0;L.MaxSize=InitSize; 
} 

 数组动态扩容

//动态扩容增大数组长度
void IncreaseArraySize(SqlList &L,int len){int *old=L.data;//存储原来动态数组的指针 //重新向内存申请更大的空间 L.data=(int *)malloc((L.MaxSize+len)*sizeof(int));for(int i=0;i<L.length;i++){L.data[i]=old[i];//将原来数组的数据放到新的数组中 }L.MaxSize=L.MaxSize+len;//顺序表的最大长度扩大len free(old);//释放原来数组所占用的内存空间 
} 

内存分配函数malloc()

C语言malloc函数详解(通俗易懂)https://blog.csdn.net/RY_01/article/details/122815201?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167871171516782427480638%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=167871171516782427480638&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_click~default-2-122815201-null-null.142%5Ev73%5Epc_new_rank,201%5Ev4%5Eadd_ask,239%5Ev2%5Einsert_chatgpt&utm_term=malloc%E5%87%BD%E6%95%B0&spm=1018.2226.3001.4187

测试

#include"stdio.h"
#include"stdlib.h"
#define InitSize 10
//定义存储结构 
typedef struct {int *data;//指向动态数组的指针int MaxSize;//顺序表的最大容量 int length; //顺序表的当前长度 
}SqlList;//初始化
void InitList(SqlList &L){//使用malloc函数向内存申请一整片连续的存储空间L.data=(int *)malloc(InitSize*sizeof(int));L.length=0;L.MaxSize=InitSize; 
} //插入元素 
bool ListInsert(SqlList &L,int i,int e){//从第i个位置往后依次移动元素,空出第i个位置给待插入的元素 for(int j=L.length;j>=i;j--){L.data[j]=L.data[j-1];}L.data[i-1]=e;//在位置i处插入该元素,下标为i-1 L.length++;//插入后长度加一return true; 
}//动态扩容增大数组长度
void IncreaseArraySize(SqlList &L,int len){int *old=L.data;//存储原来动态数组的指针 //重新向内存申请更大的空间 L.data=(int *)malloc((L.MaxSize+len)*sizeof(int));for(int i=0;i<L.length;i++){L.data[i]=old[i];//将原来数组的数据放到新的数组中 }L.MaxSize=L.MaxSize+len;//顺序表的最大长度扩大len free(old);//释放原来数组所占用的内存空间 
} //打印顺序表
void PrintList(SqlList &L){for(int i=0;i<L.length;i++){printf("%d\t",L.data[i]);}printf("\n");
} 
int main(){SqlList p;//初始化顺序表InitList(p);//插入元素 for(int i=1;i<=10;i++){ListInsert(p,i,3*i);}printf("1.插入元素后顺序表为:");PrintList(p);int len;printf("请输入你要扩大数组的长度:");scanf("%d",&len);//数组扩充 IncreaseArraySize(p,len);printf("继续插入%d个元素\n",len);for(int j=p.length+1;j<=p.MaxSize;j++){ListInsert(p,j,4*j);} printf("扩充后的顺序表为:");PrintList(p);return 0;
}

运行结果

动态分配内存下的顺序表只是数组长度可变,其基本的增删改查操作同静态分配中一致!

故此处不再赘述。


总结

  •  顺序表在使用前务必先进行初始化,否则会输出内存中的异常数据造成紊乱,如下图

  •  C语言的动态分配语句为
L.data=(ElemType *)malloc((InitSize*sizeof(ElemType));
  • C++语言的动态分配语句为
L.data=new ElemType[InitSize];
  • 注意位序与下标的区别,位序从1开始,下标从0开始
  • 在执行插入、删除、修改元素时,要先进行异常处理,即对于位序i进行合法性的判断
  • 封装思想,在测试中经常使用到循环打印顺序表中的元素,可以将该操作封装起来复用
//打印顺序表
void PrintList(SqlList &L){for(int i=0;i<L.length;i++){printf("%d\t",L.data[i]);}printf("\n");
} 

END.

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

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

相关文章

线程池 2(第二部分--循环队列)

在考虑如何去设计一个任务容器的时候&#xff0c;其实尝试了很多。最开始的时候直接用的是std::queue容器&#xff0c;主要是看了知乎上面的 “ 基于C11实现线程池 - 知乎 ”这个帖子&#xff0c;去封装一个安全队列。但是这个操作每次都要上一次锁&#xff0c;实在是太浪费时间…

ubuntu20.04 硬盘挂载、显卡驱动安装

前几天ubuntu系统莫名出问题了&#xff0c;修不好只能重装&#xff0c;在此记录安装ubuntu系统后的硬盘挂载和显卡驱动安装。 注意&#xff0c;本文并非教程&#xff0c;只是个人安装过程的记录&#xff0c;仅供参考 ubuntu系统&#xff1a;Ubuntu 20.04.6 LTS 硬件设备&…

一文带你搞清 ChatGPT 与 Azure OpenAI 的区别

这两周是我从2017年开始全职涉入 NLP 领域后最忙的两周&#xff0c;无数的同事和客户都在向我提出一个询问&#xff1a;ChatGPT 可以帮到我们什么&#xff1f; 特别是在2023年3月31日我做了一场微软 Azure OpenAI [布局助力企业]拥抱新智能时代的演讲之后&#xff0c;这几天我…

ChatGPT的真相:强泛化的秘密以及众多关键问题

进NLP群—>加入NLP交流群 本文转载自AI科技评论&#xff0c;作者韩庐山。 本文从ChatGPT带来的即时学习能力&#xff08;in-context learning&#xff09;入手&#xff0c;逐步深入地探讨了ChatGPT目前众多的关键性问题&#xff0c;包括&#xff1a; ChatGPT带来了从未有过的…

chatgpt赋能python:用Python向手机发送信息是如何实现的?

用Python向手机发送信息是如何实现的&#xff1f; 在今天的信息时代&#xff0c;随时随地保持联系已经成为生活不可或缺的一部分。随着技术的发展&#xff0c;我们可以使用各种方式发送和接收信息&#xff0c;而使用Python向手机发送短信是其中一种非常方便的方式。 Python的…

chatgpt赋能python:Python自动认证上网教程

Python自动认证上网教程 随着互联网的普及&#xff0c;越来越多的人需要通过手机、电脑等设备上网&#xff0c;而许多场所都要求进行认证才能使用网络。每次都手动操作认证费时费力&#xff0c;这时Python就可以派上用场了。Python是一种高级的编程语言&#xff0c;具有可读性…

双因素认证(2FA)教程

所谓认证&#xff08;authentication&#xff09;就是确认用户的身份&#xff0c;是网站登录必不可少的步骤。 密码是最常见的认证方法&#xff0c;但是不安全&#xff0c;容易泄露和冒充。 越来越多的地方&#xff0c;要求启用双因素认证&#xff08;Two-factor authenticatio…

如何实现双因素认证?

增强数字安全的愿望引起了世界各国政府的关注&#xff0c;所有政府都希望保护消费者和企业。因此&#xff0c;许多人提出了立法&#xff0c;将两因素身份验证 (2FA) 作为 IT 系统的强制性要求。其实&#xff0c;在我国等级保护制度中等级保护第三级以上都要求完成双因素认证的&…

网络安全合规-Tisax(汽车安全评估讯息交换平台)一

**TISAX&#xff08;汽车安全评估讯息交换平台&#xff08;可信信息安全评估交换平台&#xff09;&#xff09;**是2017年由德国汽车工业联合会(VDA) 联合欧洲网络交换所(ENX) 所推出的资讯交换平台&#xff0c;通过应用欧洲网络交换协会&#xff08;ENX&#xff09;和德国汽车…

从医疗保健攻击到HIPAA 合规性

医疗机构无疑是网络攻击的热门目标。攻击者因在暗网上出售一条健康记录而获取高额 佣金&#xff0c;在各行业网络安全报告中医疗保健行业的攻击事件占比居高不下&#xff0c;这有什么奇怪的吗&#xff1f; 根据2022 年 SonicWall 网络威胁报告&#xff0c;医疗保健行业&#x…

漫话:如何给女朋友解释鸿蒙OS是怎样实现跨平台的?

周末在家休息&#xff0c;女朋友在刷朋友圈&#xff0c;突然她问我&#xff1a; 鸿蒙OS回顾 2019年8月9日华为开发者大会上&#xff0c;华为消费者业务CEO余承东正式宣布发布自有操作系统鸿蒙&#xff0c;内核为Linux内核、鸿蒙微内核和LiteOS。未来将摆脱Linux内核和LiteOS&am…

腾讯研发动画组件,以后动画制作用PAG

你好&#xff0c;我是tiantian。 我们知道&#xff0c;动画特效可以辅助视觉制作焦点&#xff0c;引导注意力的方向&#xff0c;越来越为广大视觉设计师青睐&#xff0c;并广泛应用于各类场景开发。 关于动画设计工具&#xff0c;既有 Framer.js、Origami&#xff0c; 也有交互…

能直接修复代码 BUG,比 ChatGPT 还厉害

【公众号回复 “1024”&#xff0c;免费领取程序员赚钱实操经验】 大家好&#xff0c;又见面了&#xff0c;我是章鱼猫&#xff01; 最近 ChatGPT 非常的火&#xff0c;而且是火出圈的那种&#xff0c;各个领域的人都知道。但是不得不说程序员做的工具&#xff0c;对程序员还是…

chatgpt赋能Python-ipv4地址python

IPv4地址 Python编程介绍 IPv4地址在互联网中扮演着非常重要的角色&#xff0c;英文名称为 Internet Protocol Version 4 Address。每一个连接到互联网上的设备都会被分配一个唯一的IPv4地址&#xff0c;它由32位二进制数以点分十进制的形式呈现出来。在Python编程中&#xff…

chatgpt赋能Python-pythonip地址是否合法

Python中如何判断IP地址是否合法 在网络中&#xff0c;IP地址是非常重要的概念。它用来标识网络中每个设备的唯一地址。IP地址通常分为IPv4和IPv6两种类型。在Python中&#xff0c;有多种方法可以判断IP地址是否合法。在本文中&#xff0c;我们将介绍如何使用Python编程语言来…

可喜可贺,暴雪即将收购第一家工作室Proletariat,魔法吃鸡停运

暴雪娱乐在超过15年的时间里收购了第一家工作室。在VentureBeat的一份报告中&#xff0c;该公司收购了总部位于波士顿的工作室Proletariat。 “经过四年多的元素魔法和咒语组合&#xff0c;我们决定结束Spellbreak的研发&#xff0c;”该公司在其网站上写道。“这些服务器将于2…

修改战网昵称服务器错误,暴雪又改了游戏平台名字 暴雪战网回来了

暴雪一定是个纠结的处女座&#xff0c;距离上一次更改游戏平台名称之后&#xff0c;8月15日早上6点&#xff0c;暴雪中国又一次在微博上发表公告称“暴雪战网品牌名称更新”&#xff0c;名字从上一次的暴雪游戏平台改成了暴雪战网。 按暴雪的意思来看&#xff0c;之所以玩这么一…

暴雪战网服务器维护,炉石无法通过暴雪战网服务进行登录

有很多玩家常常遇到战网无法登陆、炉石传说无法登陆至战网服务等问题。那么下面就告诉大家这种解决办法&#xff0c;希望对你有帮助&#xff01; 1、关闭游戏或安装程序&#xff0c;打开任务管理器&#xff0c;终止以下进程&#xff1a;Agent.exe&#xff0c;Blizzard Launcher…

【吴恩达deeplearning.ai】基于ChatGPT API打造应用系统(上)

以下内容均整理来自deeplearning.ai的同名课程 Location 课程访问地址 DLAI - Learning Platform Beta (deeplearning.ai) 一、大语言模型基础知识 本篇内容将围绕api接口的调用、token的介绍、定义角色场景 调用api接口 import os import openai import tiktoken from dote…

ChatGPT讲故事,DALLE-2负责画出来!两大AI合作出绘本!

点击下方卡片&#xff0c;关注“CVer”公众号 AI/CV重磅干货&#xff0c;第一时间送达 点击进入—>CV微信技术交流群 转载自&#xff1a;机器之心 | 编辑&#xff1a;张倩、袁铭怿 生成式 AI 正在变革内容的生产方式。 在过去的一周&#xff0c;相信大家都被 ChatGPT 刷了屏…