精华内容
下载资源
问答
  • 【单选题】以下程序的输出结果是() x=10 y=0 if(x>5)or(x/y>5): print("Right") else: print("Wrong")(1.0分)【单选题】以下代码的输出结果是() def young(age): if 25...

    【单选题】以下程序的输出结果是() x=10 y=0 if(x>5)or(x/y>5): print("Right") else: print("Wrong")(1.0分)

    【单选题】以下代码的输出结果是() def young(age): if 25<=age<=30: print("年轻有前途") elif age<25: print("参加工作否") elif age>=60: print("可以退休啦") else: print("正值壮年加油干") young(42)(1.0分)

    【单选题】学前儿童一边摆积本,一边自言自话 : “摆的是高楼,摆的是大桥”等,这种思维是 ( ) (5.0分)

    【单选题】在 N 进制中,字符 N 的取值范围为:( )

    【单选题】小红知道 9 颗花生吃掉 5 颗还剩 4 额。却算不出“ 9 -5=? ”,这说明小红的思维具有 ( ) (5.0分)

    【单选题】(2.0分)

    【单选题】“乌云遮月,有雨不到半夜”这一论断反映了思维的 ( ) (5.0分)

    【其它】根据视频操作演示,利用提供素材,完成下图的锐化操作

    【单选题】下列关于分支结构的描述错误的是()(1.0分)

    【单选题】儿 童 思维的发生期是在( )岁 (5.0分)

    【单选题】(2.0分)

    【单选题】以下程序的输出结果是() (1.0分)

    【单选题】键盘输入数字5,以下代码的输出结果是() n=eval(input("请输入一个整数:")) s=0 if n>=5: n-=1 s=4 if n<5: n-=1 s=3 print(s)(1.0分)

    【单选题】已知x=10,y=20,z=30;以下语句执行后x,y,z的值是()。 if x < y: z=x x=y y=z (1.0分)

    【单选题】以下程序的输出结果是() (1.0分)

    【多选题】学前儿童的具体形象思维派生的特点有( ) (10.0分)

    【简答题】html骨架标签有哪些

    【单选题】人们凭借判断,推理和概念来进行的思维,叫 ( ) (5.0分)

    【简答题】一句话说出html作用

    【单选题】我们在头脑中把魁树分解为根、基、花、果实等来分别加以思考的过程是( ) (5.0分)

    【单选题】(2.0分)

    【单选题】以下不属于Python语言控制结构的是() (1.0分)

    【资料题】根据情景描述内容修改下面文本: 情景描述: 刘霞根据领导“不同意购买”的批示意见拟写了一份批复。邓主任认为这是一篇问题文件,返回给刘霞修改。彭总下午要签发,刘霞向你求救。原文如下: 关于不同意购买笔记本电脑的答复 销售部经理: 你部《关于购买20台联想笔记本电脑的请示》收到了。经研究,还是不购买笔记本电脑为宜。 这就是给你部的答复。 新天恒大有限责任公司(印章) ××年××月××日

    【单选题】青青听妈妈说 :" 那孩子的小嘴真甜 !" 青青问 :" 妈妈 , 您舔过她的嘴吗 ?" 这主要反映了青青思维的 ( ) (5.0分)

    【单选题】下列关于Python的描述正确的是()(1.0分)

    【资料题】教师出示饼干盒,问亮亮里面有什么,亮亮说 “饼干”。教师打开饼干盒,亮亮发现里面装的是蜡笔。教师盖上盖子后再问“欣欣没有看过这个饼干盒,等一会儿我去问欣欣盒子里面装的是什么,你猜她么怎么回答 ? ”亮亮很快就说:“蜡笔” 问题: (1) 亮亮更可能是属于哪个年龄班的幼儿 ? (5 分 ) (2) 你判断的依据是什么 ? (25 分) (30.0分)

    【多选题】下列( )是促进学前儿童思维发展的策略。 (10.0分)

    【单选题】当a,b,c,d=1,3,5,4时,执行完下面一段程序后x的值为() (1.0分)

    【单选题】(2.0分)

    【单选题】让学前儿童根据老虎和虎头的关系,摆出牛和牛头,狮和狮头这属于( )的训练。 (5.0分)

    【简答题】HTML元素标签分类及标签关系

    【单选题】护士人文修养的内涵不包括( )

    【单选题】下列数中 , 最大的数是 ( ) 。

    【单选题】" 青年人虚读有朝气、爱学习、讲文明、有礼貌”;“我是青年人”;“我应该有朝气、爱学习、讲文明、有礼貌。这一思维形式称为( ) (5.0分)

    【填空题】

    【单选题】下列关于Python分支的描述中,错误的是()(1.0分)

    【单选题】(2.0分)

    【单选题】(2.0分)

    【单选题】假设从键盘输入的值是20,以下程序的输出结果是() (1.0分)

    【简答题】HTML标签的语义化的作用

    【单选题】(2.0分)

    【简答题】文档类型的作用

    【单选题】医药伦理的核心思想是什么?

    【单选题】以下关于分支结构的描述中,错误的是()(1.0分)

    【简答题】13-1.docx

    【单选题】(2.0分)

    【单选题】4 对“护士修养”理解正确的是( )

    【单选题】发展层的人文修养主要表现为( )

    【单选题】对 “人文修养”理解正确的是( )

    【单选题】老师提出 " 砖头有什作用 " 时,学生从不同角度回答的过程。属于( ) (5.0分)

    展开全文
  • 什么是数据结构

    千次阅读 2019-06-19 20:25:39
    什么是数据结构?数据结构是什么? 数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。数据...

    什么是数据结构?数据结构是什么?

     

    数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关。

     

    定义

    名词定义

    数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成。也就是说,数组结构指的是数据集合及数据之间关系的集合,是两个集合。

    记为:Data_Structure=(D,R)

    其中D是数据元素的集合,R是该集合中所有元素之间的关系的有限集合。 

    数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成。

     

    其它定义

    Sartaj Sahni在他的《数据结构、算法与应用》一书中称:“数据结构是数据对象,以及存在于该对象的实例和组成实 例的数据元素之间的各种联系。这些联系可以通过定义相关的函数来给出。”他将数据对象(data object)定义为“一个数据对象是实例或值的集合”。
    Clifford A.Shaffer在《数据结构与算法分析》一书中的定义是:“数据结构是ADT(抽象数据类型Abstract Data Type) 的物理实现。”
    Robert L.Kruse在《数据结构与程序设计》一书中,将一个数据结构的设计过程分成抽象层、数据结构层和实现层。其中,抽象层是指抽象数据类型层,它讨论数据的逻辑结构及其运算,数据结构层和实现层讨论一个数据结构的表示和在计算机内的存储细节以及运算的实现。
    数据结构具体指同一类数据元素中,各元素之间的相互关系,包括三个组成成分,数据的逻辑结构,数据的存储结构和数据运算结构。

     

    研究对象

    一、数据的逻辑结构:指反映数据元素之间的逻辑关系的数据结构,其中的逻辑关系是指数据元素之间的前后件关系,而与他们在计算机中的存储位置无关。逻辑结构包括:
    集合
    数据结构中的元素之间除了“同属一个集合” 的相互关系外,别无其他关系;
    2.线性结构
    数据结构中的元素存在一对一的相互关系;
    3.树形结构
    数据结构中的元素存在一对多的相互关系;
    4.图形结构
    数据结构中的元素存在多对多的相互关系。
    二、数据的物理结构:指数据的逻辑结构在计算机存储空间的存放形式。 
    数据的物理结构是数据结构在计算机中的表示(又称映像),它包括数据元素的机内表示和关系的机内表示。由于具体实现的方法有顺序、链接、索引、散列等多种,所以,一种数据结构可表示成一种或多种存储结构。
    数据元素的机内表示(映像方法): 用二进制位(bit)的位串表示数据元素。通常称这种位串为节点(node)。当数据元素有若干个数据项组成时,位串中与个数据项对应的子位串称为数据域(data field)。因此,节点是数据元素的机内表示(或机内映像)。
    关系的机内表示(映像方法):数据元素之间的关系的机内表示可以分为顺序映像和非顺序映像,常用两种存储结构:顺序存储结构和链式存储结构。顺序映像借助元素在存储器中的相对位置来表示数据元素之间的逻辑关系。非顺序映像借助指示元素存储位置的指针(pointer)来表示数据元素之间的逻辑关系。
    三、数据结构的运算。

     

    重要意义

              一般认为,一个数据结构是由数据元素依据某种逻辑联系组织起来的。对数据元素间逻辑关系的描述称为数据的逻辑结构;数据必须在计算机内存储,数据的存储结构是数据结构的实现形式,是其在计算机内的表示;此外讨论一个数据结构必须同时讨论在该类数据上执行的运算才有意义。一个逻辑数据结构可以有多种存储结构,且各种存储结构影响数据处理的效率。

             在许多类型的程序的设计中,数据结构的选择是一个基本的设计考虑因素。许多大型系统的构造经验表明,系统实现的困难程度和系统构造的质量都严重的依赖于是否选择了最优的数据结构。许多时候,确定了数据结构后,算法就容易得到了。有些时候事情也会反过来,我们根据特定算法来选择数据结构与之适应。不论哪种情况,选择合适的数据结构都是非常重要的。

             选择了数据结构,算法也随之确定,是数据而不是算法是系统构造的关键因素。这种洞见导致了许多种软件设计方法和程序设计语言的出现,面向对象的程序设计语言就是其中之一。

     

    研究内容

             在计算机科学中,数据结构是一门研究非数值计算的程序设计问题中计算机的操作对象(数据元素)以及它们之间的关系和运算等的学科,而且确保经过这些运算后所得到的新结构仍然是原来的结构类型。

             “数据结构”作为一门独立的课程在国外是从1968年才开始设立的。 1968年美国唐纳德·克努特(Donald Ervin Knuth)教授开创了数据结构的最初体系,他所著的《计算机程序设计艺术》第一卷《基本算法》是第一本较系统地阐述数据的逻辑结构和存储结构及其操作的著作。“数据结构”在计算机科学中是一门综合性的专业基础课,数据结构是介于数学、计算机硬件和计算机软件三者之间的一门核心课程。数据结构这一门课的内容不仅是一般程序设计(特别是非数值性程序设计)的基础,而且是设计和实现编译程序、操作系统、数据库系统及其他系统程序的重要基础。

             计算机科学是一门研究用计算机进行信息表示和处理的科学。这里面涉及到两个问题:信息的表示,信息的处理 。

             而信息的表示和组织又直接关系到处理信息的程序的效率。随着计算机的普及,信息量的增加,信息范围的拓宽,使许多系统程序和应用程序的规模很大,结构又相当复杂。因此,为了编写出一个“好”的程序,必须分析待处理的对象的特征及各对象之间存在的关系,这就是数据结构这门课所要研究的问题。众所周知,计算机的程序是对信息进行加工处理。在大多数情况下,这些信息并不是没有组织,信息(数据)之间往往具有重要的结构关系,这就是数据结构的内容。数据的结构,直接影响算法的选择和效率。

             计算机解决一个具体问题时,大致需要经过下列几个步骤:首先要从具体问题中抽象出一个适当的数学模型,然后设计一个解此数学模型的算法(Algorithm),最后编出程序、进行测试、调整直至得到最终解答。

             寻求数学模型的实质是分析问题,从中提取操作的对象,并找出这些操作对象之间含有的关系,然后用数学的语言加以描述。当人们用计算机处理数值计算问题时,所用的数学模型是用数学方程描述。所涉及的运算对象一般是简单的整形、实型和逻辑型数据,因此程序设计者的主要精力集中于程序设计技巧上,而不是数据的存储和组织上。然而,计算机应用的更多领域是“非数值型计算问题”,它们的数学模型无法用数学方程描述,而是用数据结构描述,解决此类问题的关键是设计出合适的数据结构,描述非数值型问题的数学模型是用线性表、树、图等结构来描述的。

             计算机算法与数据的结构密切相关,算法无不依附于具体的数据结构,数据结构直接关系到算法的选择和效率。运算是由计算机来完成,这就要设计相应的插入、删除和修改的算法 。也就是说,数据结构还需要给出每种结构类型所定义的各种运算的算法。

             数据是信息的载体,是可以被计算机识别存储并加工处理的描述客观事物的信息符号的总称。所有能被输入计算机中,且能被计算机处理的符号的集合,它是计算机程序加工处理的对象。客观事物包括数值、字符、声音、图形、图像等,它们本身并不是数据,只有通过编码变成能被计算机识别、存储和处理的符号形式后才是数据。

             数据元素是数据的基本单位,在计算机程序中通常作为一个整体考虑。一个数据元素由若干个数据项组成。数据项是数据结构中讨论的最小单位。有两类数据元素:若数据元素可再分,则每一个独立的处理单元就是数据项,数据元素是数据项的集合;若数据元素不可再分,则数据元素和数据项是同一概念,如:整数"5",字符 "N" 等。例如描述一个学生的信息的数据元素可由下列6个数据项组成。其中的出生日期又可以由三个数据项:"年"、"月"和"日"组成,则称"出生日期"为组合项,而其它不可分割的数据项为原子项。

             关键字指的是能识别一个或多个数据元素的数据项。若能起唯一识别作用,则称之为 "主" 关键字,否则称之为 "次" 关键字。

             数据对象是性质相同的数据元素的集合,是数据的一个子集。数据对象可以是有限的,也可以是无限的。

             数据处理是指对数据进行查找、插入、删除、合并、排序、统计以及简单计算等的操作过程。在早期,计算机主要用于科学和工程计算,进入八十年代以后,计算机主要用于数据处理。据有关统计资料表明,计算机用于数据处理的时间比例达到80%以上,随着时间的推移和计算机应用的进一步普及,计算机用于数据处理的时间比例必将进一步增大。

     

    结构分类

             数据结构是指同一数据元素类中各数据元素之间存在的关系。数据结构分别为逻辑结构、存储结构(物理结构)和数据的运算。数据的逻辑结构是从具体问题抽象出来的数学模型,是描述数据元素及其关系的数学特性的,有时就把逻辑结构简称为数据结构。逻辑结构是在计算机存储中的映像,形式地定义为(K,R)(或(D,S)),其中,K是数据元素的有限集,R是K上的关系的有限集。

             根据数据元素间关系的不同特性,通常有下列四类基本的结构: ⑴集合结构。该结构的数据元素间的关系是“属于同一个集合”。 ⑵线性结构。该结构的数据元素之间存在着一对一的关系。 ⑶树型结构。该结构的数据元素之间存在着一对多的关系。 ⑷图形结构。该结构的数据元素之间存在着多对多的关系,也称网状结构。 从上面所介绍的数据结构的概念中可以知道,一个数据结构有两个要素。一个是数据元素的集合,另一个是关系的集合。在形式上,数据结构通常可以采用一个二元组来表示。

             数据结构的形式定义为:数据结构是一个二元组 :Data_Structure=(D,R),其中,D是数据元素的有限集,R是D上关系的有限集。线性结构的特点是数据元素之间是一种线性关系,数据元素“一个接一个的排列”。在一个线性表中数据元素的类型是相同的,或者说线性表是由同一类型的数据元素构成的线性结构。在实际问题中线性表的例子是很多的,如学生情况信息表是一个线性表:表中数据元素的类型为学生类型; 一个字符串也是一个线性表:表中数据元素的类型为字符型,等等。

             线性表是最简单、最基本、也是最常用的一种线性结构。 线性表是具有相同数据类型的n(n>=0)个数据元素的有限序列,通常记为: (a1,a2,… ai-1,ai,ai+1,…an) ,其中n为表长, n=0 时称为空表。 它有两种存储方法:顺序存储和链式存储,它的主要基本操作是插入、删除和检索等。

             数据结构在计算机中的表示(映像)称为数据的物理(存储)结构。它包括数据元素的表示和关系的表示。数据元素之间的关系有两种不同的表示方法:顺序映象和非顺序映象,并由此得到两种不同的存储结构:顺序存储结构和链式存储结构。

             顺序存储方法:它是把逻辑上相邻的结点存储在物理位置相邻的存储单元里,结点间的逻辑关系由存储单元的邻接关系来体现,由此得到的存储表示称为顺序存储结构。顺序存储结构是一种最基本的存储表示方法,通常借助于程序设计语言中的数组来实现。

             链接存储方法:它不要求逻辑上相邻的结点在物理位置上亦相邻,结点间的逻辑关系是由附加的指针字段表示的。由此得到的存储表示称为链式存储结构,链式存储结构通常借助于程序设计语言中的指针类型来实现

             索引存储方法:除建立存储结点信息外,还建立附加的索引表来标识结点的地址。

             散列存储方法:就是根据结点的关键字直接计算出该结点的存储地址。

             数据结构中,逻辑上(逻辑结构:数据元素之间的逻辑关系)可以把数据结构分成线性结构和非线性结构。线性结构的顺序存储结构是一种顺序存取的存储结构,线性表的链式存储结构是一种随机存取的存储结构。线性表若采用链式存储表示时所有结点之间的存储单元地址可连续可不连续。逻辑结构与数据元素本身的形式、内容、相对位置、所含结点个数都无关。

     

    结构算法

             算法的设计取决于数据(逻辑)结构,而算法的实现依赖于采用的存储结构。数据的存储结构实质上是它的逻辑结构在计算机存储器中的实现,为了全面的反映一个数据的逻辑结构,它在存储器中的映象包括两方面内容,即数据元素之间的信息和数据元素之间的关系。不同数据结构有其相应的若干运算。数据的运算是在数据的逻辑结构上定义的操作算法,如检索、插入、删除、更新和排序等。

             数据的运算是数据结构的一个重要方面,讨论任一种数据结构时都离不开对该结构上的数据运算及其实现算法的讨论。
    数据结构不同于数据类型,也不同于数据对象,它不仅要描述数据类型的数据对象,而且要描述数据对象各元素之间的相互关系。

             数据类型是一个值的集合和定义在这个值集上的一组操作的总称。数据类型可分为两类:原子类型、结构类型。一方面,在程序设计语言中,每一个数据都属于某种数据类型。类型明显或隐含地规定了数据的取值范围、存储方式以及允许进行的运算。可以认为,数据类型是在程序设计中已经实现了的数据结构。另一方面,在程序设计过程中,当需要引入某种新的数据结构时,总是借助编程语言所提供的数据类型来描述数据的存储结构。

             计算机中表示数据的最小单位是二进制数的一位,叫做位。我们用一个由若干位组合起来形成的一个位串表示一个数据元素,通常称这个位串为元素或结点。当数据元素由若干数据项组成时,位串中对应于各个数据项的子位串称为数据域。元素或结点可看成是数据元素在计算机中的映象。

             一个软件系统框架应建立在数据之上,而不是建立在操作之上。一个含抽象数据类型的软件模块应包含定义、表示、实现三个部分。
    对每一个数据结构而言,必定存在与它密切相关的一组操作。若操作的种类和数目不同,即使逻辑结构相同,数据结构能起的作用也不同。

             不同的数据结构其操作集不同,但下列操作必不可缺:
             1,结构的生成;
             2.结构的销毁;
             3,在结构中查找满足规定条件的数据元素;
             4,在结构中插入新的数据元素;
             5,删除结构中已经存在的数据元素;
             6,遍历。

             抽象数据类型:一个数学模型以及定义在该模型上的一组操作。抽象数据类型实际上就是对该数据结构的定义。因为它定义了一个数据的逻辑结构以及在此结构上的一组算法。抽象数据类型可用以下三元组表示:(D,S,P)。D是数据对象,S是D上的关系集,P是对D的基本操作集。ADT的定义为:

             ADT 抽象数据类型名:{数据对象:(数据元素集合),数据关系:(数据关系二元组结合),基本操作:(操作函数的罗列)}; ADT抽象数据类型名;抽象数据类型有两个重要特性:

             数据抽象

             用ADT描述程序处理的实体时,强调的是其本质的特征、其所能完成的功能以及它和外部用户的接口(即外界使用它的方法)。

             数据封装

             将实体的外部特性和其内部实现细节分离,并且对外部用户隐藏其内部实现细节。

             数据(Data)是信息的载体,它能够被计算机识别、存储和加工处理。它是计算机程序加工的原料,应用程序处理各种各样的数据。计算机科学中,所谓数据就是计算机加工处理的对象,它可以是数值数据,也可以是非数值数据。数值数据是一些整数、实数或复数,主要用于工程计算、科学计算和商务处理等;非数值数据包括字符、文字、图形、图像、语音等。数据元素(Data Element)是数据的基本单位。在不同的条件下,数据元素又可称为元素、结点、顶点、记录等。例如,学生信息检索系统中学生信息表中的一个记录等,都被称为一个数据元素。
    有时,一个数据元素可由若干个数据项(Data Item)组成,例如,学籍管理系统中学生信息表的每一个数据元素就是一个学生记录。它包括学生的学号、姓名、性别、籍贯、出生年月、成绩等数据项。这些数据项可以分为两种:一种叫做初等项,如学生的性别、籍贯等,这些数据项是在数据处理时不能再分割的最小单位;另一种叫做组合项,如学生的成绩,它可以再划分为数学、物理、化学等更小的项。通常,在解决实际应用问题时是把每个学生记录当作一个基本单位进行访问和处理的。

             数据对象(Data Object)或数据元素类(Data Element Class)是具有相同性质的数据元素的集合。在某个具体问题中,数据元素都具有相同的性质(元素值不一定相等),属于同一数据对象(数据元素类),数据元素是数据元素类的一个实例。例如,在交通咨询系统的交通网中,所有的顶点是一个数据元素类,顶点A和顶点B各自代表一个城市,是该数据元素类中的两个实例,其数据元素的值分别为A和B。 数据结构(Data Structure)是指互相之间存在着一种或多种关系的数据元素的集合。在任何问题中,数据元素之间都不会是孤立的,在它们之间都存在着这样或那样的关系,这种数据元素之间的关系称为结构。

     

    常用结构

    数组
             在程序设计中,为了处理方便, 把具有相同类型的若干变量按有序的形式组织起来。这些按序排列的同类数据元素的集合称为数组。在C语言中, 数组属于构造数据类型。一个数组可以分解为多个数组元素,这些数组元素可以是基本数据类型或是构造类型。因此按数组元素的类型不同,数组又可分为数值数组、字符数组、指针数组、结构数组等各种类别。


             是只能在某一端插入和删除的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。

    队列
             一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列是按照“先进先出”或“后进后出”的原则组织数据的。队列中没有元素时,称为空队列。

    链表
             是一种物理存储单元上非连续、非顺序的存储结构,它既可以表示线性结构,也可以用于表示非线性结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。


             是包含n(n>0)个结点的有穷集合K,且在K中定义了一个关系N,N满足 以下条件:
             (1)有且仅有一个结点 K0,他对于关系N来说没有前驱,称K0为树的根结点。简称为根(root)。  
             (2)除K0外,K中的每个结点,对于关系N来说有且仅有一个前驱。
             (3)K中各结点,对关系N来说可以有m个后继(m>=0)。


             图是由结点的有穷集合V和边的集合E组成。其中,为了与树形结构加以区别,在图结构中常常将结点称为顶点,边是顶点的有序偶对,若两个顶点之间存在一条边,就表示这两个顶点具有相邻关系。


             在计算机科学中,堆是一种特殊的树形数据结构,每个结点都有一个值。通常我们所说的堆的数据结构,是指二叉堆。堆的特点是根结点的值最小(或最大),且根结点的两个子树也是一个堆。

    散列表
             若结构中存在关键字和K相等的记录,则必定在f(K)的存储位置上。由此,不需比较便可直接取得所查记录。称这个对应关系f为散列函数(Hash function),按这个思想建立的表为散列表。

     

    简而言之,数据结构说的是:计算机组织数据和存储数据的方式。

    展开全文
  • 昆明理工大学信息工程与自动化学院学生实验报告 20122013 学年 第 一 学期 课程名称Java 程序设计 ...指导教师 尚振宏 教 师 评 教师签名 语 年 月 一实验目的及内容 目的掌握和巩固Java 结构化程序设计的概念方法 内容
  • 数据结构基础概念

    万次阅读 多人点赞 2017-11-14 13:44:24
    数据结构一些概念 数据结构就是研究数据的逻辑结构和物理结构以及它们之间相互关系,并对这种结构定义相应的运算,而且确保经过这些运算后所得到的新结构仍然是原来的结构类型。数据:所有能被输入到计算机中,且能...

    数据结构

    一些概念

    数据结构就是研究数据的逻辑结构物理结构以及它们之间相互关系,并对这种结构定义相应的运算,而且确保经过这些运算后所得到的新结构仍然是原来的结构类型。

    1. 数据:所有能被输入到计算机中,且能被计算机处理的符号的集合。是计算机操作的对象的总称。
    2. 数据元素:数据(集合)中的一个“个体”,数据及结构中讨论的基本单位
    3. 数据项:数据的不可分割的最小单位。一个数据元素可由若干个数据项组成。
    4. 数据类型:在一种程序设计语言中,变量所具有的数据种类。整型、浮点型、字符型等等

    5. 逻辑结构:数据之间的相互关系。

      • 集合 结构中的数据元素除了同属于一种类型外,别无其它关系。
      • 线性结构 数据元素之间一对一的关系
      • 树形结构 数据元素之间一对多的关系
      • 图状结构或网状结构 结构中的数据元素之间存在多对多的关系
    6. 物理结构/存储结构:数据在计算机中的表示。物理结构是描述数据具体在内存中的存储(如:顺序结构、链式结构、索引结构、哈希结构)等
    7. 在数据结构中,从逻辑上可以将其分为线性结构和非线性结构
    8. 数据结构的基本操作的设置的最重要的准则是,实现应用程序与存储结构的独立。实现应用程序是“逻辑结构”,存储的是“物理结构”。逻辑结构主要是对该结构操作的设定,物理结构是描述数据具体在内存中的存储(如:顺序结构、链式结构、索引结构、希哈结构)等。
    9. 顺序存储结构中,线性表的逻辑顺序和物理顺序总是一致的。但在链式存储结构中,线性表的逻辑顺序和物理顺序一般是不同的。

    10. 算法五个特性: 有穷性、确定性、可行性、输入、输出

    11. 算法设计要求:正确性、可读性、健壮性、高效率与低存储量需求。(好的算法)
    12. 算法的描述有伪程序、流程图、N-S结构图等。E-R图是实体联系模型,不是程序的描述方式。
    13. 设计算法在执行时间时需要考虑:算法选用的规模、问题的规模
    14. 时间复杂度:算法的执行时间与原操作执行次数之和成正比。时间复杂度有小到大:O(1)、O(logn)、O(n)、O(nlogn)、O(n2)、O(n3)。幂次时间复杂度有小到大O(2n)、O(n!)、O(nn)
    15. 空间复杂度:若输入数据所占空间只取决于问题本身,和算法无关,则只需要分析除输入和程序之外的辅助变量所占额外空间

    线性表

    线性表是一种典型的线性结构。头结点无前驱有一个后继,尾节点无后继有一个前驱。链表只能顺序查找,定位一个元素的时间为O(N),删除一个元素的时间为O(1)

    1. 线性表的顺序存储结构:把线性表的结点按逻辑顺序依次存放在一组地址连续的存储单元里。用这种方法存储的线性表简称顺序表。是一种随机存取的存储结构。顺序存储指内存地址是一块的,随机存取指访问时可以按下标随机访问,存储和存取是不一样的。如果是存储,则是指按顺序的,如果是存取,则是可以随机的,可以利用元素下标进行。数组比线性表速度更快的是:原地逆序、返回中间节点、选择随机节点。
      • 便于线性表的构造和任意元素的访问
      • 插入:插入新结点,之后结点后移。平均时间复杂度:O(n)
      • 删除:删除节点,之后结点前移。平均时间复杂度:O(n)
    2. 线性链表:用一组任意的存储单元来依次存放线性表的结点,这组存储单元即可以是连续的,也可以是不连续的,甚至是零散分布在内存中的任意位置上的。因此,链表中结点的逻辑次序和物理次序不一定相同。为了能正确表示结点间的逻辑关系,在存储每个结点值的同时,还必须存储指示其后继结点的地址。data域是数据域,用来存放结点的值。next是指针域(亦称链域),用来存放结点的直接后继的地址(或位置)。不需要事先估计存储空间大小。
      • 单链表中每个结点的存储地址是存放在其前趋结点next域中,而开始结点无前趋,故应设头指针head指向开始结点。同时,由于最后一个结点无后继,故结点的指针域为空,即NULL。头插法建表(逆序)、尾插法建表(顺序)。增加头结点的目的是算法实现上的方便,但增大了内存开销。
        • 查找:只能从链表的头指针出发,顺链域next逐个结点往下搜索,直到搜索到第i个结点为止。因此,链表不是随机存取结构
        • 插入:先找到表的第i-1的存储位置,然后插入。新结点先连后继,再连前驱。
        • 删除:首先找到ai-1的存储位置p。然后令p–>next指向ai的直接后继结点,即把ai从链上摘下。最后释放结点ai的空间.r=p->next;p->next=r->next;delete r。
        • 判断一个单向链表中是否存在环的最佳方法是快慢指针。
      • 静态链表:用一维数组来实现线性链表,这种用一维数组表示的线性链表,称为静态链表。静态:体现在表的容量是一定的。(数组的大小);链表:插入与删除同前面所述的动态链表方法相同。静态链表中指针表示的是下一元素在数组中的位置。
      • 静态链表是用数组实现的,是顺序的存储结构,在物理地址上是连续的,而且需要预先分配大小。动态链表是用申请内存函数(C是malloc,C++是new)动态申请内存的,所以在链表的长度上没有限制。动态链表因为是动态申请内存的,所以每个节点的物理地址不连续,要通过指针来顺序访问。静态链表在插入、删除时也是通过修改指针域来实现的,与动态链表没有什么分别
      • 循环链表:是一种头尾相接的链表。其特点是无须增加存储量,仅对表的链接方式稍作改变,即可使得表处理更加方便灵活。
        • 在单链表中,将终端结点的指针域NULL改为指向表头结点的或开始结点,就得到了单链形式的循环链表,并简单称为单循环链表。由于循环链表中没有NULL指针,故涉及遍历操作时,其终止条件就不再像非循环链表那样判断p或p—>next是否为空,而是判断它们是否等于某一指定指针,如头指针或尾指针等。
      • 双向链表:在单链表的每个结点里再增加一个指向其直接前趋的指针域prior。这样就形成的链表中有两个方向不同的链。双链表一般由头指针唯一确定的,将头结点和尾结点链接起来构成循环链表,并称之为双向链表。设指针p指向某一结点,则双向链表结构的对称性可用下式描述:p—>prior—>next=p=p—>next—>prior。从两个方向搜索双链表,比从一个方向搜索双链表的方差要小。
        • 插入:先搞定插入节点的前驱和后继,再搞定后结点的前驱,最后搞定前结点的后继。
        • 在有序双向链表中定位删除一个元素的平均时间复杂度为O(n)
        • 可以直接删除当前指针所指向的节点。而不需要像单向链表中,删除一个元素必须找到其前驱。因此在插入数据时,单向链表和双向链表操作复杂度相同,而删除数据时,双向链表的性能优于单向链表

    栈和队列

    栈(Stack)是限制在表的一端进行插入和删除运算的线性表,通常称插入、删除的这一端为栈顶(Top),另一端为栈底(Bottom)。先进后出。top= -1时为空栈,top=0只能说明栈中只有一个元素,并且元素进栈时top应该自增

    1. 顺序存储栈:顺序存储结构
    2. 链栈:链式存储结构。插入和删除操作仅限制在链头位置上进行。栈顶指针就是链表的头指针。通常不会出现栈满的情况。 不需要判断栈满但需要判断栈空。
    3. 两个栈共用静态存储空间,对头使用也存在空间溢出问题。栈1的底在v[1],栈2的底在V[m],则栈满的条件是top[1]+1=top[2]。
    4. 基本操作:删除栈顶元素、判断栈是否为空以及将栈置为空栈等
    5. 对于n各元素的入栈问题,可能的出栈顺序有C(2n,n)/(n+1)个。
    6. 堆栈溢出一般是循环的递归调用、大数据结构的局部变量导致的

    应用,代码

    1. 进制转换
    2. 括号匹配的检验
    3. 行编辑程序
    4. 迷宫求解:若当前位置“可通”,则纳入路径,继续前进;若当前位置“不可通”,则后退,换方向继续探索;若四周“均无通路”,则将当前位置从路径中删除出去。
    5. 表达式求解:前缀、中缀、后缀。
      • 操作数之间的相对次序不变;
      • 运算符的相对次序不同;
      • 中缀式丢失了括弧信息,致使运算的次序不确定
      • 前缀式的运算规则为:连续出现的两个操作数和在它们之前且紧靠它们的运算符构成一个最小表达式
      • 后缀式的运算规则为:运算符在式中出现的顺序恰为表达式的运算顺序;每个运算符和在它之前出现且紧靠它的两个操作数构成一个最小表达式。
    6. 实现递归:多个函数嵌套调用的规则是:后调用先返回。
    7. 浏览器历史纪录,Android中的最近任务,Activity的启动模式,CPU中栈的实现,Word自动保存,解析计算式,解析xml/json。解析XML时,需要校验节点是否闭合,节点闭合的话,有头尾符号相对应,遇到头符号将其放入栈中,遇到尾符号时,弹出栈的内容,看是否有与之对应的头符号,栈的特性刚好符合符号匹配的就近原则。

    不是所有的递归程序都需要栈来保护现场,比方说求阶乘的,是单向递归,直接用循环去替代从1乘到n就是结果了,另外一些需要栈保存的也可以用队列等来替代。不是所有的递归转化为非递归都要用到栈。转化为非递归主要有两种方法:对于尾递归或单向递归,可以用循环结构算法代替

    队列

    队列(Queue)也是一种运算受限的线性表。它只允许在表的一端进行插入,而在另一端进行删除。允许删除的一端称为队头(front),允许插入的一端称为队尾(rear)。先进先出。

    1. 顺序队列:顺序存储结构。当头尾指针相等时队列为空。在非空队列里,头指针始终指向队头前一个位置,而尾指针始终指向队尾元素的实际位置
    2. 循环队列。在循环队列中进行出队、入队操作时,头尾指针仍要加1,朝前移动。只不过当头尾指针指向向量上界(MaxSize-1)时,其加1操作的结果是指向向量的下界0。除非向量空间真的被队列元素全部占用,否则不会上溢。因此,除一些简单的应用外,真正实用的顺序队列是循环队列。故队空和队满时头尾指针均相等。因此,我们无法通过front=rear来判断队列“空”还是“满”
    3. 链队列:链式存储结构。限制仅在表头删除和表尾插入的单链表。显然仅有单链表的头指针不便于在表尾做插入操作,为此再增加一个尾指针,指向链表的最后一个结点。
    4. 设尾指针的循环链表表示队列,则入队和出队算法的时间复杂度均为O(1)。用循环链表表示队列,必定有链表的头结点,入队操作在链表尾插入,直接插入在尾指针指向的节点后面,时间复杂度是常数级的;出队操作在链表表头进行,也就是删除表头指向的节点,时间复杂度也是常数级的。

    5. 队空条件:rear==front,但是一般需要引入新的标记来说明栈满还是栈空,比如每个位置布尔值

    6. 队满条件:(rear+1) % QueueSize==front,其中QueueSize为循环队列的最大长度
    7. 计算队列长度:(rear-front+QueueSize)% QueueSize
    8. 入队:(rear+1)% QueueSize
    9. 出队:(front+1)% QueueSize
    10. 假设以数组A[N]为容量存放循环队列的元素,其头指针是front,当前队列有X个元素,则队列的尾指针值为(front+X mod N)

    串(String)是零个或多个字符组成的有限序列。长度为零的串称为空串(Empty String),它不包含任何字符。通常将仅由一个或多个空格组成的串称为空白串(Blank String) 注意:空串和空白串的不同,例如“ ”和“”分别表示长度为1的空白串和长度为0的空串。

    串的表示和实现:

    1. 定长顺序存储表示。静态存储分配的顺序表。
    2. 堆分配存储表示。存储空间是在程序执行过程中动态分配而得。所以也称为动态存储分配的顺序表
    3. 串的链式存储结构。

    串匹配:将主串称为目标串,子串称之为模式串。蛮力法匹配。KMP算法匹配。Boyer-Moore算法匹配。

    数组和广义表

    数组和广义表可看成是一种特殊的线性表,其特殊在于: 表中的元素本身也是一种线性表。内存连续。根据下标在O(1)时间读/写任何元素。

    二维数组,多维数组,广义表、树、图都属于非线性结构

    数组

    数组的顺序存储:行优先顺序;列优先顺序。数组中的任一元素可以在相同的时间内存取,即顺序存储的数组是一个随机存取结构。

    关联数组(Associative Array),又称映射(Map)、字典( Dictionary)是一个抽象的数据结构,它包含着类似于(键,值)的有序对。 不是线性表。

    矩阵的压缩:

    1. 对称矩阵、三角矩阵:直接存储矩阵的上三角或者下三角元素。注意区分i>=j和i

    广义表

    广义表(Lists,又称列表)是线性表的推广。广义表是n(n≥0)个元素a1,a2,a3,…,an的有限序列,其中ai或者是原子项,或者是一个广义表。若广义表LS(n>=1)非空,则a1是LS的表头,其余元素组成的表(a2,…an)称为LS的表尾。广义表的元素可以是广义表,也可以是原子,广义表的元素也可以为空。表尾是指除去表头后剩下的元素组成的表,表头可以为表或单元素值。所以表尾不可以是单个元素值。

    例子:

    1. A=()——A是一个空表,其长度为零。
    2. B=(e)——表B只有一个原子e,B的长度为1。
    3. C=(a,(b,c,d))——表C的长度为2,两个元素分别为原子a和子表(b,c,d)。
    4. D=(A,B,C)——表D的长度为3,三个元素都是广义 表。显然,将子表的值代入后,则有D=(( ),(e),(a,(b,c,d)))。
    5. E=(a,E)——这是一个递归的表,它的长度为2,E相当于一个无限的广义表E=(a,(a,(a,(a,…)))).

    三个结论:

    1. 广义表的元素可以是子表,而子表的元素还可以是子表。由此,广义表是一个多层次的结构,可以用图形象地表示
    2. 广义表可为其它表所共享。例如在上述例4中,广义表A,B,C为D的子表,则在D中可以不必列出子表的值,而是通过子表的名称来引用。
    3. 广义表的递归性

    考点:

    1. 广义表是0个或多个单因素或子表组成的有限序列,广义表可以是自身的子表,广义表的长度n>=0,所以可以为空表。广义表的同级元素(直属于同一个表中的各元素)具有线性关系
    2. 广义表的表头为空,并不代表该广义表为空表。广义表()和(())不同。前者是长度为0的空表,对其不能做求表头和表尾的运算;而后者是长度为l的非空表(只不过该表中惟一的一个元素是空表),对其可进行分解,得到的表头和表尾均是空表()
    3. 已知广义表LS=((a,b,c),(d,e,f)),运用head和tail函数取出LS中原子e的运算是head(tail(head(tail(LS)))。根据表头、表尾的定义可知:任何一个非空广义表的表头是表中第一个元素,它可以是原子,也可以是子表,而其表尾必定是子表。也就是说,广义表的head操作,取出的元素是什么,那么结果就是什么。但是tail操作取出的元素外必须加一个表——“()“。tail(LS)=((d,e,f));head(tail(LS))=(d,e,f);tail(head(tail(LS)))=(e,f);head(tail(head(tail(LS))))=e。
    4. 二维以上的数组其实是一种特殊的广义表
    5. 在(非空)广义表中:1、表头head可以是原子或者一个表 2、表尾tail一定是一个表 3.广义表难以用顺序存储结构 4.广义表可以是一个多层次的结构

    树和二叉树

    一种非线性结构。树是递归结构,在树的定义中又用到了树的概念。

    基本术语:

    1. 树结点:包含一个数据元素及若干指向子树的分支;
    2. 孩子结点:结点的子树的根称为该结点的孩子;
    3. 双亲结点:B结点是A结点的孩子,则A结点是B结点的双亲;
    4. 兄弟结点:同一双亲的孩子结点;
    5. 堂兄结点:同一层上结点;
    6. 结点层次:根结点的层定义为1;根的孩子为第二层结点,依此类推;
    7. 树的高(深)度:树中最大的结点层
    8. 结点的度:结点子树的个数
    9. 树的度: 树中最大的结点度。
    10. 叶子结点:也叫终端结点,是度为0的结点;
    11. 分枝结点:度不为0的结点(非终端结点);
    12. 森林:互不相交的树集合;
    13. 有序树:子树有序的树,如:家族树;
    14. 无序树:不考虑子树的顺序;

    二叉树

    二叉树可以为空。二叉树结点的子树要区分左子树和右子树,即使只有一棵子树也要进行区分,说明它是左子树,还是右子树。这是二叉树与树的最主要的差别。注意区分:二叉树、二叉查找树/二叉排序树/二叉搜索树二叉平衡(查找)树

    二叉平衡树肯定是一颗二叉排序树。堆不是一颗二叉平衡树。

    二叉树与树是不同的,二叉树不等价于分支树最多为二的有序树。当一个结点只包含一个子节点时,对于有序树并无左右孩子之分,而对于二叉树来说依然有左右孩子之分,所以二叉树与树是两种不同的结构。

    性质:

    1. 在二叉树的第 i 层上至多有2i-1个结点。
    2. 深度为 k 的二叉树上至多含 2k-1 个结点(k≥1)
    3. 对任何一棵二叉树,若它含有n0个叶子结点、n2个度为 2 的结点,则必存在关系式:n0= n2+1。
    4. 具有 n 个结点的完全二叉树的深度为⎣log2 n⎦+1 。
    5. n个结点的二叉树中,完全二叉树具有最小的路径长度。
    6. 如果对一棵有n个结点的完全二叉树的结点按层序编号,则对任一结点i(1<=i<=n),有:
      • 如果i=1,则结点i无双亲,是二叉树的根;如果i>1,则其双亲的编号是 i/2(整除)。
      • 如果2i>n,无左孩子;否则,其左孩子是结点2i。
      • 如果2i+1>n,则结点i无右孩子;否则,其右孩子是结点2i+1。

    二叉树的存储结构

    1. 顺序存储结构:仅仅适用于满或完全二叉树,结点之间的层次关系由性质5确定。
    2. 二叉链表法:每个节点存储左子树和右子树。三叉链表:左子树、右子树、父节点,总的指针是n+2
    3. 在有n个结点的二叉链表中,值为非空的链域的个数为n-1。在有N个结点的二叉链表中必定有2N个链域。除根结点外,其余N-1个结点都有一个父结点。所以,一共有N-1个非空链域,其余2N-(N-1)=N+1个为空链域。
    4. 二叉链存储法也叫孩子兄弟法,左指针指向左孩子,右指针指向右兄弟。而中序遍历的顺序是左孩子,根,右孩子。这种遍历顺序与存储结构不同,因此需要堆栈保存中间结果。而中序遍历检索二叉树时,由于其存储结构跟遍历顺序相符,因此不需要用堆栈。

    遍历二叉树和线索二叉树

    遍历二叉树:使得每一个结点均被访问一次,而且仅被访问一次。非递归的遍历实现要利用栈。

    • 先序遍历DLR:根节点->左子树->右子树
    • 中序遍历LDR:左子树->根节点->右子树。必须要有中序遍历才能得到一棵二叉树的正确顺序
    • 后续遍历LRD:左子树->右子树->根节点。需要栈的支持。
    • 层次遍历:用一维数组存储二叉树时,总是以层次遍历的顺序存储结点。层次遍历应该借助队列。

    线索二叉树:对二叉树所有结点做某种处理可在遍历过程中实现;检索(查找)二叉树某个结点,可通过遍历实现;如果能将二叉树线索化,就可以简化遍历算法,提高遍历速度,目的是加快查找结点的前驱或后继的速度。

    如何线索化?以中序遍历为例,若能将中序序列中每个结点前趋、后继信息保存起来,以后再遍历二叉树时就可以根据所保存的结点前趋、后继信息对二叉树进行遍历。对于二叉树的线索化,实质上就是遍历一次二叉树,只是在遍历的过程中,检查当前结点左,右指针域是否为空,若为空,将它们改为指向前驱结点或后继结点的线索。前驱就是在这一点之前走过的点,不是下一将要去往的点

    加上结点前趋后继信息(结索)的二叉树称为线索二叉树。n个结点的线索二叉树上每个结点有2个指针域(指向左孩子和右孩子),总共有2n个指针域;一个n个结点的树有n-1条边,那么空指针域= 2n - (n-1) = n + 1,即线索数为n+1。指针域tag为0,存放孩子指针,为1,存放前驱/后继节点指针。

    线索树下结点x的前驱与后继查找:设结点x相应的左(右)标志是线索标志,则lchild(rchild)就是前驱(后继),否则:

    • LDR–前驱:左子树中最靠右边的结点;后继:右子树中最靠左边的结点
    • LRD–前驱:右子树的根,若无右子树,为左子树跟。后继:x是根,后继是空;x是双亲的右孩子、x是双亲的左孩子,但双亲无右孩子,双亲是后继;x是双亲的左孩子,双亲有右孩子,双亲右子树中最左的叶子是后继
    • DLR–对称于LRD线索树—将LRD中所有左右互换,前驱与后继互换,得到DLR的方法。
    • 为简化线索链表的遍历算法,仿照线性链表,为线索链表加上一头结点,约定:
      • 头结点的lchild域:存放线索链表的根结点指针;
      • 头结点的rchild域: 中序序列最后一个结点的指针;
      • 中序序列第一结点lchild域指向头结点;
      • 中序序列最后一个结点的rchild域指向头结点;

    中序遍历的线索二叉树以及线索二叉树链表示意图
    xiansuobinarytree

    一棵左右子树均不空的二叉树在前序线索化后,其中空的链域的个数是1。前序和后续线索化后空链域个数都是1,中序是2。二叉树在线索化后,仍不能有效求解的问题是前序求前序先驱,后序求后序后继。

    中序遍历的顺序为:左、根、右,所以对于每一非空的线索,左子树结点的后继为根结点,右子树结点的前驱为根结点,再递归的执行上面的过程,可得非空线索均指向其祖先结点。在中序线索二叉树中,每一非空的线索均指向其祖先结点

    在二叉树上加上结点前趋、后继线索后,可利用线索对二叉树进行遍历,此时,不需栈,也不需递归。基本步骤:

    1. p=T->lchild; p指向线索链表的根结点;
    2. 若线索链表非空,循环:
      • 循环,顺着p左孩子指针找到最左下结点;访问之;
      • 若p所指结点的右孩子域为线索,p的右孩子结点即为后继结点循环: p=p->rchild; 并访问p所指结点;(在此循环中,顺着后继线索访问二叉树中的结点)
      • 一旦线索“中断”,p所指结点的右孩子域为右孩子指针,p=p->rchild,使 p指向右孩子结点;

    树和森林

    树的存储结构:

    1. 双亲表示法
    2. 孩子表示法
    3. 利用图表示树
    4. 孩子兄弟表示法(二叉树表示法):链表中每个结点的两指针域分别指向其第一个孩子结点和下一个兄弟结点

    将树转化成二叉树:右子树一定为空

    1. 加线:在兄弟之间加一连线
    2. 抹线:对每个结点,除了其左孩子外,去除其与其余孩子之间的关系
    3. 旋转:以树的根结点为轴心,将整树顺时针转45°

    森林转换成二叉树:

    1. 将各棵树分别转换成二叉树
    2. 将每棵树的根结点用线相连
    3. 以第一棵树根结点为二叉树的根

    树与转换后的二叉树的关系:转换后的二叉树的先序对应树的先序遍历;转换后的二叉树的中序对应树的后序遍历

    哈弗曼树/霍夫曼树

    一些概念

    1. 路径:从一个祖先结点到子孙结点之间的分支构成这两个结点间的路径;
    2. 路径长度:路径上的分支数目称为路径长度;
    3. 树的路径长度:从根到每个结点的路径长度之和。
    4. 结点的权:根据应用的需要可以给树的结点赋权值;
    5. 结点的带权路径长度:从根到该结点的路径长度与该结点权的乘积;
    6. 树的带权路径长度=树中所有叶子结点的带权路径之和;通常记作 WPL=∑wi×li
    7. 哈夫曼树:假设有n个权值(w1, w2, … , wn),构造有n个叶子结点的二叉树,每个叶子结点有一个 wi作为它的权值。则带权路径长度最小的二叉树称为哈夫曼树。最优二叉树。

    前缀码的定义:在一个字符集中,任何一个字符的编码都不是另一个字符编码的前缀。霍夫曼编码就是前缀码,可用于快速判断霍夫曼编码是否正确。霍夫曼树是满二叉树,若有n个节点,则共有(n+1)/2个码子

    给定n个权值作为n的叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为霍夫曼树(Huffman Tree)。霍夫曼树是带权路径长度最短的树,权值较大的结点离根较近。

    假设哈夫曼树是二叉的话,则度为0的结点个数为N,度为2的结点个数为N-1,则结点总数为2N-1。哈夫曼树的结点个数必为奇数。

    哈夫曼树不一定是完全二叉树,但一定是最优二叉树。

    若度为m的哈夫曼树中,其叶结点个数为n,则非叶结点的个数为[(n-1)/(m-1)]。边的数目等于度。

    图遍历与回溯

    图搜索->形成搜索树

    1. 穷举法。
    2. 贪心法。多步决策,每步选择使得构成一个问题的可能解,同时满足目标函数。
    3. 回溯法。根据题意,选取度量标准,然后将可能的选择方法按度量标准所要求顺序排好,每次处理一个量,得到该意义下的最优解的分解处理。

    无向图

    1. 回路或环:第一个顶点和最后一个顶点相同的路径。
    2. 简单回路或简单环:除第一个顶点和最后一个顶点之外,其余顶点不重复出现的回路
    3. 连通:顶点v至v’ 之间有路径存在
    4. 连通图:无向图图 G 的任意两点之间都是连通的,则称G是连通图。
    5. 连通分量:极大连通子图,子图中包含的顶点个数极大
    6. 所有顶点度的和必须为偶数

    有向图:

    1. 回路或环:第一个顶点和最后一个顶点相同的路径。
    2. 简单回路或简单环:除第一个顶点和最后一个顶点之外,其余顶点不重复出现的回路。
    3. 连通:顶点v至v’之间有路径存在
    4. 强连通图:有向图G的任意两点之间都是连通的,则称G是强连通图。各个顶点间均可达。
    5. 强连通分量:极大连通子图
    6. 有向图顶点的度是顶点的入度与出度之和。邻接矩阵中第V行中的1的个数是V的出度

    7. 生成树:极小连通子图。包含图的所有n个结点,但只含图的n-1条边。在生成树中添加一条边之后,必定会形成回路或环。

    8. 完全图:有 n(n-1)/2 条边的无向图。其中n是结点个数。必定是连通图。
    9. 有向完全图:有n(n-1)条边的有向图。其中n是结点个数。每两个顶点之间都有两条方向相反的边连接的图。
    10. 一个无向图 G=(V,E) 是连通的,那么边的数目大于等于顶点的数目减一:|E|>=|V|-1,而反之不成立。如果 G=(V,E) 是有向图,那么它是强连通图的必要条件是边的数目大于等于顶点的数目:|E|>=|V|,而反之不成立。没有回路的无向图是连通的当且仅当它是树,即等价于:|E|=|V|-1。

    图的存储形式

    1. 邻接矩阵和加权邻接矩阵
      • 无权有向图:出度: i行之和;入度: j列之和。
      • 无权无向图:i结点的度: i行或i列之和。
      • 加权邻接矩阵:相连为w,不相连为∞
    2. 邻接表
      • 用顶点数组表、边(弧)表表示该有向图或无向图
      • 顶点数组表:用数组存放所有的顶点。数组大小为图顶点数n
      • 边表(边结点表):每条边用一个结点进行表示。同一个结点的所有的边形成它的边结点单链表。
      • n个顶点的无向图的邻接表最多有n(n-1)个边表结点。有n个顶点的无向图最多有n*(n-1)/2条边,此时为完全无向图,而在邻接表中每条边存储两次,所以有n*(n-1)个结点

    图的遍历

    深度优先搜索利用栈,广度优先搜索利用队列

    求一条从顶点i到顶点s的简单路径–深搜。求两个顶点之间的一条长度最短的路径–广搜。当各边上的权值均相等时,BFS算法可用来解决单源最短路径问题。

    生成树和最小生成树

    每次遍历一个连通图将图的边分成遍历所经过的边和没有经过的边两部分,将遍历经过的边同图的顶点构成一个子图,该子图称为生成树。因此有DFS生成树和BFS生成树。

    生成树是连通图的极小子图,有n个顶点的连通图的生成树必定有n-1条边,在生成树中任意增加一条边,必定产生回路。若砍去它的一条边,就会把生成树变成非连通子图

    最小生成树:生成树中边的权值(代价)之和最小的树。最小生成树问题是构造连通网的最小代价生成树。

    Kruskal算法:令最小生成树集合T初始状态为空,在有n个顶点的图中选取代价最小的边并从图中删去。若该边加到T中有回路则丢弃,否则留在T中;依此类推,直至T中有n-1条边为止。

    Prim算法、Kruskal算法和Dijkstra算法均属于贪心算法。

    1. Dijkstra算法解决的是带权重的有向图上单源最短路径问题,该算法要求所有边的权重都为非负值。
    2. Dijkstra算法解决了从某个原点到其余各顶点的最短路径问题,由循环嵌套可知该算法的时间复杂度为O(N*N)。若要求任一顶点到其余所有顶点的最短路径,一个比较简单的方法是对每个顶点当做源点运行一次该算法,等于在原有算法的基础上,再来一次循环,此时整个算法的复杂度就变成了O(N*N*N)。
    3. Bellman-Ford算法解决的是一般情况下的单源最短路径问题,在这里,边的权重可以为负值。该算法返回一个布尔值,以表明是否存在一个从源节点可以到达的权重为负值的环路。如果存在这样一个环路,算法将告诉我们不存在解决方案。如果没有这种环路存在,算法将给出最短路径和它们的权重。

    双连通图和关节点

    若从一个连通图中删去任何一个顶点及其相关联的边,它仍为一个连通图的话,则该连通图被称为重(双)连通图

    若连通图中的某个顶点和其相关联的边被删去之后,该连通图被分割成两个或两个以上的连通分量,则称此顶点为关节点

    没有关节点的连通图为双连通图

    1. 若生成树的根结点,有两个或两个以上的分支,则此顶点(生成树的根)必为关节点;
    2. 对生成树上的任意一个非叶“顶点”,若其某棵子树中的所有“顶点”没有和其祖先相通的回边,则该“顶点”必为关节点。

    有向无环图及其应用

    拓扑排序。在用邻接表表示图时,对有n个顶点和e条弧的有向图而言时间复杂度为O(n+e)。一个有向图能被拓扑排序的充要条件就是它是一个有向无环图。拓扑序列唯一不能唯一确定有向图。

    AOV网(Activity On Vertex):用顶点表示活动,边表示活动的优先关系的有向图称为AOV网。AOV网中不允许有回路,这意味着某项活动以自己为先决条件。

    拓扑有序序列:把AOV网络中各顶点按照它们相互之间的优先关系排列一个线性序列的过程。若vi是vj前驱,则vi一定在vj之前;对于没有优先关系的点,顺序任意。

    拓扑排序:对AOV网络中顶点构造拓扑有序序列的过程。方法:

    1. 在有向图中选一个没有前驱的顶点且输出之
    2. 从图中删除该顶点和所有以它为尾的弧
    3. 重复上述两步,直至全部顶点均已输出;或者当图中不存在无前驱的顶点为止(此时说明图中有环)

    采用深度优先搜索拓扑排序算法可以判断出一个有向图中是否有环(回路).深度优先搜索只要在其中记录下搜索的节点数n,当n大于图中节点数时退出,并可以得出有回路。若有回路,则拓扑排序访问不到图中所有的节点,所以也可以得出回路。广度优先搜索过程中如果访问到一个已经访问过的节点,可能是多个节点指向这个节点,不一定是存在环。

    算法描述:

    1. 把邻接表中入度为0的顶点依此进栈
    2. 若栈不空,则
      • 栈顶元素vj退栈并输出;
      • 在邻接表中查找vj的直接后继vk,把vk的入度减1;若vk的入度为0则进栈
    3. 若栈空时输出的顶点个数不是n,则有向图有环;否则,拓扑排序完毕。

    AOE网:带权的有向无环图,其中顶点表示事件,弧表示活动,权表示活动持续时间。在工程上常用来表示工程进度计划。

    一些定义:

    1. 事件的最早发生时间(ve(j)):从源点到j结点的最长的路径。意味着事件最早能够发生的时间。
    2. 事件的最迟发生时间(vl(j)):不影响工程的如期完工,事件j必须发生的时间。
    3. 活动ai由弧

    查找

    顺序查找、折半查找、索引查找、分块查找是静态查找,动态查找有二叉排序树查找,最优二叉树查找,键树查找,哈希表查找

    静态查找表

    顺序表的顺序查找:应用范围:顺序表或线性链表表示的表,表内元素之间无序。查找过程:从表的一端开始逐个进行记录的关键字和给定值的比较。

    顺序有序表的二分查找。平均查找时间(n+1)/n log2(n+1)

    分块查找:将表分成几块,块内无序,块间有序,即前一块中的最大值小于后一块中的最小值。并且有一张索引表,每一项存放每一块的最大值和指向该块第一个元素的指针。索引表有序,块内无序。所以,块间查找用二分查找,块内用顺序查找,效率介于顺序和二分之间;先确定待查记录所在块,再在块内查找。因此跟表中元素个数和块中元素个数都有关。

    1. 用数组存放待查记录,
    2. 建立索引表,由每块中最大(小)的关键字及所属块位置的信息组成。
    3. 当索引表较大时,可以采用二分查找
    4. 在数据量极大时,索引可能很多,可考虑建立索引表的索引,即二级索引,原则上索引不超过三级

    分块查找平均查找长度:ASLbs = Lb + Lw。其中,Lb是查找索引表确定所在块的平均查找长度, Lw是在块中查找元素的平均查找长度。在n一定时,可以通过选择s使ASL尽可能小。当s=sqrt(n)时,ASL最小。

    1. 时间:顺序查找最差,二分最好,分块介于两者之间
    2. 空间:分块最大,需要增加索引数据的空间
    3. 顺序查找对表没有特殊要求
    4. 分块时数据块之间在物理上可不连续。所以可以达到插入、删除数据只涉及对应的块;另外,增加了索引的维护。
    5. 二分查找要求表有序,所以若表的元素的插入与删除很频繁,维持表有序的工作量极大。
    6. 在表不大时,一般直接使用顺序查找。

    动态查找

    二叉排序树的结点删除:

    1. x为叶子结点,则直接删除
    2. x只有左子树xL或只有右子树xR ,则令xL或xR直接成为双亲结点f的子树;
    3. x即有左子树xL也有右子树xR,在xL中选值最大的代替x,该数据按二叉排序树的性质应在最右边。

    平衡二叉树:每个结点的平衡因子都为 1、-1、0 的二叉排序树。或者说每个结点的左右子树的高度最多差1的二叉排序树。

    平衡二叉树的平衡:

    1. 左调整(新结点插入在左子树上的调整):
      • LL(插入在结点左子树的左子树上):旋转前后高度都为h+1
      • LR(新插入结点在左子树的右子树上):旋转前后高度仍为h+1
    2. 右调整(新结点插入在右子树上进行的调整):
      • RR(插入在的右子树的右子树上):处理方法和 LL对称
      • RL(插入在的右子树的左子树上):处理方法和 LR对称

    平衡树建立方法:

    1. 按二叉排序树插入结点
    2. 如引起结点平衡因子变为|2|,则确定旋转点,该点是离根最远(或最接近于叶子的点)
    3. 确定平衡类型后进行平衡处理,平衡后以平衡点为根的子树高不变
    4. 最小二叉平衡树的节点的公式如下 F(n)=F(n-1)+F(n-2)+1 这个类似于一个递归的数列,可以参考Fibonacci数列,1是根节点,F(n-1)是左子树的节点数量,F(n-2)是右子树的节点数量。

    常见的平衡二叉树:

    1. 红黑树是平衡二叉树,也就是左右子树是平衡的,高度大概相等。这种情况等价于一块完全二叉树的高度,查找的时间复杂度是树的高度,为logn,插入操作的平均时间复杂度为O(logn),最坏时间复杂度为O(logn)
      红黑树
      • 节点是红色或黑色。
      • 根是黑色。
      • 所有叶子都是黑色(叶子是NIL节点)。
      • 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
      • 从任一节点到其每个叶子的所有简单路径 都包含相同数目的黑色节点。
    2. avl树也是自平衡二叉树;红黑树和AVL树查找、插入、删除的时间复杂度相同;包含n个内部结点的红黑树的高度是o(logn); TreeMap 是一个红黑树的实现,能保证插入的值保证排序
    3. STL和linux多使用红黑树作为平衡树的实现:
      1. 如果插入一个node引起了树的不平衡,AVL和RB-Tree都是最多只需要2次旋转操作,即两者都是O(1);但是在删除node引起树的不平衡时,最坏情况下,AVL需要维护从被删node到root这条路径上所有node的平衡性,因此需要旋转的量级O(logN),而RB-Tree最多只需3次旋转,只需要O(1)的复杂度。
      2. 其次,AVL的结构相较RB-Tree来说更为平衡,在插入和删除node更容易引起Tree的unbalance,因此在大量数据需要插入或者删除时,AVL需要rebalance的频率会更高。因此,RB-Tree在需要大量插入和删除node的场景下,效率更高。自然,由于AVL高度平衡,因此AVL的search效率更高。
      3. map的实现只是折衷了两者在search、insert以及delete下的效率。总体来说,RB-tree的统计性能是高于AVL的。

    查找总结

    1. 既希望较快的查找又便于线性表动态变化的查找方法是哈希法查找。二叉排序树查找,最优二叉树查找,键树查找,哈希法查找是动态查找。分块、顺序、折半、索引顺序查找均为静态。分块法应该是将整个线性表分成若干块进行保存,若动态变化则可以添加在表的尾部(非顺序结构),时间复杂度是O(1),查找复杂度为O(n);若每个表内部为顺序结构,则可用二分法将查找时间复杂度降至O(logn),但同时动态变化复杂度则变成O(n);顺序法是挨个查找,这种方法最容易实现,不过查找时间复杂度都是O(n),动态变化时可将保存值放入线性表尾部,则时间复杂度为O(1);二分法是基于顺序表的一种查找方式,时间复杂度为O(logn);通过哈希函数将值转化成存放该值的目标地址,O(1)
    2. 二叉树的平均查找长度为O(log2n)——O(n).二叉排序树的查找效率与二叉树的高度有关,高度越低,查找效率越高。二叉树的查找成功的平均查找长度ASL不超过二叉树的高度。二叉树的高度与二叉树的形态有关,n个节点的完全二叉树高度最小,高度为[log2n]+1,n个节点的单只二叉树的高度最大,高度为n,此时查找成功的ASL为最大(n+1)/2,因此二叉树的高度范围为[log2n]+1——n.
    3. 链式存储不能随机访问,必须是顺序存储

    B_树的B+树

    B_树

    B-树就是B树。m阶B_树满足或空,或为满足下列性质的m叉树:

    B-树

    1. 树中每个结点最多有m棵子树
    2. 根结点在不是叶子时,至少有两棵子树
    3. 除根外,所有非终端结点至少有⎡m/2⎤棵子树
    4. 有s个子树的非叶结点具有 n = s-1个关键字,结点的信息组织为:(n,A0,K1,A1,K2,A2 … Kn,An)。这里:n为关键字的个数,ki(i=1,2,…,n)为关键字,且满足Ki小于Ki+1,,Ai(i=0,1,..n)为指向子树的指针。
    5. 所有的叶子结点都出现在同一层上,不带信息(可认为外部结点或失败结点)。
    6. 关键字集合分布在整颗树中
    7. 任何一个关键字出现且只出现在一个结点中
    8. 搜索有可能在非叶子结点结束
    9. 其搜索性能等价于在关键字全集内做一次二分查找
    10. 只适用于随机检索,不适用于顺序检索。
    11. 有结点的平衡因子都为零
    12. M阶B-树中含有N个关键字,最大深度为log⎡m/2⎤(n+1)/2+2

    B_树中结点的插入

    1. m代表B_树的阶,插入总发生在最低层
    2. 插入后关键字个数小于等于 m-1,完成。
    3. 插入后关键字个数等于m,结点分裂,以中点数据为界一分为二,中点数据放到双亲结点中。这样就有可能使得双亲结点的数据个数为m,引起双亲结点的分裂,最坏情况下一直波及到根,引起根的分裂——B_树长高。

    3阶B_树的插入。每个结点最多3棵子树,2个数据;最少2棵子树,1个数据。所以3阶B_树也称为2-3树。

    B_树中结点的删除

    1. 删除发生在最底层
      • 被删关键字所在结点中的关键字数目大于等于 m/2 ,直接删除。
      • 删除后结点中数据为⎡m/2⎤-2,而相邻的左(右)兄弟中数据大于⎡m/2⎤-1,此时左(右兄弟)中最大(小)的数据上移到双亲中,双亲中接(靠)在它后(前)面的数据移到被删数据的结点中
      • 其左右兄弟结点中数据都是⎡m/2⎤-1,此时和左(右)兄弟合并,合并时连同双亲中相关的关键字。此时,双亲中少了一项,因此又可能引起双亲的合并,最坏一直到根,使B-树降低一层。
    2. 删除不在最底层
      • 在大于被删数据中选最小的代替被删数据,问题转换成在最底层的删除

    B+树

    在实际的文件系统中,用的是B+树或其变形。有关性质与操作类似与B_树。

    B+树

    差异:

    1. 有n棵子树的结点中有n个关键字,每个关键字不保存数据,只用来索引,所有数据都保存在叶子节点。
    2. 所有叶子结点中包含全部关键字信息,及对应记录位置信息及指向含有这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大的顺序链接。(而B树的叶子节点并没有包括全部需要查找的信息)
    3. 所有非叶子为索引,结点中仅含有其子树根结点中最大(或最小)关键字。 (而B树的非终节点也包含需要查找的有效信息)
    4. 非叶最底层顺序联结,这样可以进行顺序查找

    B+特性

    1. 所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的;
    2. 不可能在非叶子结点命中
    3. 非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层
    4. 更适合文件索引系统
    5. B+树插入操作的平均时间复杂度为O(logn),最坏时间复杂度为O(logn)

    查找过程

    • 在 B+ 树上,既可以进行缩小范围的查找,也可以进行顺序查找;
    • 在进行缩小范围的查找时,不管成功与否,都必须查到叶子结点才能结束;
    • 若在结点内查找时,给定值≤Ki, 则应继续在 Ai 所指子树中进行查找

    插入和删除的操作:类似于B_树进行,即必要时,也需要进行结点的“分裂”或“合并”。

    为什么说B+tree比B树更适合实际应用中操作系统的文件索引和数据库索引?

    1. B+tree的磁盘读写代价更低
      • B+tree的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对B 树更小。如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说IO读写次数也就降低了。
      • 举个例子,假设磁盘中的一个盘块容纳16bytes,而一个关键字2bytes,一个关键字具体信息指针2bytes。一棵9阶B-tree(一个结点最多8个关键字)的内部结点需要2个盘快。而B+树内部结点只需要1个盘快。当需要把内部结点读入内存中的时候,B树就比B+树多一次盘块查找时间(在磁盘中就是盘片旋转的时间)。
    2. B+tree的查询效率更加稳定
      • 由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

    B树和B+树都是平衡的多叉树。B树和B+树都可用于文件的索引结构。B树和B+树都能有效的支持随机检索。B+树既能索引查找也能顺序查找.

    哈希表

    1. 在记录的存储地址和它的关键字之间建立一个确定的对应关系;这样不经过比较,一次存取就能得到元素。
    2. 哈希函数——在记录的关键字与记录的存储位置之间建立的一种对应关系。是从关键字空间到存储位置空间的一种映象。
    3. 哈希表——应用哈希函数,由记录的关键字确定记录在表中的位置信息,并将记录根据此信息放入表中,这样构成的表叫哈希表。
    4. Hash查找适合于关键字可能出现的值的集合远远大于实际关键字集合的情形。
    5. 更适合查找,不适合频繁更新
    6. Hash表等查找复杂依赖于Hash值算法的有效性,在最好的情况下,hash表查找复杂度为O(1)。只有无冲突的hash_table复杂度才是O(1)。一般是O(c),c为哈希关键字冲突时查找的平均长度。插入,删除,查找都是O(1)。平均查找长度不随表中结点数目的增加而增加,而是随负载因子的增大而增大
    7. 由于冲突的产生,使得哈希表的查找过程仍然是一个给定值与关键字比较的过程。

    根据抽屉原理,冲突是不可能完全避免的,所以,选择好的散列函数和冲突处理方法:

    1. 构造一个性能好,冲突少的Hash函数
    2. 如何解决冲突

    常用的哈希函数

    1. 直接定址法。仅适合于:地址集合的大小 == 关键字集合的大小
    2. 数字分析法。对关键字进行分析,取关键字的若干位或其组合作哈希地址。仅适合于:能预先估计出全体关键字的每一位上各种数字出现的频度。
    3. 平方取中法。以关键字的平方值的中间几位作为存储地址。
    4. 折叠法。将关键字分割成位数相同的几部分,然后取这几部分的叠加和(舍去进位)做哈希地址。移位叠加/间界叠加。适合于: 关键字的数字位数特别多,且每一位上数字分布大致均匀情况。
    5. 除留余数法。取关键字被某个不大于哈希表表长m的数p除后所得余数作哈希地址,即H(key)=key%p,p<=m。
    6. 随机数法。取关键字的伪随机函数值作哈希地址,即H(key)=random(key),适于关键字长度不等的情况。

    冲突解决

    1. 开放定址法。当冲突发生时,形成一个探查序列;沿此序列逐个地址探查,直到找到一个空位置(开放的地址),将发生冲突的记录放到该地址中。即Hi=(H(key)+di) % m,i=1,2,……k(k<=m-1),H(key)哈希函数,m哈希表长,di增量序列。缺点:删除:只能作标记,不能真正删除;溢出;载因子过大、解决冲突的算法选择不好会发生聚集问题。要求装填因子α较小,故当结点规模较大时会浪费很多空间。
      • 线性探测再散列:di=1,2,3,…,m-1
      • 二次探测再散列:di=12,-12,22,-22,…,±k2(k<=m/2)
      • 伪随机探测再散列: di为伪随机数序列
    2. 链地址法:将所有关键字为同义词的记录存储在一个单链表中,并用一维数组存放头指针。拉链法中可取α≥1,且结点较大时,拉链法中增加的指针域可忽略不计,因此节省空间。一旦发生冲突,在当前位置给单链表增加结点就行。
    3. 其他方法:再哈希法、建立公共溢出区
    4. 在用拉链法构造的散列表中,删除结点的操作易于实现。拉链法的缺点是:指针需要额外的空间,故当结点规模较小时,开放定址法较为节省空间。由于拉链法中各链表上的结点空间是动态申请的,故它更适合于造表前无法确定表长的情况。拉链法解决冲突时,需要使用指针,指示下一个元素的存储位置
    5. 开哈希表–链式地址法;闭哈希表–开放地址法.开哈希和闭哈希主要的区别在于,随着哈希表的密集度提高,使用闭哈希时,不仅会与相同哈希值的元素发生冲突,还容易与不同哈希值的元素发生冲突;而开哈希则不受哈希表疏密与否的影响,始终只会与相同哈希值的元素冲突而已。所以在密集度变大的哈希表中查找时,显然开哈希的平均搜索长度不会增长。
    6. 设有n个关键字具有相同的Hash函数值,则用线性探测法把这n个关键字映射到Hash表中需要做n*(n-1)/2次线性探测。如果使用二次探测再散列法将这n个关键字存入哈希表,至少要进行n*(n+1)/2次探测

    Hash查找效率:装填因子=表中记录数/表容量

    有B+Tree/Hash_Map/STL Map三种数据结构。对于内存中数据,查找性能较好的数据结构是Hash_Map,对于磁盘中数据,查找性能较好的数据结构是B+Tree。Hash操作能根据散列值直接定位数据的存储地址,设计良好的hash表能在常数级时间下找到需要的数据,但是更适合于内存中的查找。B+树是一种是一种树状的数据结构,适合做索引,对磁盘数据来说,索引查找是比较高效的。STL_Map的内部实现是一颗红黑树,但是只是一颗在内存中建立二叉树树,不能用于磁盘操作,而其内存查找性能也比不上Hash查找。

    内部排序

    1. 内部排序:全部数据可同时放入内存进行的排序。
    2. 外部排序:文件中数据太多,无法全部调入内存进行的排序。

    插入类:

    1. 直接插入排序。最坏情况是数据递减序,数据比较和移动量最大,达到O(n2),最好是数据是递增序,比较和移动最少为O(n)。趟数是固定的n-1,即使有序,也要依次从第二个元素开始。排序趟数不等于时间复杂度。
    2. 折半插入排序 。由于插入第i个元素到r[1]到r[i-1]之间时,前i个数据是有序的,所以可以用折半查找确定插入位置,然后插入。
    3. 希尔排序。缩小增量排序。5-3-1。在实际应用中,步长的选取可简化为开始为表长n的一半(n/2),以后每次减半,最后为1。插入的改进,最后一趟已基本有序,比较次数和移动次数相比直接插入最后一趟更少

    交换类:

    1. 冒泡排序。O(n2)通常认为冒泡是比较差的,可以加些改进,比如在一趟中无数据的交换,则结束等措施。
      • 在数据已基本有序时,冒泡是一个较好的方法
      • 在数据量较少时(15个左右)可以用冒泡
    2. 快速排序。
      • 时间复杂度。最好情况:每次支点总在中间,O(nlog2n),平均O(nlog2n)。最坏,数据已是递增或递减,O(n2)。pivotkey的选择越靠近中央,即左右两个子序列长度越接近,排序速度越快。越无序越快。
      • 空间复杂度。需栈空间以实现递归,最坏情况:S(n)=O(n);一般情况:S(n)=O(log2n)
      • 在序列已是有序的情况下,时间复杂度最高。原因:支点选择不当。改进:随机选取支点或最左、最右、中间三个元素中的值处于中间的作为支点,通常可以避免最坏情况。所以,快速排序在表已基本有序的情况下不合适。
      • 在序列长度已较短时,采用直接插入排序、起泡排序等排序方法。序列的个数通常取10左右。

    选择类排序:

    1. 简单选择排序。O(n2)。总比较次数n(n-1)/2。
    2. 堆排序。建堆 O(n),筛选排序O(nlogn)。找出若干个数中最大/最小的前K个数,用堆排序是最好。小根堆中最大的数一定是放在叶子节点上,堆本身是个完全二叉树,完全二叉树的叶子节点的位置大于[n/2]。时间复杂度不会因为待排序序列的有序程度而改变,但是待排序序列的有序程度会影响比较次数。
    3. 归并排序。时间:与表长成正比,若一个表表长是m,另一个是n,则时间是O(m+n)。单独一个数组归并,时间:O(nlogn),空间:O(n),比较次数介于(nlogn)/2和(nlogn)-n+1,赋值操作的次数是(2nlogn)。归并排序算法比较占用内存,但却是效率高且稳定的排序算法。在外排序中使用。归并的趟数是logn。
    4. 基数排序。在一般情况下,每个结点有 d 位关键字,必须执行 t = d次分配和收集操作。分配的代价:O(n);收集的代价:O(rd) (rd是基数);总的代价为:O( d ×(n + rd))。适用于以数字和字符串为关键字的情况。
    5. 枚举排序,通常也被叫做秩排序,比较计数排序。对每一个要排序的元素,统计小于它的所有元素的个数,从而得到该元素在整个序列中的位置,时间复杂度为O(n2)

    比较法分类的下界:O(nlogn)

    排序算法的一些特点:

    1. 堆排序、冒泡排序、快速排序在每趟排序过程中,都会有一个元素被放置在其最终的位置上。
    2. 有字符序列 {Q,H,C,Y,P,A,M,S,R,D,F,X} ,新序列{F,H,C,D,P,A,M,Q,R,S,Y,X},是快速排序算法一趟扫描的结果。(拿Q作为分割点,快速排序一轮。二路归并,第一趟排序,得到 n / 2 个长度为 2 的各自有序的子序列,第二趟排序,得到 n / 4 个长度为 4 的各自有序的子序列H Q C Y A P M S D R F X。如果是快速排序的话,第一个元素t将会被放到一个最准确的位置,t前的数均小于t,后面的数均大于t。希尔排序每个小分组内将会是有序的。堆排序,把它构成一颗二叉树的时候,该堆要么就是大根堆,要么就是小根堆,第一趟Y排在最后;冒泡,那么肯定会有数据下沉的动作,第一趟有A在第一位。)
    3. 在文件”局部有序”或文件长度较小的情况下,最佳内部排序的方法是直接插入排序。(归并排序要求待排序列已经部分有序,而部分有序的含义是待排序列由若干有序的子序列组成,即每个子序列必须有序,并且其时间复杂度为O(nlog2n);直接插入排序在待排序列基本有序时,每趟的比较次数大为降低,即n-1趟比较的时间复杂度由O(n^2)降至O(n)。在待排序的元素序列基本有序或者每个元素距其最终位置不远也可用插入排序,效率最高的排序方法是插入排序
    4. 排序趟数与序列的原始状态有关的排序方法是优化冒泡和快速排序法。(插入排序和选择排序不管序列的原始状态是什么都要执行n-1趟,优化冒泡和快排不一定。仔细理解排序的次数比较次数的区别)
    5. 不稳定的排序方法:快排,堆排,希尔,选择
    6. 要与关键字的初始排列次序无关,那么就是最好、最坏、一般的情况下排序时间复杂度不变, 总共有堆排序,归并排序,选择排序,基数排序
    7. 快速排序、Shell 排序、归并排序、直接插入排序的关键码比较次数与记录的初始排列有关。折半插入排序、选择排序无关。(直接插入排序在完全有序的情况下每个元素只需要与他左边的元素比较一次就可以确定他最终的位置;折半插入排序,比较次数是固定的,与初始排序无关;快速排序,初始排序不影响每次划分时的比较次数,都要比较n次,但是初始排序会影响划分次数,所以会影响总的比较次数,但快排平均比较次数最小;归并排序在归并的时候,如果右路最小值比左路最大值还大,那么只需要比较n次,如果右路每个元素分别比左路对应位置的元素大,那么需要比较2*n-1次,所以与初始排序有关)
    8. 精俭排序,即一对数字不进行两次和两次以上的比较,插入和归并是“精俭排序”。插入排序,前面是有序的,后面的每一个元素与前面有序的元素比较,比较过的就是有序的了,不会再比较一次。归并每次合并后,内部都是有序的,内部的元素之间不用再比较。选择排序,每次在后面的元素中找到最小的,找最小元素的过程是在没有排好序的那部分进行,所有肯定会比较多次。堆排序也需比较多次。

    外部排序

    1. 生成合并段(run):读入文件的部分记录到内存->在内存中进行内部排序->将排好序的这些记录写入外存,形成合并段->再读入该文件的下面的记录,往复进行,直至文件中的记录全部形成合并段为止。
    2. 外部合并:将上一阶段生成的合并段调入内存,进行合并,直至最后形成一个有序的文件。
    3. 外部排序指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存,需要在内存和外部存储器之间进行多次数据交换,以达到排序整个文件的目的。外部排序最常用的算法是多路归并排序,即将原文件分解成多个能够一次性装入内存的部分,分别把每一部分调入内存完成排序。然后,对已经排序的子文件进行多路归并排序
    4. 不管初始序列是否有序, 冒泡、选择排序时间复杂度是O(n^2),归并、堆排序时间复杂度是O(nlogn)
    5. 外部排序的总时间 = 内部排序(产出初始归并段)所需时间 + 外存信息读取时间 + 内部归并所需的时间
    6. 外排中使用置换选择排序的目的,是为了增加初始归并段的长度。减少外存读写次数需要减小归并趟数

    7. 根据内存容量设若干个输入缓冲区和一个输出缓冲区。若采用二路归并,用两个输入缓冲。

    8. 归并的方法类似于归并排序的归并算法。增加的是对缓冲的监视,对于输入,一旦缓冲空,要到相应文件读后续数据,对于输出缓冲,一旦缓冲满,要将缓冲内容写到文件中去。
    9. 外排序和内排序不只是考虑内外排序算法的性能,还要考虑IO数据交换效率的问题,内存存取速度远远高于外存。影响外排序的时间因素主要是内存与外设交换信息的总次数

    有效的算法设计

    1. 贪心法。Dijkstra的最短路径(时间复杂度O(n2));Prim求最小生成树邻接表存储时是O(n+e),图O(n2);关键路径及关键活动的求法。
    2. 回溯法
    3. 分支限界法
    4. 分治法。分割、求解、合并。二分查找、归并排序、快速排序。
    5. 动态规划。Floyd-Warshall算法求解图中所有点对之间最短路径时间复杂度为O(n3)

    动态规划解题的方法是一种高效率的方法,其时间复杂度通常为O(n2),O(n3)等,可以解决相当大的信息量。(数塔在n<=100层时,可以在很短的时间内得到问题解)

    • 适用的原则:原则为优化原则,即整体优化可以分解为若干个局部优化。
    • 动态规划比穷举法具有较少的计算次数
    • 递归算法需要很大的栈空间,而动态规划不需要栈空间

    贪心和动态规划的差别:

    1. 所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别。
    2. 在动态规划算法中,每步所作的选择往往依赖于相关子问题的解。因而只有在解出相关子问题后,才能作出选择。而在贪心算法中,仅在当前状态下作出最好选择,即局部最优选择。然后再去解作出这个选择后产生的相应的子问题。
    3. 贪心算法所作的贪心选择可以依赖于以往所作过的选择,但决不依赖于将来所作的选择,也不依赖于子问题的解。正是由于这种差别,动态规划算法通常以自底向上的方式解各子问题,而贪心算法则通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为一个规模更小的子问题。

    P问题

    1. P问题,如果它可以通过运行多项式次(即运行时间至多是输入量大小的多项式函数的一种算法获得解决),可以找到一个能在多项式的时间里解决它的算法。—-确定性问题
    2. NP问题,虽然可以用计算机求解,但是对于任意常数k,它们不能在O(nk)时间内得到解答,可以在多项式的时间里验证一个解的问题。所有的P类问题都是NP问题。
    3. NP完全问题,知道有效的非确定性算法,但是不知道是否存在有效的确定性算法,同时,不能证明这些问题中的任何一个不存在有效的确定性算法。这类问题称为NP完全问题。
    展开全文
  • 以下哪个选项不是Python语言的保留字?EXCEL2016中,向单元格输入内容后,想将光标定位在下一列,按()健。A:TABB:CTRLC:ALTD:SHIFTAPCI源特别适合强极性化合物的分析。A:错B:对从生产力发展水平看,三代是以青铜器...

    以下哪个选项不是Python语言的保留字?

    EXCEL2016中,向单元格输入内容后,想将光标定位在下一列,按()健。A:TABB:CTRLC:ALTD:SHIFT

    APCI源特别适合强极性化合物的分析。A:错B:对

    从生产力发展水平看,三代是以青铜器为主要生产工具,被称为()A:艺术起源B:原始艺术时代C:青铜时代D:艺术萌芽期

    下列符号表示两拍的是A:B:C:D:

    5G全网建设与优化仿真系统中,NSA组网下,5G基站直接接入到5G核心网,5G核心网传输信令,5GNR基站传输数据业务。A:对B:错

    公元前1000-500年时,在如今意大利北部居住的是__________A:埃特鲁里亚人(Etruschi)B:东北的威尼托人(veneti)C:西北的高卢人(galli)D:拉丁人(latini)

    有的时候,工程的实际使用寿命并会大于设计寿命。A:错B:对

    插座的线路很简单,应遵循一个原则对于两孔插座,通常是左零、右火。A:错B:对

    态度不是与生俱来的,且稳定而不变。A:错B:对

    出口补贴对出口国消费的影响是()A:国内价格下降消费增加B:国内价格上涨消费减少C:政府补贴支出增加D:出口量增加

    控制的有效性取决于()。A:纠正的方法和方向B:监督的方法和力度C:科学的方法与工具D:计划的周密程度

    约翰·罗尔斯要求人们采用“无知之幕”的思维方式,来寻求()原则。A:程序公正B:分配公正C:交易公正D:补偿公正

    脉冲反吹风袋式收尘器种类有()。A:手动式B:电动型C:机动型D:气动型

    由于书法是以汉字为塑造形象的材料,与人们的生活、学习、工作没有关系。()A:对B:错

    以下是挺水植物的是()。A:金鱼藻B:苦草C:菱D:芦苇

    Whatisthemainaimofbookreview?A:summariesreviewsandcommentstheresearchtrendsthemajordiscoveriessignificantfindingstheleadingopinionsonaparticularsubjectB:analyzingordiscussingresearchespreviouslypublishedbyothersC:analyzingaperspectiveorarguesapoin

    声带小结喉镜下表现为()A:单侧声带前1/3处游离缘突起;B:双侧声带前1/3游离缘对称性突起;C:双侧声带前中1/3游离缘突起;D:双侧声带中后1/3交点的游离缘对称突起。

    海洋内波因为发生在海洋内部,所以没有什么危害。A:错B:对

    Speakingreferstocharacterdialogs,whichservetopropelthedevelopmentofthestory.A:对B:错

    建筑物的荷载最终是由基础承担的。A:错B:对

    AutoCAD软件文字样式对话框中,“字高”不能设置为0,否则书写的文字高度即为0。A:错B:对

    急性弥漫性增生性肾小球肾炎光镜下的主要病变为A:肾小球系膜基质增生B:肾小球内皮细胞和系膜细胞增生C:壁层上皮增生D:新月体形成E:肾小球基底膜增厚

    几何条件反映的速度变化与截面变化的关系。A:对B:错

    导游按工作程序,应该在规定时间要求送客到达机场,如客人乘坐的是国内航班,应提前多长时间()A:120分钟B:60分钟C:45分钟D:90分钟

    “替代性旅游”这一概念的几个核心成分包括:旅游者与当地人之间的接触和沟通、对平等的追求、()、对环境意识的追求和对人文关怀的追求。A:对文化的追求B:对个性的追求C:对公益的追求D:对消费的追求

    “选择性粘贴”对话框有哪些选项?A:批注B:全部C:数值D:格式

    面部皮肤低度恶性肿瘤为()A:腺癌B:蕈样肉芽肿C:恶性黑素瘤D:基底细胞癌E:鳞状细胞癌

    定量金相的基本符号采用国际通用的体视学符号,其中L表示()。A:点数B:平面面积C:线段长度D:物体数

    糖皮质激素的临床应用有_______________。A:各种休克B:低血容量性休克C:感染中毒性休克D:过敏性休克E:心源性休克

    技术创新,只有通过有独创意义的设计创造出全新的产品成为引导消费的先驱。虽然功能性的创造离不开技术设计,但产品设计对功能的创造与技术设计是不同的。A:对B:错

    江西某公司为获取一项工程合同,拟向工程发包有关人员支付好处费10万元。公司市场部持公司董事长的批示到财会部申领该笔款项。财会部经理王某认为,该项支出不符合有关规定,但考虑到公司主要领导已作出了批示,即同意拨付该笔款项。下列各项中,正确的是()。A:王某的行为与会计职业道德无关B:王某的行为违背了坚持准则的会计职业道德要求C:王某的行为违背了爱岗敬业的会计职业道德要求D:王某的行为符合参与管理的会计职业道德要求

    与女子胞关系密切的经脉是()A:任脉B:带脉C:督脉D:冲脉

    顺治十四年江南乡试案中,因为()中举方氏家族成员受到牵连而被流放。A:方孝标B:方犹C:方拱乾D:方章钺

    同一优先级的中断源同时发生时,CPUA:外部中断1B:定时器0中断C:定时器1中断D:外部中断0

    在sheet1工作表中引用sheet2中A1单元格的内容,引用格式为sheet2.A1.A:对B:错

    基于新型半导体结构的FPGA的两种结构有:碳纳米管交叉开关结构、忆阻器结构。A:错B:对

    Whatdoestheword“catchy”mean?A:歌曲朗朗上口的B:主题容易抓住的

    阿莫西林粉主要用于治疗鱼类细菌性疾病。A:错B:对

    有车之人对某款车的评价不会受自己车子品牌的影响。()A:错B:对

    创业者应该如何有效资源整合?()A:发挥自有资源杠杆作用B:设置利益“共赢”机制C:用心经营人脉资源D:控制启动期费用支出

    如果(1)锗用锑(A:(1)为n型半导体(2)为p型半导体B:(1)(2)均为n型半导体C:(1)(2)均为p型半导体D:(1)为p型半导体(2)为n型半导体

    在Excel?2010中,可在原工作表中嵌入图表,也可以在新工作表中生成图表。A:对B:错

    情绪与肝有关是因为()A:肝主疏泄能调节情志B:肝主升发C:肝能藏血和调节血量D:肝能调节女子月经和男子排精

    学生的知识学习过程主要是一个对知识的内在加工过程,包括三个阶段A:知识应用B:知识反馈C:知识获得D:知识保持

    肾综合征出血热病毒感染引起的典型临床表现有A:头痛眼眶痛腰痛B:面、颈、上胸部潮红C:水肿D:出血和肾损害E:高热

    信息的外部来源产生在()。A:市场推广信息B:经验来源C:私人来源D:公共来源

    JSON使用什么符号来表示对象?A:[]B::C:{}D:""

    展开全文
  • 数据结构的基本概念【图文详解】

    千次阅读 2018-09-14 21:58:01
    1.1数据结构: 计算机科学是一门研究数据表示和数据处理的科学,在利用计算机进行数据处理时,...1.1.1基本概念: 1.数据 数据(Date)是外部世界信息的载体。它能够被计算机识别、存储和加工处理,是计算机程序的...
  • 数据结构的基本概念习题

    千次阅读 2020-03-18 21:49:01
    1、可以用(D )定义一个完整的数据结构。 A、数据元素 B、数据对象 C、数据关系 D、抽象数据类型 解析: 抽象数据类型(ADT)描述了数据的逻辑结构和抽象运算,通常用(数据对象,数据关系,基本...2、以下数据结构...
  • 提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一、pandas是什么? 二、使用步骤 1.... 2....例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多...(数据..
  • 数据结构基础概念知识点_保研/考研/面试复习

    千次阅读 多人点赞 2019-09-17 20:21:22
    为准备推免保研面试,对数据结构基础概念知识点作了如下总结。 参考书籍:《数据结构(C语言版)》 严蔚敏等 清华大学出版社 参考网页:https://blog.csdn.net/qq_31196849/article/details/78529724 以上引用侵删。 ...
  • 在数据库技术中,用数据模型的概念描述数据库的结构和语义,是对现实世界的数据抽象。数据模型是研究数据库技术的核心和基础。 文章目录1.概念数据模型(CDM)2.逻辑数据模型(LDM)3.物理数据模型(PDM) 1.概念...
  • 【数据结构】链表的概念以及分类

    千次阅读 2018-11-02 16:52:14
    我们知道顺序表和链表都属于线性表。既然都是存储数据,干啊费那么大劲整这么多,所以它们俩肯定有各自的优点和缺点。   优点 缺点 顺序表 1.支持随机访问 1....
  • 【知识图谱】知识图谱的基础概念与构建流程

    千次阅读 多人点赞 2019-11-09 18:46:49
    3.1知识图谱的逻辑结构 3.2知识图谱的体系架构 4、代表性知识图谱库 5、知识图谱构建的关键技术 5.1 知识提取 5.2 知识表示 5.3 知识融合 【导读】知识图谱技术是人工智能技术的组成部分,其强大的语义处理和...
  • 概念结构设计宏观步骤. 局部E-R模型设计. E-R图冲突. 1.属性冲突. 2.命名冲突. 3.结构冲突. 合并局部E-R模型. E-R图冗余. 优化初步E-R图. 关系模式转换. 合并关系模式. Some Examples. E1. E2. E3. 概念结构设计...
  • 数据结构分别为逻辑结构、(存储)物理结构和数据的运算三个部分。 为什么要学数据结构? 首先,因为数据结构作为计算机专业的专业基础课程,是计算机考研的必考科目之一,如果打算报考计算机专业的研究生,你...
  • 数据结构的基本概念与术语

    万次阅读 2019-09-13 10:28:11
    数据结构的基本概念与术语数据数据元素数据对象数据结构 数据 数据元素 数据对象 数据结构
  • 数据元素:数据的基本单位,一个数据元素可由若干个数据项组成,数据项是数据的可分割的最小单位数据对象:性质相同的数据元素的集合是数据的一个子集数据结构:相互之间存在一种或多种特定的关系的数据元素的集合...
  • 数据结构面试题

    千次阅读 多人点赞 2018-01-22 10:21:28
    数据结构面试题 1.数据结构与算法常见笔试题    第一章 数据结构与算法 一.算法的基本概念 计算机解题的过程实际上是在实施某种算法,这种算法称为计算机算法。 1.算法的基本特征:可行...
  • 数据结构几个基本概念

    千次阅读 2017-09-14 19:23:11
    程序设计 = 数据结构 + ...其实数据仅仅是什么整形,浮点型,而是所有的具备可以输入到计算机中,能被计算机处理的,,都可以叫做数据,,比如说非数值型数据:声音,图片,视频等都是可以用编码手段编程字符数据来
  • 【参考资料:《数据结构》(C语言版)】 本人实现主要以C++或Java两种语言实现。 数据结构定义 简单来说,数据结构是一门研究非数值计算的程序设计问题中计算机的操作对象以及它们之间的关系和操作等的学科。 ...
  • 分门别类介绍数据结构的基本概念,查漏补缺必看文章。
  • 现代的CPU基本上归为冯诺伊曼结构(也成普林斯顿结构)和哈佛结构。 冯洛伊曼结构就是我们所说的X86架构,而哈佛结构就是ARM架构。一个广泛用于桌面端(台式/笔记本/服务器/工作站等),一个雄踞移动领域,我们的...
  • 以下一些相关的内容,来自王道的数据结构讲解。 基本概念 数据结构是相互之间存在一种或多种特定关系的数据元素的集合。这个概念对于我来说太过于深奥,也能记住,于是我思考。举个例子,在食堂里吃麻辣香锅,我们...
  • 数据结构(廿一) -- C语言版 -- 图 - 图的基本概念

    千次阅读 多人点赞 2020-07-26 20:08:00
    图(Graph)是一种较线性表和树更为复杂的数据结构,在线性表中,数据元素之间仅有线性关系,每个数据元素只有一个直接前驱和一个直接后继;在树形结构中 ,数据元素之间有着明显的层次关系,并且每一层上的数据元素...
  • 数据结构(C++)有关练习题

    热门讨论 2008-01-02 11:27:18
    <br>实验二 单链表结构及计算 实验目的: 通过实验掌握下列知识: 1、熟悉线性表的基本运算在两种存储结构(顺序结构和链式结构)上的实现; 2、继续熟悉VC编程、编译和调试环境; 内容及步骤:...
  • 2、数据结构的基本概念 数据:所有能够输入到计算机中去描述事物的符号。 数据项:有独立含义的数据最小单位,也叫域。 数据元素:数据的基本单位也叫节点、记录。 数据结构:数据元素和数据关系的集合。 算法:数据...
  • 因为教材中的概念之间存在冲突,所以广泛浏览各类教材、视频,对数据结构进行系统、辩证的梳理。建议考研看懂教材或者视频的同学看一看。
  • 数据结构与算法基本概念

    千次阅读 2021-10-24 19:29:23
    数据结构和算法是程序员的必修课,也是基础课。学好数据结构很有必要,对于编程的思维和解决实际问题有很大的好处。最近重新翻看数据结构与算法的书,并把一些知识点整理出来,以加深自己的记忆和理解。 首先要明确...
  • 结构化设计的概念0 目录5 结构化分析方法15.1 结构化设计的概念5.1.1课堂重点5.1.2测试与作业6 下一章 0 目录 5 结构化分析方法1 5.1 结构化设计的概念 5.1.1课堂重点 5.1.2测试与作业 1单选(2分)结构化...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 204,113
精华内容 81,645
关键字:

以下不属于结构概念的是