基本数据结构——算法学习(三)上

news/2024/12/26 13:43:39/文章来源:https://www.cnblogs.com/CloverJoyi/p/18632655

数据结构——算法学习(三)上


前言

数据结构是计算机科学的基石,几乎所有的软件开发、算法设计都离不开对数据的组织与管理。它不仅是程序高效运行的保障,也是解决复杂问题的关键工具。学习数据结构的过程,不仅仅是掌握具体的知识点,更是培养逻辑思维能力和问题解决能力的重要途径。

在本章中,我们要讨论如何通过使用指针的简单数据结构来表示动态集合。虽然运用指针可以构造多种复杂的数据结构,但这里只介绍几种基本的结构:栈、队列、链表和有根树。

有限动态集合

概念

可以进行增大、缩小或其他变化的集合,集合中的每个元素都由一个对象表示

常见的动态集合操作

SEARCH(S,k):返回在集合S中指向关键字k的指针,没有则返回NIL

NSERT(S,x):将指针x指向的元素加入到集合S中

DELETE(S,x):将指针x指向的元素从集合S中删除

MINIMUM(S):返回指向全序集S中具有最小关键字元素的指针

MAXIMUM(S):返回指向全序集S中具有最大关键字元素的指针

SUCCESSOR(S,x):返回全序集S中比元素x大的下一个元素的指针,没有则返回NIL

PREDECESSOR(S,x):返回全序集S中比元素x小的前一个元素的指针,没有则返回NIL

线性数据结构

线性数据结构是指数据元素按照线性顺序排列,每个元素仅有一个直接前驱和一个直接后继,常见形式包括数组、链表、栈和队列,广泛应用于数据存储与算法设计中,因其简单直观的特性而成为计算机科学的重要基础。

栈(Stack)实现一种在进行DELETE操作时后进先出(last-in, first-out, LIFO)的策略

栈上的INSERT操作称为压入PUSH,DELETE操作称为弹出POP

对空栈的弹出操作称为栈下溢,若S.top超过了n则称为栈上溢,检查栈空的查询操作STACK_EMPTY

实现栈的空判断、push、pop的伪代码( 这三种栈操作的执行时间都为O(1) )

Function stack-empty(S):if S.top = 0 then return true;else return false;
end
Function push(S,x):if S.top = S.capactity then error "overflow";S.top <- S.top + 1;S[S.top] <- x;
end
Function pop(S):if stack-empty(S) then error "underflow";elseS.top <- S.top - 1;return S[S.top+1];end
end

队列

队列实现一种在进行DELETE操作时先进先出的策略

队列上的INSERT操作称为入队(ENQUEUE),DELETE操作称为出队(DEQUEUE)

队列有队头(head)和队尾(tail)

实现队列ENQUEUE、DEQUEUE操作伪代码

Function enqueue(Q,x):if S.head = S.tail then error "overflow";Q[Q.tail] <- x;if Q.tail = Q.capacity then Q.tail <- 1;else Q.tail <- Q.tail + 1;
end
Function dequeue(Q):if S.head = S.tail then error "underflow";x <- Q[Q.head];if Q.head = Q.capacity then Q.head <- 1;else Q.head <- Q.head + 1;return x;
end

链表

链表是一种元素按线性顺序排列的数据结构,元素的顺序由元素内部的指针决定

链表的几种形式:

  • 单链接链表中元素没有prev指针,双链接链表不省略
  • 已排序链表中元素的线性顺序与关键字线性顺序一致,未排序链表元素可按任意顺序出现
  • 循环链表中表头元素的prev指针指向表尾元素,表尾元素的next指针指向表头元素

无哨兵的链表操作实现伪代码:

Function list-search(L,k):x <- L.head;while x != NIL and x.key != k do x <- x.next;return x;
end
Function list-insert(L,x):x.next <- L.head;if L.head !=NIL then L.head.prev <- x;L.head <- x;x.prev <- NIL;
end
Function list-delete(L,x):if x.prev != NIL then x.prev.next <- x.next;else L.head <- x.next;if x.next != NIL then x.next.next <- x.prev;
end

带哨兵的链表操作实现伪代码:

Function list-search(L,k):x <- L.nil.next;while x != L.nil and x.key != k do x <- x.next;return x;
end
Function list-insert(L,x):x.next <- L.nil.next;L.nil.next.prev <- x;L.nil.next <- x;x.prev <- L.nil;
end
Function list-delete(L,x):x.prev.next <- x.next;x.next.prev <- x.prev;
end

图和树

有向图G是一个二元组(V,E),其中V是有限集,E是V上的二元关系。集合V称为图G的顶点集,其元素称为顶点。集合E是G的边集,其元素称为边。图中可能存在自环

有向图G = (V,E),其中V = {1,2,3,4,5,6},E = {(1,2),(2,2),(2,4),(2,5),(4,1),(4,5),(5,4),(6,3)}

在无向图G = (V,E)中,边集E由无序的顶点对组成,其中V = {1,2,3,4,5,6},E={(1,2),(1,5),(2,5),(3,6)}

概念

一、自由树

自由树是一个连通的、无环的无向图,不连通的无环无向图称为森林,对于自由树G = (V,E),有|E| = |V|-1


二、有根树

有根树是一棵自由树,存在一个顶点作为树的根。

从有根树T中的一个结点x到根r的简单路径上的任一结点y称为x的一个祖先,x是y的后代。每个结点既是自己的祖先也是自己的后代。若y是x的祖先且y≠x,则y是x的真祖先;若y是x的后代且y≠x,则y是x的真后代

以x为根的子树是根为x由x的后代组成的有根树

如果从根r到结点x的简单路径上的最后一条边是(y,x),则y是x的父结点,而x是y的子结点。若两个结点有相同的父结点,则它们是兄弟。一个没有子结点的结点为叶结点(或外部结点),非叶结点也称内部结点

有根树T的结点x的度等于其子结点的数目,从根r到结点x的简单路径的长度即为x在T中的深度,有根树T的高度等于树中结点的最大深度


三、有序树

有序树是每个结点的子结点都有序有根树


四、二叉树

二叉树T是定义在有限结点集上的结构,它或者不包含任何结点,或者包含三个不相交的结点集合:一个根结点,一棵称为左子树的二叉树,一棵称为右子树的二叉树,不包含任何结点的二叉树称为空树或零树,有时用符号NIL表示

若左子树非空,则它的根结点称为整棵树的根的左孩子;类似地,非空右子树地根称为整棵树的根的右孩子,如果一棵子树是零树,则称该孩子是缺失的

二叉树不仅仅是一棵结点度数均为2的有序树,一棵满二叉树的每个结点或是叶结点或度为2


五、完美二叉树和完全二叉树

完美二叉树的所有内部结点均有2个子结点,所有叶结点深度相同,高度为k完美二叉树包含2^k-1个结点

•完全二叉树除最后一层外其余层都是满的,且最后一层要么是满的,要么在右边缺少若干连续结点,高度为k的完全二叉树最少有2(k-1)个结点,最多有2k-1个结点,一个包含n个结点的完全二叉树高度为⌊lg⁡n ⌋+1


二叉树的表示

每个结点具有三个属性p、left和right,分别存放指向父结点、左孩子和右孩子的指针,如果x.p=NIL,则x是根结点;如果x没有左孩子,则x.left=NIL;如果x没有右孩子,则x.right=NIL,T.root指向整棵树的根结点,如果T.root=NIL则该树为空

对于每个结点至多有k个孩子的有根树,每个结点维护k个指针可能造成大量空间浪费,使用左孩子右兄弟表示法来避免空间浪费,每个结点维护三个指针:

  1. 指向父结点的指针x.p
  2. 指向最左边孩子的指针x.left_child
  3. 指向右侧相邻兄弟的指针x.right_sibling

如果结点x没有孩子结点,则x.left_child=NIL;如果结点x是其父结点的最右孩子,则x.right_sibling=NIL

二叉堆

二叉堆是一棵完全二叉树

二叉堆有两种形式:

  • 最大堆(大根堆)
    除根结点外的所有节点满足A[parent(i)]≥A[i]
  • 最小堆(小根堆)
    除根结点外的所有节点满足A[parent(i)]≤A[i]

实现维护二叉堆的性质(假定根节点为left(i)和right(i)的二叉堆都是最大堆)

//递归
Function max-heapify(A,i): l <- left(i); r <- right(i); if l <= A.heapSize and A[l] > A[i] then largest <- l; else largest <- i; if r <= A.heapSize and A[r] > A[i] then largest <- r; if largest != i then exchange A[j] with A[largest]; max-heapify(A,largest); end 
end//非递归
Function max-heapify(A,i): while i <- A.heapSize/2 do l←left(i); r←right(i); if l <= A.heapSize and A[l] > A[i] then largest <- l; else largest <- i; if r <= A.heapSize and A[r] > A[i] then largest <- r; if largest != i then exchange A[i] with A[largest]; i <- largest; end else break; end 
end

建堆

Function build-max-heap(A):A.heapSize <- A.length;for i <- [A.length/2] downto 1 domax-heapify(A,i);end
end

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

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

相关文章

电脑永久免费云存储空间,什么是云存储

在当今全球化的背景下,远程连接技术的重要性愈发凸显。它使得分布在世界各地的团队成员能够实时协作,共享资源,共同推进项目的进展。无论是跨国公司的远程办公,还是国际学术研究中的数据共享,远程连接都发挥着关键的作用,促进了信息的流通和知识的传播。这次给大家介绍什…

这 30 款 IDEA 宝贝插件,顶级优秀!

这 30 款 IDEA 宝贝插件,顶级优秀!头上一片天空 Java知音 2024年12月26日 10:05 河北1、Translation源码英文翻译插件源码中很多注解都是英文,有时候看着有点费劲。这款翻译插件基本上与Idea一体化,从集成度和方便程度来说,可以吊打其他的第三方翻译软件了。不需要你切换窗…

龙哥量化:通达信文华技术指标-双均线策略叠加分时均线,量化策略思路详细分析

如果您需要代写技术指标公式, 请联系我。 龙哥QQ:591438821 龙哥微信:Long622889 也可以把您的通达信,文华技术指标改成TB交易开拓者、金字塔、文华8的自动交易量化策略 开始分享一些细致化的思路和写法,我常用的是TB交易开拓者。对量化感兴趣的朋友可以多交流 这篇介绍重…

MDS100-16-ASEMI电机专用整流模块MDS100-16

MDS100-16-ASEMI电机专用整流模块MDS100-16编辑:ll MDS100-16-ASEMI电机专用整流模块MDS100-16 型号:MDS100-16 品牌:ASEMI 封装:M18 正向电流:100A 反向电压:1600V 引脚数量:5 芯片个数:6 芯片尺寸:50MIL 漏电流:>10ua 恢复时间:>2000ns 浪涌电流:920A 芯片…

Nginx使用手册

由于格式和图片解析问题,为了更好的体验可前往 阅读原文Nginx(发音为 "engine-x")是一个高性能、开源的HTTP和反向代理服务器,也可以作为电子邮件(IMAP/POP3)代理服务器、以及通用的TCP/UDP代理服务器。它由俄罗斯的程序员Igor Sysoev创建于2002年,其目的是解…

在线性坐标系中绘制三角函数图象

本文记述了用 Matplotlib 在线性坐标系中绘制三角函数图象的例子。 代码主体内容如下: ...def main():fig, axs = plt.subplots(1, 3, figsize=(14,4.5)) #1axs[0] = configure_axes(axs[0], Trigonometric Function\t\t\t + r$sine$, 2*np.pi, 1, np.pi, np.pi/2…

美团后端暑期一面,本来收到感谢信,但又复活了!

今天来分享的是一位读者的美团暑期实习一面面经,主要是一些常规八股,难度还是有的,部分题目确实不太好回答。这位同学回答的不是很好,本来是收到感谢信了。结果,过几天又收到复活赛邀请,复活赛倒是打赢了,已oc。 1、线程池的参数/*** 用给定的初始参数创建一个新的Threa…

Makefile文件中,两个$的变量变量$$Xxx 与一个$的变量 $Xxx的区别

使用来引用 Makefile 中的变量。使用$$来引用 shell 中的变量,以确保在传递给 shell 时保留单个符号。原文地址:Makefile文件中,两个$的变量变量$$Xxx 与一个$的变量 $Xxx的区别Makefile 中的变量引用 在 Makefile 中,$ 符号用于变量替换,但它的使用方式有一些细微的区别:…

【日记】各位圣诞节快乐呀!(566 字)

正文不知道为什么最近总是做噩梦。昨天晚上梦到我一枪射死鱼儿,然后兄长用一瓶 4 块钱 1L 的冰红茶将我敲死,最后全人类死于小行星撞地球。有一颗小行星刚好降落在我家附近的山上,然后散射出了无数激光,把我家切割成一块一块的。也没塌,不知道哪个巫师用了魔法,把周围的房…

LDA主题模型——Python实现(三)

img { display: block; margin-left: auto; margin-right: auto } table { margin-left: auto; margin-right: auto } LDA假设每个文档都是多个主题的混合,每个主题又是多个词语的混合。它通过识别文档中的词语分布来推断出文档的主题结构。LDA的一个简单比喻是冰淇淋店:每个…

工具大全-dirsearch探测Web目录

目录扫描工具dirsearch非常详细使用方法dirsearch介绍dirsearch是一款开源的、基于Python开发的命令行工具,主要用于对Web服务器进行目录和文件的扫描,以发现潜在的安全漏洞。 dirsearch下载地址: https://github.com/maurosoria/dirsearch 运行环境:必须安装python3为什么…