王道408数据结构——第二章 线性表

文章目录

  • 一、线性表的定义和基本操作
    • 线性表
    • 顺序表
      • 1.插入操作
      • 2.删除操作
      • 3.按值查找(顺序查找)
  • 二、单链表
      • 1. 头插法
      • 2. 尾插法
      • 3. 按序号查找
      • 4. 按值查找
      • 5. 插入结点
      • 6. 删除结点
      • 7. 求表长
  • 三、 双链表
      • 1. 插入
      • 2. 删除
  • 四、循环链表
  • 五、静态链表
  • 六、顺序表和链表的比较
  • 七、特殊矩阵的压缩储存
    • 数组的定义
    • 数组的存储结构
    • 矩阵的压缩存储
      • 1. 对称矩阵
      • 2. 三角矩阵
      • 3. 三对称矩阵(带状矩阵)
      • 4. 稀疏矩阵
  • 八、广义表
    • 广义表的定义
    • 广义表的操作

一、线性表的定义和基本操作

线性表

线性表是具有相同数据类型的n个数据元素的有限序列,其中n为表长,n=0是为一个空表。除第一个元素外,每一个元素有且仅有一个直接前驱,除最后一个元素外,每一个元素有且仅有一个直接后驱

顺序表

线性表的顺序存储称为顺序表,是用一组地址连续的存储单元一次存储线性表中的数据结构,从而使得逻辑上相邻的两个元素在物理位置上也相邻
线性表的位序是从1开始的,而数组元素的下标从0开始。

1.插入操作

最好情况:表尾插入,时间复杂度O(1)
最坏情况:表头插入,时间复杂度O(n)
平均情况:n/2
平均时间复杂度:O(n)

2.删除操作

最好情况:删除表尾元素,时间复杂度O(1)
最坏情况:删除表头元素,时间复杂度O(n)
平均情况:(n-1)/2
平均时间复杂度:O(n)

顺序表插入和删除的时间主要耗费在移动元素上,而移动元素的个数取决于插入删除元素的位置。

3.按值查找(顺序查找)

最好情况:查找的元素在表头,时间复杂度O(1)
最坏情况:查找的元素在表尾或不存在,时间复杂度O(n)
平均情况:(n+1)/2
平均时间复杂度:O(n)

二、单链表

线性表的链式存储又称单链表,指通过一组任意的存储单元来存储线性表中的数据元素。对每个链表结点,除存放元素自身信息外,还需要存放一个指向其后继节点的指针。
利用单链表可以解决顺序表需要大量连续存储单元的缺点,但单链表附加指针域,存在浪费空间的缺点。由于单链表的元素离散地分布在存储空间中,所以单链表是非随机存取的存储结构。

如果要访问某个结点的前去前驱结点,只能从头开始遍历。

头节点:在单链表的第一个结点前附加一个结点。头结点可以不设任何信息,也可以记录表长等信息。引入头结点可以带来两个优点:

  1. 链表的第一个位置的操作可以和其他位置相统一。
  2. 无论链表是否为空,其头指针都指向头结点,因此空表和非空表的操作得到统一。

1. 头插法

将新结点插入当前链表的表头,即头结点之后。
读入数据的顺序和生成链表中的元素顺序是相反的,总时间复杂度为O(n)

2. 尾插法

增加一个尾指针,使其始终指向当前链表的尾结点。可使导入数据和链表元素的顺序一致,总时间复杂度为O(n)。

3. 按序号查找

时间复杂度O(n)

4. 按值查找

时间复杂度O(n)

5. 插入结点

插入结点的代码片段如下

p = getElem(L, i-1);  // 移动到插入位置前一个结点
s->next = p->next;
p->next = s;

算法时间开销主要在于查找第i-1个元素,时间复杂度为O(n);如果在给定结点后插入,时间复杂度仅为O(1)。

6. 删除结点

代码片段如下

p = getElem(L, i-1);
q = p->next;
p->next = q->next;
free(q);
// 第二、三步顺序不能颠倒

该算法的时间复杂度也耗费找查找操作上,时间复杂度为O(n)。

7. 求表长

时间复杂度O(n)

三、 双链表

双链表结点有两个指针,分别指向其前驱结点和后继结点。

1. 插入

在p所指结点之后插入*s

s->next = p->next;
p->next->prior = s;
s->prior = p;
p->next = s;
/// 第一、二步必须在第四步之前

2. 删除

p后删除q

p->next = q->next;
q->next->prior = p;
free(q);

四、循环链表

将单链表最后一个结点的指针改为指向头结点,形成循环单链表。判空条件是头结点的指针是否指向自身。

循环单链表可以从表中任意一个结点开始遍历整个链表。
有时单链表常用操作是在表头和表尾进行的,此时不设头指针而仅设尾指针。

五、静态链表

借助数组来描述线性表的链式结构,结点也有数据域和指针域。与链表的指针不同,静态链表的指针是结点的相对地址(数组下标),又称游标
静态链表需要预先分配一块连续的内存空间。

六、顺序表和链表的比较

——————顺序表链表
存取(读写)方式既可以顺序存取,也可以随机存取只能从表头顺序存取元素
逻辑结构与物理结构逻辑上相邻的元素,对应的物理存储位置也相邻逻辑上相邻的元素,物理存储位置不一定相邻,其对应的逻辑关系通过指针链接来表示
按值查找顺序表有序时,可采用折半查找,时间复杂度为O(log2n)O(log_2n)O(log2n),若无序,时间复杂度为O(n)时间复杂度为O(n)
按序号查找顺序表支持随机访问,时间复杂度仅为O(1)时间复杂度为O(n)
插入、删除平均需要移动半个表长的元素只需修改相关结点的指针域
空间分配在静态存储分配情形,一旦存储空间装满就不能扩充,加入新元素会导致内存溢出,因此需要预先分配足够大的空间。但预先分配过大,会导致后部空间大量闲置;动态存储分配虽然存储空间可以扩充,但需要移动大量元素,导致操作效率降低,若内存没有更大块的连续存储空间,则会导致分配失败。链式存储的结点空间只需在需要是申请,只要内存有空间就可以分配,操作灵活、高效。

如何选取存储结构:

  • 基于存储考虑:难以估计线性表的长度或存储规模时,不宜采用顺序表;链表实现不用估计存储规模,但链表的存储密度较低。
  • 基于运算考虑:如经常做的运算时按序号访问元素,则顺序表优于链表;如经常进行插入、删除操作,链表较优。
  • 基于环境考虑:任何高级语言都有数组类型,顺序表较容易实现;链表的操作是基于指针的。

通常,较稳定的线性表选择顺序存储,而频繁进行插入、删除操作的线性表(动态性强)宜选择链式存储。

七、特殊矩阵的压缩储存

数组的定义

数组是由n(n ≥\ge 1)个相同类型的数据元素构成的有序序列。
每个元素在线性关系中的序号称为该元素的下标,下标的取值范围称为数组的维界
数组是线性表的推广:一维数组可视为一个线性表,二维数组可视为其元素也是定长线性表的线性表。
数组一旦被定义。其维数和维界就不再改变,因此除初始化和销毁外,数组只有存取元素和修改元素的操作。

数组的存储结构

对于多维数组,有按行优先按列优先两种映射方法。

设二维数组Ah1×h2A_{h_1\times h_2}Ah1×h2的行下标和列下标范围分别为[l1,h1],[l2,h2][l_1,h_1],[l_2, h_2][l1,h1][l2,h2]
其按行优先存储时LOC(ai,j)=LOC(al1,l2)+[(i−l1)×(h2−l2+1)+(j−l2)]×LLOC(a_{i,j})=LOC(a_{l_1,l_2})+[(i-l_1)\times (h_2-l_2+ 1)+(j-l_2)]\times LLOC(ai,j)=LOC(al1,l2)+[(il1)×(h2l2+1)+(jl2)]×L其按列优先存储时,LOC(ai,j)=LOC(al1,l2)+[(j−l2)×(h1−l1+1)+(i−l1)]×LLOC(a_{i,j})=LOC(a_{l_1,l_2})+[(j-l_2)\times (h_1-l_1+1)+(i-l_1)]\times LLOC(ai,j)=LOC(al1,l2)+[(jl2)×(h1l1+1)+(il1)]×L

矩阵的压缩存储

为多个值相同的元素只分配一个存储空间,对零元素不分配存储空间,目的是节省空间。

1. 对称矩阵

将对称矩阵A[1…n][1…n]存放在一维数组B[n(n+1/2)]中,只存放下三角部分的元素。

2. 三角矩阵

下三角矩阵中,上三角区的所有元素均为同一常量,其储存思想与对称矩阵类似,不同之处在于储存完下三角区和主对角线上的元素后,在储存上三角取的常量一次。

943 2019年选择第9题默认矩阵下标从0开始

3. 三对称矩阵(带状矩阵)

三对角线上的元素ai,ja_{i,j}ai,j在一维数组中的下标为k=2+3(i-1)+(j-i+1)-1=2i+j-1(数组和元素下标均从0开始)。

4. 稀疏矩阵

矩阵中非零元素个数远小于矩阵元素的矩阵。
通常将非零元素及其相应的行和列构成一个三元组,然后按照一定规则储存这些三元组。
稀疏矩阵压缩存储后便失去了随机存储的特性。

八、广义表

c++中union关键字详见

广义表的定义

广义表的操作

getHead():获得广义表的第一个元素;
getTail():获得以广义表出第一个元素外的其余元素构成的广义表

如:A=(a), B=(b,c,d),C=(()),那么
getHead(A)=a, getHead(B)=b, getHead(C)=()
getTail(B)=(), getTail(B)=(c,d), getTail(C)=()

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

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

相关文章

C和指针之用拉托斯特尼筛方法(Eratosthenes)查找区间质素个数

1、问题 用拉托斯特尼筛方法(Eratosthenes)查找区间质素个数 2、代码实现 #include <stdio.h> #define LEN 10000 /***Eratosthenes-埃拉托斯特尼筛方法找质数,给出要筛数值的范围n,先用2去筛,2的倍数不是质数,* 再用下一个素数,也就是3筛,把3留下,把3的倍数不是…

Mysql数据库性能优化

2019独角兽企业重金招聘Python工程师标准>>> Mysql数据库性能优化&#xff0c;可以从下面三点入手&#xff1a; 数据库设计 SQL语句优化 架构优化 一.数据库设计优化 1.适度的违反范式&#xff0c;适度 遵循三大范式就会带来查询时经常需要join&#xff0c;导致…

BZOJ 2588: Spoj 10628. Count on a tree 树上跑主席树

2588: Spoj 10628. Count on a tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php?id2588Description 给定一棵N个节点的树&#xff0c;每个点有一个权值&#xff0c;对于M个询问(u,v,k)&#xff0c;你需要回答u xor las…

session多服务器共享的方案梳理

因方便自己学习以此记录本文转自&#xff1a;http://www.cnblogs.com/wangtao_20/p/3395518.html#2846008session的存储了解以前是怎么做的&#xff0c;搞清楚了来龙去脉&#xff0c;才会明白进行共享背后的思想和出发点。我喜欢按照这样的方式来问(或者去搞清楚)&#xff1a;为…

4. 堪比JMeter的.Net压测工具 - Crank 进阶篇 - 认识wrk、wrk2

1. 前言上一篇文章我们了解了bombardier&#xff0c;并知道了bombardier.yml与开源项目bombardier的关系&#xff0c;接下来的文章我们了解一下wrk、wrk2&#xff0c;并对比一下它们与bombardier的关系2. 认识wrkwrk是一种现代 HTTP 基准测试工具&#xff0c;能够在单个多核 CP…

王道408数据结构——第三章 栈和队列

一、栈 栈&#xff08;Stack&#xff09;是只允许在一端进行插入或删除操作的线性表。 栈顶&#xff1a;线性表允许插入删除的那一端 栈底&#xff1a;固定的、不允许进行插入删除的另一端 栈的操作特性可以概括为后进先出&#xff08;LIFO&#xff09; n个不同的元素进栈&…

C和指针之const、#define、volatile

1、const 定义const 只读变量,具有不可变形 const int a = 100; 编译器通常不为普通Const只读变量分配存储空间, 而是将它们保存在符号表中, 这使得它成为一个编译期间的值,没有了存储与读内存操作,使用效率很高 #define M3 //宏常量const int N = 5; //此时并没有将…

dispatchTouchEvent onInterceptTouchEvent onTouchEvent区分

1. dispatchTouchEvent 是处理触摸事件分发,执行super.dispatchTouchEvent(ev)&#xff0c;事件向下分发。 2. onInterceptTouchEvent是ViewGroup提供的方法&#xff0c;默认返回false&#xff0c;返回true表示拦截。 3. onTouchEvent是View中提供的方法&#xff0c;ViewGroup也…

Avalonia跨平台入门第二十篇之语音播放问题

在前面分享的几篇中咱已经玩耍了Popup、ListBox多选、Grid动态分、RadioButton模板、控件的拖放效果、控件的置顶和置底、控件的锁定、自定义Window样式、动画效果、Expander控件、ListBox折叠列表、聊天窗口、ListBox图片消息、窗口抖动、语音发送、语音播放;今晚加个班来解决…

递归算法浅谈

递归算法 程序调用自身的编程技巧称为递归&#xff08; recursion&#xff09;。   一个过程或函数在其定义或说明中又直接或间接调用自身的一种方法&#xff0c;它通常把一个大型复杂的问题层层转化为一个与原问题类似的规模较小的问题来求解&#xff0c;递归策略仅仅需少量…

C和指针之实现strlen函数

1、问题 求字符串长度,实现strlen函数。 2、代码实现 #include <stdio.h> #include <assert.h>int get_strlen(char *str) {assert(NULL != str);return *str == \0 ? 0 : (1 + get_strlen(++str)); }int main() {char *str = "chenyu";char…

王道408数据结构——第四章 串(KMP算法)

一、串的定义和实现 字符串简称串&#xff0c;是由零个或多个字符组成的有限序列&#xff0c;一般记为S′a1a2⋅⋅⋅an′Sa_1a_2a_nS′a1​a2​⋅⋅⋅an′​&#xff0c;n称为串的长度。 串中任意多个连续字符组成的子序列称为该串的子串&#xff0c;相应的该串称为主串。某个…

ThoughtWorks技术雷达专区

作为一家服务于全球不同类型的IT专业服务公司&#xff0c;ThoughtWorks从未停止过对卓越技术的追求&#xff0c;为此&#xff0c;ThoughtWorks的全球技术委员会(TAB)会定期讨论技术战略&#xff0c;并将其绘制成一份能够体现技术趋势的雷达图&#xff0c;它相当于当下技术领域的…

腾讯视频VIP周卡深圳地区免费领!附非深圳免费领腾讯视频会员攻略

深圳今天开始&#xff0c;暂停了所有公共交通&#xff0c;小区开始封闭管理&#xff0c;大家都居家办公&#xff0c;腾讯官方今天给深圳地区用户免费发放7天腾讯视频VIP会员&#xff0c;居家期间&#xff0c;可以追剧了&#xff01;这是腾讯官方给深圳地区的抗疫福利&#xff0…

编译器与解释器

什么是编译器&#xff1f;什么事解释器&#xff1f; 编译器是女儿&#xff0c;解释器是儿子。为什么这么说呢&#xff1f; 引用文章 http://www.cnblogs.com/sword03/archive/2010/06/27/1766147.html 大概总结就是&#xff1a;妈给儿子和女儿打电话说&#xff1a;你们的老爸不…

SQL Server 权限的分类

SQL Server 的权限可以分三类 第一类 server 层面上的&#xff1a; select * from sys.fn_builtin_permissions(default) where class_desc like server; 第二类 database 层面&#xff1a; select * from sys.fn_builtin_permissions(default)    where class_desc like d…

C和指针之部分理解和编码总结

1、在C语言中,当一维数组作为函数参数的时候,编译器总是把它解析成一个指向成一个指向其首元素首地址的指针 这也就是为什么数组int a[10],a不能a++操作,而把a传递给函数的时候,可以作为指针a++操作的原因。 2、内存为0的地址处,也就是NULL地址处,一般定义指针变量的同时…

王道408数据结构——第五章 树与二叉树

文章目录一、树的基本概念树的性质二、二叉树满二叉树完全二叉树二叉排序树平衡二叉树二叉树的性质完全二叉树的性质三、二叉树的储存结构顺序储存链式存储四、树的储存方式双亲表示法孩子表示法孩子兄弟表示法&#xff08;二叉树表示法&#xff09;五、二叉树的遍历先序遍历&a…

Redis集群监控RedisClusterManager

Redis集群监控RedisClusterManagerRedisClusterManager监控Redis集群1234环境要求&#xff1a;Java8jdk配置这里略过RedisClusterManager 下载地址&#xff1a;https://git.oschina.net/yanfanVIP/RedisClusterManager/releases1234567891011121314151617181920212223242526272…

Visual Studio怎么使用中文帮助文档

今天给大家带来vs中怎么使用帮助文档&#xff1f;事情起因是这样的&#xff0c;上周有个哥们问我问题&#xff0c;字符串怎么分割啊&#xff0c;我当时有点忙&#xff0c;我就说你去看看帮助文档。然后过了三十秒 我看见他打开了百度。。。。。。我郁闷了 &#xff0c;我说你直…