3.数据结构

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

插入和删除不方便
链表:不连续方式,相对定位,访问不方便,速度慢;
插入和删除方便。

线性结构反映到线性结构(内存)
逻辑结构的物理实现(物理结构)

二叉树:
链式存储:从根开始遍历,链表中指针指示树中的
关系。 数组存储:树中的关系利用数组下标的关系计算得 出。
其它树:
孩子兄弟表示法转换成二叉树
树和二叉树


层次结构 二叉树:有根有序树
数组实现 链表实现(更常用)

二叉树的遍历 设树T的前序、中序、后序遍历序列为PreOrder(T), InOrder(T)和PostOrder(T),则有:
PreOrder(T)={Root(T), PreOrder(L), PreOrder(R)} InOrder(T)={InOrder(L), Root(T), InOrder(R)} PostOrder(T) ={PostOrder(L), PostOrder(R), Root(T)}

另一种方法:序贯方法
其它数据结构

集合 并查集 字典 哈希表
集合及其表示
集合基本概念


集合是成员(元素)的一个群集。集合中的成 员可以是原子(单元素),也可以是集合。 集合的成员必须互不相同。

在算法与数据结构中所遇到的集合,其单元 素通常是整数、字符、字符串或指针,且同 一集合中所有成员具有相同的数据类型。 例:colour = { red, orange, yellow, green, black, blue, purple, white }

图分为无向图(undirected graph) 和有向图(directed graph) 两种。 图最常用的表示法是邻接矩阵和邻接表。 图的连通分量(4和8连通) 查找连通分量方法--种子填充的方法 算法的基本思想:
从上到下从左到右地检查每一个方格,每找到一个未标记方格就从它出 发找到一个完整的连通分量。如何找到一个完整的连通块?设臵一 个队列,初始时只有那个方格。每次从队首取出一个方格,把它相 邻的具有同样属性方格中没有放入过队列的那些全部放入队列中。

小机器人的一种实现方式


当你扔一枚硬币进来的时候,它什么都不做,自己睡大觉; 当你按按钮的时候,它慌了,赶紧找钱。它先随便挑出一个硬币拿在手 里,然后把其他所有硬币的看一遍,如果发现更值钱的,就用把手里的 硬币换掉,最后手里拿着的就是最值钱的硬币,然后从孔里扔出去。
void new_coin () { zzzZZZ (); }
层次序遍历二叉树的算法

层次序遍历二叉树就是从根结点开始,按层次 逐层遍历,如图:
+ a b c /
*
-
e
f
d
遍历顺序


这种遍历需要使用一个先进先出的队列,在 处理上一层时,将其下一层的结点直接进到 队列(的队尾)。在上一层结点遍历完后, 下一层结点正好处于队列的队头,可以继续 访问它们。 算法是非递归的。
链表
组成元素:数据;链接指针
头结点:保证链表中至少有一个结点,统一
操作 单向链表 双向链表 循环链表 链表的遍历


队列和栈可以看作优先队列的特殊情况。
队列(queue) 的特点是先进队的元素先出队,好比在食堂排 队买饭。 队列的先进先出(First In First Out, FIFO) 特性体现了元素的 公平性,在算法中往往被用来放臵还没来得及处理的,应维 持某种顺序的元素。这个特点是广度优先遍历算法的基础, 因为所有待扩展结点需要按照深度从小到大依次处理。 栈(stack) 的特点是后进栈的元素先出栈。只有一端允许操作 的结构往往都是这样。例如:往抽屉里放东西。 栈的后进先出(Last In First Out, LIFO) 特性体现了元素的局部 性,这个特点是递归、表达式处理和栈统计算法的基础。

每次投入一枚面值相当于执行操作insert,按一次 按钮相当于先执行empty,如果队列不空,则执 行getmax。
线性表

最简单的逻辑结构 前驱和后继 数组:逻辑上连续、物理上也连续 数组的操作 插入:涉及到元素的移动(移动顺序从后往前),元素 个数加1 删除:涉及到元素的移动(移动顺序从前往后),元素 个数减一 数组的反转 借助于辅助数组 按替换关系进行交换 两个元素的交换 借助辅助变量 使用异或运算符:a = a xor b; b = a xor b; a = a xor b

小机器人的另一种实现


拿几个不同的小桶,每个桶装一种面值的硬币。假设一共有 1元、5角、1角、5分、2分和1分共6种面值的硬币,则只需 要六个桶。 当来了一枚新硬币时,小机器人把它放到相应的盒子中; 需要找钱时,小机器人只需要看1元的盒子里有没有硬币, 有的话随便拿一个扔出去;如果没有的话再看5角的盒子有 没有硬币,有的话随便拿一个扔出去。不管有多少硬币,只 要盒子装得下,总是最多只需要开6次桶即可,即使每开一 个桶需要5秒钟,有1,000,000个硬币时最多也只需要半分钟, 比刚才的2.8小时快多了。
点。用于稀疏图可以降低存储空间。
外部特性和内部结构
物理结构、逻辑结构中的某些属性可以被外界所感 知,而另外一些属性却是不可见的。 数据结构包含外部特性和内部结构两个方面。外部 特性决定了它将如何被使用,而内部结构决定了它 的原理和具体实现。 初学数据结构时,可以更多的关注它们的外部特性, 在熟练使用并体会到数据结构的好处之后再学习它 们的内部结构,并根据其中的设计思想创造出新的 数据结构。



相同的外特性(自动储钱罐)可以用多种
结构(小机器人的程序中的内部结构)实 现,它们的时间效率可能不同,空间开销 也可能不同(新程序需要用附加盒子)
更好的实现方式:最大堆,无论什么情况
只要1次
抽象数据类型

抽象数据类型(Abstract Data Types, ADT) 是只通过接口访问的 数据类型(数据类型是指值集合和值上的操作集合)。
= (V,E),其中G为图,V为结点集,E为 边集。 例如:Internet的拓扑结构
图中的相关概念: 有向图,无向图 带权图(网) 完全图,稀疏图
度,路径,连通分量
。。。。。 线性结构是树的特殊情况,树是图的特殊情况
逻辑结构的物理实现(物理结构)

线性结构的物理实现
数组:连续方式,绝对地址定位,访问方便,速度快;
除了最后一个元素之外,每一个元素都有唯 一的“上一个元素”和“下一个元素”。这 是最简单的逻辑结构。 树型结构:具有层次性,看起来像是一棵倒 立的“树”。在树状结构中,强调的是结点 之间的关系。
树的相关概念:结点、树根、叶子,祖先、 父亲,双亲、儿子、孩子、子树、兄弟
网状结构
任意两个结点之间都可能有联系 G


有一只自动储钱罐,它有一个孔和一个按钮。存 钱的时候,你可以从小孔往里面投一枚硬币;取 钱的时候,只要按一下按钮,面值最大的硬币就 会从孔里掉出来。
自动储钱罐的设计者告诉你:钱罐里有一个很小 的机器人,每次按下按钮的时候,它就从钱罐里 找出最值钱的一枚,从孔里扔出来。如果硬币有 很多的话,从一大堆钱里找到最值钱的硬币是需 要花时间的,所以可能你按下按钮以后需要等待 几分钟,让小机器人慢慢找。
逻辑结构的物理实现(物理结构)

邻接矩阵(adjacency matrix) 直接记录结点之间是否有边,方便于直接判断两
个点之间是否有边;缺点:存储空间占用大,用 于稠密图。(写出的算法相对比较简单,好理解)
邻接表(adjacency list)
为每个结点做一个链表,记录与之相邻的所有结
栈和队列
队列的操作限定在线性表的两头
队首:出队(Dequeue),删除,first指针 队尾:入队(Enqueue),插入,last指针 first和last均逐渐增大
循环队列
x=queue[first] ; first=(first+1)%n;
queue[last]=x; last=(last+1)%n; 队列中的元素个数不能超过n



前面的储钱罐就是一个优先队列(priority queue) ADT,每个硬币的优先级就是它的面值。每次优 先级最大的出队。
基本优先队列的操作如下: bool empty():判断队列是否为空 void insert(i, p):往队列里加入一个元素i,优先 级为p int getmax():取得队列里最大元素并把它从队列 里删除
ຫໍສະໝຸດ Baidu




由于coin是无序数组,我们把这种方法称为无序数 组实现法。 这个钱罐“添加硬币”很快(小机器人啥都不做), 找最大面值却很慢。如果小机器人检查一枚硬币的 时间是0.01秒,那么有100个硬币时需要1秒,有 10,000个硬币时需要100秒( 约两分钟) , 而 1,000,000个硬币时就需要10,000秒(约2.8小时)!
使用ADT的程序叫客户端(client) 。 指定数据类型细节的程序叫实现(implementation) 。接口不是 透明的, 即客户端无法看到(往往也不关心)实现, 更无法直接 修改ADT的内部结构。换句话说,可以用接口完全描述一个 ADT,即定义ADT所支持的操作。 抽象数据类型的定义仅取决于数据对象的逻辑特性,和计算机 内部如何实现无关。

栈和队列


栈:先进后出
队列:先进先出 栈和队列从本质上仍是线性表,只不过限定了操作的位臵 (对象) 栈的实现:数组int stack[]和栈顶指针top 插入(push)
stack[++top ] = x ;


删除(pop)(删除的数据仍在栈中,只不过不再有效)
x = stack [ top--];
void delete_max () { int i; int best = 0; for(i = 1; i < coin_count ; i ++) if( coin [i] > coin [ best ]) best = i; throw_away ( best ); } coin[i]表示第i枚硬币,throw away(i)表示把第i枚硬币扔出去且终止程序
数据结构原理
使用原则
尽可能使用简单的数据结构,越简单越不容
易出错 当问题最大输入规模确定时,或不限定但比 较宽松时,使用静态的数据结构(当问题考查使用动
态数据结构能力时,给出的限定会有相应的暗示)
尽可能使用程序设计语言中内置的数据类型
数据结构基础
逻辑结构(数据之间的逻辑关系)
线性结构:特点是:有唯一的“第一元素”。
二叉树的重建
根据二叉树的前序遍历和中序遍历求后序遍

根据前序遍历,我们很容易找到根(它就是前序
遍历的第一个结点)。在中序遍历中找到根的位 臵,就可以找到左子树和右子树各有哪些结点。 对左右子树分别采用同样的方式再继续划分子树。
同理可以根据二叉树的后序遍历和中序遍历
求前序遍历
图的表示



void new_coin (int value ) { count [ value ]++; }
void delete_max () { int i; for(i = 1; i <= 6; i ++) if( count [i ] > 0) throw_away (i); } 其中count[i]表示第i种面值的桶里有多少硬币,throw away(i)表示把一枚面值为i的硬币扔出去。每个count[i]保 存了捅里的硬币数目,我们把这种方法称为桶实现法。 方法虽然好,但是前提是只有6种面值。如果1分、2分、3 分、4分、. . .99元9角8分、99元9角9分、100元整这1万 种面值的硬币都有,那就需要1万个盒子。如果扔的 1,000,000个硬币的面值全部不同,那么这个新方法就没 有任何优势了。




集合中的成员一般是无序的,但在表示它时, 常写在一个序列里。 常设定集合中的单元素具有线性有序关系, 此关系可记作“<”,表示“优先于”。 整数、字符和串都有一个自然线性顺序。指 针也可依据其在序列中安排的位臵给予一个 线性顺序。 在某些集合中保存实际数据值,某些集合中 保存标示元素是否在集合中的指示信息。如 学校开设的所有课程的编码属于前者,一个 学期开设的课程构成的集合属于后者。
相关文档
最新文档