【数据结构】详细剖析线性表

顺序表与链表的比较

  • 导言
  • 一、线性表
  • 二、线性表的存储结构
  • 三、顺序表和链表的相同点
  • 四、顺序表与链表之间的差异
  • 五、存储结构的选择
  • 六、静态顺序表的基本操作
  • 七、无头结点单链表的基本操作
  • 结语

封面

导言

大家好,很高兴又和大家见面啦!!!

经过这段时间的学习与分享,想必大家跟我一样都已经对线性表的相关内容比较熟悉了。为了更好的巩固线性表相关的知识点,下面我们一起将线性表这个章节的内容梳理一遍吧。

一、线性表

线性表的相关概念

线性表时具有相同数据类型 n ( n > = 0 ) n(n>=0) n(n>=0)个数据元素的有限序列,其中 n n n为表长,当 n = 0 n=0 n=0时线性表是一个空表。

如果我们以 a i ( 1 < = i < = n ) a_i(1<=i<=n) ai(1<=i<=n)作为线性表的各个元素时,元素 a 1 a_1 a1为线性表唯一的第一个元素,称为表头元素;元素 a n a_n an为线性表唯一的最后一个元素,称为表尾元素


线性表的逻辑特性是:

  • 除了表头元素外,每个元素有且仅有一个直接前驱
  • 除了表尾元素外,每个元素有且仅有一个直接后继

线性表的特点是:

  • 表中元素的个数是有限的
  • 表中元素具有逻辑上的顺序性,表中元素有其先后次序
  • 表中元素都是数据元素,每个元素都是单个元素
  • 表中元素的数据类型都相同,这意味着每个元素所占空间大小相同
  • 表中元素具有抽象性,即仅讨论元素间的逻辑关系,而不考虑元素的内容

线性表的基本操作:

  1. 创建与销毁
    • InitList(&L):初始化表。构造一个空的线性表;
    • DestroyList(&L):销毁操作。销毁线性表,并释放线性表L所占用的内存空间。
  1. 插入与删除
    • ListInSERT(&L,i,e):插入操作。在表L中第i个位置插入指定元素e;
    • ListDelete(&L,i,&e):删除操作。删除表L中第i个位置的元素,并用e返回删除元素的值;
  1. 查找
    • LocateElem(L,e):按值查找操作。在表L中查找具有给定关键字值的元素;
    • GetElem(L,i):按位查找操作。获取表L中第i个位置的元素的值;
  1. 其它操作
    • Length(L):求表长。返回线性表L的长度,即L中数据元素的个数;
    • PrintList(L):输出操作。按前后顺序输出线性表L的所有元素值;
    • Empty(L):判空操作。若L为空表,则返回true,否则返回false;

复习完了线性表的相关知识点,下面我们来看一下线性表的两种存储结构;

二、线性表的存储结构

线性表的各元素在内存中存储时满足在逻辑上相邻,也在物理位置上相邻,这样的存储结构称为顺序存储,又称为顺序表。通常用高级程序设计语言中的数组来表示顺序存储结构

线性表中的各个元素在内存中存储时满足在逻辑上相邻,在物理位置上不一定相邻,元素与元素之间通过“链”建立起来的逻辑关系,这样的存储结构称为链式存储,又称为链表。


对于顺序表和链表它们又有哪些异同点呢?

三、顺序表和链表的相同点

顺序表和链表的相同点都是建立在它们的本质上面的,下面我们就来看看它们具有哪些相同点:

  • 顺序表和链表的元素个数都是有限的;
  • 顺序表和链表的元素类型都是相同的;
  • 顺序表和链表的元素都满足在逻辑上相邻;
  • 顺序表和链表的元素都是数据元素,且每个元素都是单一元素;
  • 顺序表和链表的元素都满足只有一个唯一的表头元素和一个唯一的表尾元素;
  • 顺序表和链表的逻辑特性都是:
    • 除了表头元素外,每个元素都有且仅有一个直接前驱;
    • 除了表尾元素外,每个元素都有且仅有一个直接后继;
  • 循序表和链表都能进行创建、销毁、增删改查等基本操作;
  • 顺序表和链表在金泰

因此,我们可以得到结论:

  • 顺序表和链表的本质都是线性表,只不过线性表强调的数据元素在内存上的逻辑结构,而顺序表与链表强调的是数据元素在内存上的存储结构

介绍完了顺序表与链表的相同点,接下来我们继续来看一看它们的不同点;

四、顺序表与链表之间的差异

  1. 存取方式不同
  • 顺序表是顺序存取结构,同时也是随机存取结构;
  • 链表是链式存取结构,同时也是非随机存取结构;

因此,我们想要访问顺序表的各个元素时,只需要知道元素的下标就可以直接查找到,此时的时间复杂度是O(1);而链表想要访问第i个元素时,需要从表头开始进行遍历,此时的时间复杂度是O(n);

  1. 物理结构不同
  • 顺序表的各个元素在物理位置上也是相邻的;
  • 链表的各个元素在物理位置上不一定相邻;

因此顺序表在存储时可以做到密集存储,但是需要在内存中消耗一块连续的存储空间;而链表在存储时是离散存储的,但是需要消耗额外的空间来存放指向下一个结点的指针;

  1. 创建方式不同
  • 顺序表在创建时需要明确最大表长、当前表长、数据存放的空间;
  • 链表在创建时需要明确数据域和指针域;
  • 顺序表在初始化时可以只初始化当前表长;
  • 链表在初始化时需要对头结点进行初始化,链表的表长需要通过额外的计数器来确定;

因此顺序表在创建后表的大小是固定的,虽然可以通过malloccallocrealloc来申请新的空间达到修改表长的目的,但是在申请完新的空间后还伴随着大量的复制操作,此时的时间复杂度是O(n);而链表在创建时链表的大小是可以随时进行修改的,只需要在插入新结点时修改对应结点的指针域就行,此时的时间复杂度是O(1);

  1. 查找方式不同
  • 顺序表在进行按位查找时,可以直接通过位序查找到对应的元素;
  • 链表在进行按位查找时,需要通过从头结点往后进行遍历才能找到对应的元素;
  • 顺序表在进行按值查找时,可以通过不同的查找方式进行快速查找;
  • 链表在进行按值查找时,需要从头结点开始往后进行顺序查找;

因此顺序表在进行按位查找时的时间复杂度是O(1),在进行按值查找时的最坏时间复杂度为O(n);而链表在进行按位查找与按值查找的时间复杂度都是O(n);

  1. 插入与删除方式不同
  • 顺序表在进行插入与删除时需要移动大量的元素;
  • 链表在进行插入与删除时只需要修改对应的指针域;

因此顺序表的插入与删除操作的时间复杂度为O(n);而链表的插入与删除的时间复杂度为O(1);

  1. 空间分配不同
  • 顺序表在进行动态分配时,需要申请一块连续的空间,且空间大小不能修改;
  • 链表在进行动态分配时,需要申请对应的结点的空间,空间大小可以随时修改;
  • 顺序表在修改表长时,需要移动大量的元素;
  • 链表在修改表长时,只需要修改对应结点的指针域;

因此,顺序表在修改表长时对应的时间复杂度为O(n);而链表在修改表长时对应的时间复杂度为O(1);


在了解了顺序表与链表的异同点后,我们又应该如何进行选择呢?

五、存储结构的选择

我们在实际运用中要选择对应的存储结构,就需要结合具体的情况进行分析。从前面的介绍中我们可以看到,顺序表的优势是在查找元素的上面,而链表的优势是在增加、删除上面。因此我们在选择时需要考虑以下几点:

  1. 存储的考虑

在不确定线性表的长度与存储规模时,宜采用链表;
在确定线性表的表长,且需要密集存储时,宜采用顺序表;

  1. 运算的考虑

在表长固定的情况下需要经常对表中元素进行按序号访问时,宜采用顺序表;
在表长需要进行增加、删除的操作时,宜采用链表;

  1. 环境的考虑

在不支持指针的计算机语言中,虽然可以通过静态链表来实现链表,但是顺序表会更加简单一点;
在支持指针的计算机语言中,就需要从存储与运算这两个方面的角度去考虑了。


总之,两种存储结构各有长短,选择哪一种还是得由实际情况来决定。通常较稳定的线性表选择顺从存储;需要平方进行插入、删除操作的线性表选择链式存储。要想更加深刻的理解顺序存储与链式存储之间的优缺点,还是需要熟练的掌握它们才行。

六、静态顺序表的基本操作

在前面我们只介绍了动态顺序表的基本操作,今天我将补上静态顺序表基本操作,其对应的的基本格式如下所示:

//顺序表的静态创建
#define MaxSize 10//定义最大表长
typedef struct Sqlist {ElemType data[MaxSize];//存储数据元素的数组int length;//当前表长
}Sqlist;//重命名后的静态顺序表类型名
//顺序表的初始化
bool InitList(Sqlist* L){if (!L)return false;//指针L为空指针时返回falseL->length = 0;//初始化当前表长return true;
}
//顺序表的按位查找
ElemType GetElem(Sqlist L, int i){if (i<1 || i>L.length)//位序小于1,或者位序大于当前表长时表示位序不合理return -1;//位序不合理,返回-1return L.data[i - 1];//位序合理,返回下标为i-1的元素的值
}
//顺序表的按值查找
int LocateElem(Sqlist L, ElemType e) {for (int i = 0; i < L.length; i++){if (L.data[i] == e)return i + 1;//找到对应的值返回位序i+1}return -1;//没有对应的值返回-1
}
//顺序表的插入
bool ListInsert(Sqlist* L, int i, ElemType e) {if (i<1 || i>L->length + 1)//位序小于1,或者位序大于当前表长+1时表示位序不合理return false;//位序不合理返回falseif (L->length >= MaxSize)return false;//当前线性表已存满,返回falsefor (int j = L->length; j >= i; j--) {L->data[j] = L->data[j - 1];//元素往后移动}L->data[i - 1] = e;//将元素e插入位序i的位置L->length++;//当前表长+1return true;//插入成功返回true
}
//顺序表的删除
bool ListDelete(Sqlist* L, int i, ElemType e) {if (i<1 || i>L->length)//位序小于1,或者位序大于当前表长时位序不合理return false;//位序不合理返回falsee = L->data[i - 1];for (int j = i - 1; j < L->length; j++) {L->data[j] = L->data[j + 1];//元素往前移}L->length--;//当前表长-1return true;//删除成功返回true
}

七、无头结点单链表的基本操作

前面的介绍中,我只介绍了有头结点的单链表与双链表的基本操作,这里给大家补上无头结点的单链表的基本操作,其对应的格式如下所示:

//无头结点单链表的基本操作
//单链表类型的声明
typedef struct LNode {ElemType data;//数据域struct LNode* next;//指针域
}LNode, * LinkList;//重命名后的结点类型与单链表类型名
//单链表的初始化
bool InistList(LinkList* L) {if (!L)return false;//L为空指针时返回falseL= NULL;//头指针初始化为空指针return true;//初始化完返回true
}
//单链表的创建——头插法
LinkList List_HeadInsert(LinkList* L){if (!L)return NULL;//当L为空指针时返回NULLLNode* s = NULL;//指向表头结点的指针ElemType x = 0;//存放数据元素的变量……;//获取数据元素while (x != EOF)//为创建过程设置一个终点{//头插操作if (!(*L))//单链表为空表时{*L = (LNode*)calloc(1, sizeof(LNode));//创建表头结点assert(*L);//创建失败报错(*L)->data = x;//将数据元素放入数据域中(*L)->next = NULL;//表头结点指针域指向空指针}else {s = (LNode*)calloc(1, sizeof(LNode));//创建新结点assert(s);//创建失败报错s->data = x;//数据元素存放进数据域中s->next = (*L)->next;//新结点指针域指向表头结点(*L)->next = s;//头指针指向新结点}……;//获取新的数据元素}return *L;//返回创建好的单链表
}
//单链表的创建——尾插法
LinkList List_TailInsert(LinkList* L) {if (!L)return NULL;//当L为空指针时返回NULLLNode* r = NULL;//指向表尾结点的指针LNode* s = NULL;//指向新结点的指针ElemType x = 0;//存放数据元素的变量……;//获取数据元素while (x != EOF)//为创建过程设置一个终点{//尾插操作if (!(*L))//单链表为空表时{*L = (LNode*)calloc(1, sizeof(LNode));//创建表头结点assert(*L);//创建失败报错(*L)->data = x;//将数据元素放入数据域中(*L)->next = NULL;//表头结点指针域指向空指针r = (*L);//表尾指针指向表头结点,此时的表头结点也是表尾结点}else {s = (LNode*)calloc(1, sizeof(LNode));//创建新结点assert(s);//创建失败报错s->data = x;//数据元素存放进数据域中s->next = r->next;//新结点指针域指向表尾结点r->next = s;//表尾结点的指针域指向新结点r = s;//表尾指针指向新结点}……;//获取新的数据元素}return *L;//返回创建好的单链表
}
//单链表的按位查找
LNode* GetElem(LinkList L, int i) {if (!L)return NULL;//单链表为空表时返回NULLif (i < 1)return NULL;//位序不合理时返回NULLint j = 1;//单链表结点的位序LNode* s = L->next;//指向查找结点的指针while (j < i && s)//当位序相等时,结束查找;当s为空指针时,结束查找{s = s->next;//向后遍历}return s;//查找结束,返回当前结点
}
//单链表的按值查找
LNode* LocateElem(LinkList L, ElemType e) {if (!L)return NULL;//当表为空表时返回NULLLNode* s = L->next;//指向查找结点的指针while (s->data == e && s)//当元素相等时,结束查找,当s为空指针时,结束查找{s = s->next;//向后遍历}return s;//查找结束,返回当前结点
}
//单链表的前插操作——指定结点
bool InsertPriorNode(LNode* p, ElemType e) {if (!p)return false;//p为空指针,返回falseLNode* s = (LNode*)calloc(1, sizeof(LNode));//创建新结点assert(s);//创建失败,报错s->data = p->data;//p结点的数据元素放入新结点的数据域中p->data = e;//插入的数据元素放入p结点的数据域中s->next = p->next;//新结点的指针域指向p结点的后继结点p->next = s;//p结点的指针域指向新结点,完成插入操作return true;//插入成功,返回true
}
//单链表的前插操作——指定位序
bool InsertPriorNode(LinkList* L, int i, ElemType e) {if (!L)return false;//L为空指针时返回falseif (!(*L))return false;//单链表为空表时返回falseif (i < 1)return false;//位序不合理时,返回falseLNode* p = GetElem(*L, i - 1);//指向前驱结点的指针LNode* s = (LNode*)calloc(1, sizeof(LNode));//创建新结点assert(s);//创建失败,报错s->data = e;//数据元素放入新结点的数据域中s->next = p->next;//新结点的指针域指向p结点的后继结点p->next = s;//p结点的指针域指向新结点,完成插入操作return true;//插入成功,返回true
}
//单链表的后插操作——指定结点
bool InsertNextNode(LNode* p, ElemType e) {if (!p)return false;//p为空指针,返回falseLNode* s = (LNode*)calloc(1, sizeof(LNode));//创建新结点assert(s);//创建失败,报错s->data = e;//数据元素放入新结点的数据域中s->next = p->next;//新结点的指针域指向p结点的后继结点p->next = s;//p结点的指针域指向新结点,完成插入操作return true;//插入成功,返回true
}
//单链表的后插操作——指点位序
bool InsertNextNode(LinkList* L, int i, ElemType e) {if (!L)return false;//L为空指针时返回falseif (!(*L))return false;//单链表为空表时返回falseif (i < 1)return false;//位序不合理时,返回falseLNode* p = GetElem(*L, i);//指向位序i结点的指针if (!p)return false;//结点p为空指针时,返回falseLNode* s = (LNode*)calloc(1, sizeof(LNode));//创建新结点assert(s);//创建失败,报错s->data = e;//数据元素放入新结点的数据域中s->next = p->next;//新结点的指针域指向p结点的后继结点p->next = s;//p结点的指针域指向新结点,完成插入操作return true;//插入成功,返回true
}
//单链表的删除操作——指定位序
bool ListDelete(LinkList* L, int i, ElemType e) {if (!L)return false;//L为空指针时返回falseif (!(*L))return false;//单链表为空表时返回falseif (i < 1)return false;//位序不合理时返回falseLNode* p = GetElem(*L, i - 1);//位序i的前驱结点if (!p)return false;//结点p为空指针时,返回falseLNode* q = p->next;//需要删除的结点if (!q)return false;//结点q为空指针时,返回falsee = q->data;//需要删除的元素存放在变量e中p->next = q->next;//前驱结点的指针域指向删除结点的后继结点free(q);//释放被删除的结点空间return true;//删除完成,返回true
}
//单链表的删除操作——指定结点
bool ListDelete(LinkList* L,LNode* p, ElemType e) {if (!L)return false;//L为空指针时返回falseif (!(*L))return false;//单链表为空表时返回falseif (!p)return false;//p为空指针时,返回falseLNode* q = (*L)->next;//指向前驱结点的指针while (q->next != p)//判断q是否为p的前驱结点{q = q->next;//向后遍历}q->next = p->next;//前驱结点指向删除结点的后继结点free(p);//释放删除结点的空间return true;//删除完成,返回true
}

结语

到这里咱们今天的内容就全部介绍完了,线性表的相关知识点也全部介绍完了,希望这些内容能帮助大家更好的学习线性表。
接下来我们将开始进入数据结构——栈、队列和数组的学习,大家记得关注哦!最后,感谢各位的翻阅,咱们下一篇再见!!!

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

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

相关文章

轻量应用服务器与云服务器CVM对比——腾讯云

腾讯云轻量服务器和云服务器CVM该怎么选&#xff1f;不差钱选云服务器CVM&#xff0c;追求性价比选择轻量应用服务器&#xff0c;轻量真优惠呀&#xff0c;活动 https://curl.qcloud.com/oRMoSucP 轻量应用服务器2核2G3M价格62元一年、2核2G4M价格118元一年&#xff0c;540元三…

液晶时钟设计

#include<reg51.h> //包含单片机寄存器的头文件 #include<stdlib.h> //包含随机函数rand()的定义文件 #include<intrins.h> //包含_nop_()函数定义的头文件 sbit RSP2^0; //寄存器选择位&#xff0c;将RS位定义为P2.0引脚 sbit RWP2^1; //读写选…

UEFI模拟环境搭建——windows+EDKII

目录 0 说明 1 安装软件 1.1 VS2019的安装 1.2 Python的安装 1.3 IASL的安装 1.4 NASM的安装 1.5 git的下载 2 EDKII的下载 3 配置环境 0 说明 个人感觉UEFI的环境搭建非常复杂&#xff0c;在经过很长一段折磨后&#xff0c;终于还是搭建成功&#xff0c;写下来记录一…

ctfshow——文件上传

文章目录 文件上传思路web 151web 152web 153知识点解题 web 154web 155web 156web 157web 158web 159web160web 161 文件上传思路 web 151 打开页面显示&#xff1a;前台校验不可靠。说明这题是前端验证。 右键查看源代码&#xff0c;找到与上传点有关的前端代码&#xff1a…

软件测试/测试开发丨Linux进阶命令(curl、jq)

1、 curl 接口请求 curl是一个发起请求数据给服务器的工具curl支持的协议FTP、FTPS、HTTP、HTTPS、TFTP、SFTP、Gopher、SCP、Telnet、DICT、FILE、LDAP、LDAPS、IMAP、POP3、SMTP和RTSPcurl是一个非交互的工具 2、 curl 发起 get 请求 -G&#xff1a;使用get请求-d&#xf…

电子邮件地址填写指南:格式与常见问题解答

一个专业的电子邮件地址是一个你只用于工作目的的通信帐户。当你给收件人发送电子邮件时&#xff0c;这是他们最先看到的细节之一。无论你的职位或行业如何&#xff0c;拥有一个专业的电子邮件地址都可以提高你和所在公司的可信度。 在本文中我们解释了专业的电子邮件地址是什么…

2023-12-22 LeetCode每日一题(得到山形数组的最少删除次数)

2023-12-22每日一题 一、题目编号 1671. 得到山形数组的最少删除次数二、题目链接 点击跳转到题目位置 三、题目描述 我们定义 arr 是 山形数组 当且仅当它满足&#xff1a; arr.length > 3存在某个下标 i &#xff08;从 0 开始&#xff09; 满足 0 < i < arr.…

Zookeeper-Zookeeper应用场景实战(二)

1. Zookeeper 分布式锁实战 1.1 什么是分布式锁 在单体的应用开发场景中涉及并发同步的时候&#xff0c;大家往往采用Synchronized&#xff08;同步&#xff09;或者其他同一个 JVM内Lock机制来解决多线程间的同步问题。在分布式集群工作的开发场景中&#xff0c;就需要 一种…

2024年【安全员-A证】考试内容及安全员-A证最新解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 安全员-A证考试内容参考答案及安全员-A证考试试题解析是安全生产模拟考试一点通题库老师及安全员-A证操作证已考过的学员汇总&#xff0c;相对有效帮助安全员-A证最新解析学员顺利通过考试。 1、【多选题】下列关于门…

RHCE9学习指南 第13章 硬盘管理

新的硬盘首先需要对硬盘进行分区和格式化&#xff0c;首先了解一下硬盘的结构&#xff0c;如图13-1所示。 图13-1 磁盘上的磁道和扇区 硬盘的磁盘上有一个个的圈&#xff0c;每两个圈组成一个磁道。从中间往外发射线&#xff0c;把每个磁道分成一个个的扇区&#xff0c;每个扇…

Python高级用法:生成器(generator)

生成器&#xff08;generator&#xff09; 生成器是一种返回生成序列的方法&#xff0c;与直接使用列表等方式返回序列的方式不同的是&#xff0c;他的生成可以是无限的。 生成器可以与next搭配使用&#xff0c;可以被看作是一种特殊的迭代器。 yield语句 yield一般与循环相…

UDP套接字搭建简易服务器与客户端

使用UDP套接字搭建 文章目录 使用UDP套接字搭建前言一、基本结构二、使用步骤1.服务器端2.客户端 三、效果展示总结 前言 这次较上个版本《Python 网络编程之搭建简易服务器和客户端》https://only-me.blog.csdn.net/article/details/135251171增加了&#xff1a; UDP协议来进…

机器学习部分相关概念

数据集(Data Set)即数据的集合&#xff0c;每一条单独的数据被称为样本(Sample)。 对于每个样本&#xff0c;它通常具有一些属性(Attribute)或者特征(Feature)&#xff0c; 特征所具体取得值被称为特征值(Feature Value)。 西瓜数据集 色泽根蒂纹理青绿稍蜷模糊乌黑蜷缩清晰 …

学Python的正确顺序千万别弄反了,到时候后悔就来不及了

学Python的正确顺序&#xff1a;从基础到高级&#xff0c;步步为营 在当今数字化时代&#xff0c;Python已成为最受欢迎的编程语言之一。它不仅广泛应用于数据分析、人工智能和Web开发等领域&#xff0c;还为初学者提供了一个友好且功能强大的平台。然而&#xff0c;学习Python…

matalb实践(十二):减肥

1.题目 2.解答 2.1模型假设 1.体重增加正比于吸收的热量&#xff0c;平均每8000kcal增加体重1kg 2.身体正常代谢引起的体重减少正比于体重&#xff0c;每周每千克体重消耗热量一般在200kcal至320kcal之间&#xff0c;且因人而异&#xff0c;这相当于体重70kg的人每天消耗2000k…

【Spark精讲】一文讲透Spark RDD

MapReduce的缺陷 MR虽然在编程接口的种类和丰富程度上已经比较完善了&#xff0c;但这些系统普遍都缺乏操作分布式内存的接口抽象&#xff0c;导致很多应用在性能上非常低效 。 这些应用的共同特点是需要在多个并行操 作之间重用工作数据集 &#xff0c;典型的场景就是机器学习…

Apollo自动驾驶:改变交通运输的游戏规则

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 ChatGPT体验地址 文章目录 前言1. Apollo缓存层2. 本地状态管理库3. 离线同步和冲突解决4. 离线数据同步和离线优先策略结论 &#x1f4f2;&#x1f50c; 构建离线应用&#xff1a;Apollo…

ssm基于web 的个人时间管理系统+vue论文

基于web 的个人时间管理系统的设计与实现 摘要 当下&#xff0c;正处于信息化的时代&#xff0c;许多行业顺应时代的变化&#xff0c;结合使用计算机技术向数字化、信息化建设迈进。传统的个人时间信息管理模式&#xff0c;采用人工登记的方式保存相关数据&#xff0c;这种以人…

【数据结构】排序之交换排序(冒泡 | 快排)

交换目录 1. 前言2. 交换排序3. 冒泡排序3.1 分析3.2 代码实现 4. 快速排序4.1 hoare版本4.1.1 分析4.1.2 hoare版本代码 4.2 挖坑法4.2.1 分析4.2.2 挖坑法代码实现 4.3 前后指针版本4.3.1 分析4.3.2 前后指针版本代码实现 1. 前言 在之前的博客中介绍了插入排序&#xff0c;…

Linux基础知识学习2

tree命令的使用 可以看到dir2目录下的这些文件&#xff0c;要想显示dir2的具体结构&#xff0c;可用tree命令 mv命令 它可以实现两个功能 1.将文件移动到另一个目录中 2.对某一个文件进行重命名 1.将文件移动到另一个目录中 这里将dir1中的2.txt移动到他的子目录dir3中 执行…