版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
数据结构与算法编程实战教程指南TOC\o"1-2"\h\u28607第一章基础概念与数据结构 2136511.1数据结构概述 2238911.1.1线性数据结构 2300951.1.2非线性数据结构 2196701.2算法概述 2135681.2.1算法的基本要素 222251.2.2算法设计策略 398541.3时间复杂度与空间复杂度分析 326041.3.1时间复杂度 3206881.3.2空间复杂度 3279111.3.3时间复杂度与空间复杂度的关系 314446第二章数组与链表 3257962.1数组的基本操作 3102532.2动态数组实现 3270092.3链表的概念与实现 458042.4链表的基本操作 416457第三章栈与队列 4243253.1栈的实现与应用 4254153.1.1栈的基本概念 4234393.1.2栈的实现 4123563.1.3栈的应用 6213553.2队列的实现与应用 6144173.2.1队列的基本概念 6184293.2.2队列的实现 685943.2.3队列的应用 8286663.3栈与队列的综合应用 821629第四章排序算法 10215524.1冒泡排序 11143564.2选择排序 11254354.3插入排序 1173904.4快速排序 1215802第五章查找算法 12134805.1线性查找 12159455.2二分查找 1295595.3哈希查找 1314023第六章树与二叉树 13305526.1树的基本概念 13156036.2二叉树的实现 14257056.3二叉树的基本操作 1468196.4线索二叉树 1429138第七章图 15162907.1图的基本概念 15228587.2邻接矩阵与邻接表 15193247.3图的遍历 1577047.4最短路径算法 1613979第八章动态规划 16225838.1动态规划的基本概念 1675288.2斐波那契数列 16198338.3最长公共子序列 1713518.4最小路径和 1828938第九章贪心算法 19293549.1贪心算法的基本概念 19255369.2活动选择问题 1983379.3零钱找零问题 1992319.4最小树 1927953第十章分治算法 192116310.1分治算法的基本概念 192779210.2快速排序的改进 202280410.3最大子序列和 202288110.4合并排序 20第一章基础概念与数据结构1.1数据结构概述数据结构是计算机存储、组织数据的方式。合理的数据结构可以有效地提高数据处理的效率,降低算法的复杂度。数据结构主要分为两大类:线性数据结构和非线性数据结构。1.1.1线性数据结构线性数据结构包括数组、链表、栈、队列等。这类数据结构的特点是数据元素之间存在一对一的线性关系。1.1.2非线性数据结构非线性数据结构包括树、图、哈希表等。这类数据结构的特点是数据元素之间存在一对多或多对多的关系。1.2算法概述算法是一系列解决问题的步骤,它描述了计算机在解决问题时的具体操作。一个好的算法应当具备以下特点:正确性、可读性、健壮性、效率高和可维护性。1.2.1算法的基本要素算法的基本要素包括输入、输出、算法描述、算法实现等。1.2.2算法设计策略算法设计策略包括贪心算法、分治算法、动态规划、回溯算法等。1.3时间复杂度与空间复杂度分析时间复杂度和空间复杂度是评价算法功能的两个重要指标。它们分别描述了算法在执行过程中所消耗的时间和空间资源。1.3.1时间复杂度时间复杂度是描述算法执行时间与输入规模之间关系的函数。常见的时间复杂度有O(1)、O(logn)、O(n)、O(nlogn)、O(n^2)等。1.3.2空间复杂度空间复杂度是描述算法执行过程中所需存储空间与输入规模之间关系的函数。常见的空间复杂度有O(1)、O(logn)、O(n)、O(n^2)等。1.3.3时间复杂度与空间复杂度的关系在算法设计中,通常需要在时间复杂度和空间复杂度之间做出权衡。在实际应用中,应根据具体问题需求和资源限制,选择合适的算法。第二章数组与链表2.1数组的基本操作数组是一种基础的数据结构,用于存储具有相同数据类型的元素集合。在数组中,每个元素都分配了一个索引,用于唯一标识该元素。以下是数组的基本操作:初始化:创建一个指定大小的数组,并初始化所有元素为默认值。访问元素:通过索引访问数组中的特定元素。更新元素:修改数组中指定索引处的元素值。插入元素:在数组中指定位置插入一个新元素,可能需要移动其他元素。删除元素:从数组中删除指定位置的元素,同样可能需要移动其他元素。2.2动态数组实现动态数组是一种特殊的数组,能够在运行时改变其大小。以下是动态数组实现的几个关键点:初始化:创建一个具有初始容量的数组。扩容:当数组达到容量上限时,创建一个更大的数组,并将原数组元素复制到新数组中。缩容:在元素数量减少到一定程度时,可以减小数组的大小以节约内存。动态数组支持数组的基本操作,并且可以在不溢出的情况下插入和删除元素。2.3链表的概念与实现链表是一种由一系列节点组成的线性集合,用于存储一连串数据元素。在链表中,每个节点至少包含两个部分:一个是存储数据元素的数据域,另一个是存储下一个节点地址的指针域。链表的实现方式主要有以下几种:单向链表:每个节点只包含一个指向下一节点的指针。双向链表:每个节点包含两个指针,一个指向前一个节点,另一个指向下一个节点。循环链表:链表中最后一个节点的指针指向第一个节点,形成一个环。2.4链表的基本操作链表的基本操作包括:初始化:创建一个空链表。添加元素:在链表的末尾或特定位置添加新节点。删除元素:从链表中删除指定节点,需要更新相邻节点的指针。查找元素:遍历链表以找到具有特定值的节点。更新元素:修改链表中指定节点的数据值。获取链表长度:遍历链表以计算其中的节点数量。第三章栈与队列3.1栈的实现与应用3.1.1栈的基本概念栈(Stack)是一种后进先出(LastInFirstOut,LIFO)的数据结构。在栈中,数据元素的插入和删除操作都只能在栈顶进行。栈的操作主要包括入栈(push)和出栈(pop)。3.1.2栈的实现栈可以使用数组或链表来实现。以下是使用数组实现的栈的基本操作:cdefineMAXSIZE100//定义栈的最大容量typedefstruct{intdata[MAXSIZE];//存储栈中元素inttop;//栈顶指针}Stack;//初始化栈voidInitStack(Stacks){s>top=1;}//判断栈是否为空intIsEmpty(Stacks){returns>top==1;}//判断栈是否已满intIsFull(Stacks){returns>top==MAXSIZE1;}//入栈操作intPush(Stacks,intx){if(IsFull(s)){return0;//栈满,无法入栈}s>data[s>top]=x;return1;}//出栈操作intPop(Stacks,intx){if(IsEmpty(s)){return0;//栈空,无法出栈}x=s>data[s>top];return1;}//获取栈顶元素intGetTop(Stacks,intx){if(IsEmpty(s)){return0;//栈空,无法获取栈顶元素}x=s>data[s>top];return1;}3.1.3栈的应用栈在编程中应用广泛,如括号匹配、表达式求值、递归调用等。3.2队列的实现与应用3.2.1队列的基本概念队列(Queue)是一种先进先出(FirstInFirstOut,FIFO)的数据结构。在队列中,数据元素的插入操作发生在队列尾部,删除操作发生在队列头部。3.2.2队列的实现队列可以使用数组或链表来实现。以下是使用循环数组实现的队列的基本操作:cdefineMAXSIZE100//定义队列的最大容量typedefstruct{intdata[MAXSIZE];//存储队列中元素intfront;//队列头指针intrear;//队列尾指针}Queue;//初始化队列voidInitQueue(Queueq){q>front=q>rear=0;}//判断队列是否为空intIsEmpty(Queueq){returnq>front==q>rear;}//判断队列是否已满intIsFull(Queueq){return(q>rear1)%MAXSIZE==q>front;}//入队操作intEnQueue(Queueq,intx){if(IsFull(q)){return0;//队列满,无法入队}q>data[q>rear]=x;q>rear=(q>rear1)%MAXSIZE;return1;}//出队操作intDeQueue(Queueq,intx){if(IsEmpty(q)){return0;//队列空,无法出队}x=q>data[q>front];q>front=(q>front1)%MAXSIZE;return1;}//获取队头元素intGetFront(Queueq,intx){if(IsEmpty(q)){return0;//队列空,无法获取队头元素}x=q>data[q>front];return1;}3.2.3队列的应用队列在编程中也有广泛的应用,如任务调度、缓冲区管理、图的广度优先搜索等。3.3栈与队列的综合应用栈和队列在实际编程中常常结合使用,解决一些复杂问题。以下是一个栈与队列综合应用的例子:表达式求值。表达式求值需要处理两种类型的元素:操作数和运算符。操作数存储在栈中,运算符也存储在栈中。在处理表达式时,首先将操作数压入栈,当遇到运算符时,从栈中弹出两个操作数进行计算,然后将计算结果压入栈。当表达式处理完毕时,栈中只剩下一个元素,即表达式的结果。c//表达式求值函数intEvaluateExpression(charexpr){StackopStack,numStack;InitStack(&opStack);InitStack(&numStack);intnum1,num2,result;charop;//处理表达式中的每个字符while(expr!='\0'){if(expr>='0'&&expr<='9'){//操作数入栈Push(&numStack,expr'0');}elseif(expr==''expr==''expr==''expr=='/'){//运算符入栈Push(&opStack,expr);}elseif(expr==')'){//遇到右括号,计算并入栈Pop(&opStack,&op);Pop(&numStack,&num2);Pop(&numStack,&num1);switch(op){case'':result=num1num2;break;case'':result=num1num2;break;case'':result=num1num2;break;case'/':result=num1/num2;break;}Push(&numStack,result);}expr;}//计算栈中剩余的表达式while(!IsEmpty(&opStack)){Pop(&opStack,&op);Pop(&numStack,&num2);Pop(&numStack,&num1);switch(op){case'':result=num1num2;break;case'':result=num1num2;break;case'':result=num1num2;break;case'/':result=num1/num2;break;}Push(&numStack,result);}//获取最终结果Pop(&numStack,&result);returnresult;}第四章排序算法排序算法是计算机科学中一类重要的算法,其目的是将一组数据按照特定的顺序排列。本章将介绍几种常用的排序算法,包括冒泡排序、选择排序、插入排序和快速排序。4.1冒泡排序冒泡排序(BubbleSort)是一种简单的排序算法。其基本思想是通过比较相邻元素的值,将较大的数向后移动,从而实现数据的有序排列。冒泡排序的时间复杂度为O(n^2)。算法描述:(1)从第一个元素开始,比较相邻两个元素的值。(2)如果前一个元素的值大于后一个元素的值,交换这两个元素的位置。(3)对每一对相邻元素进行同样的操作,直到最后一个元素。(4)重复步骤13,直到整个数组有序。4.2选择排序选择排序(SelectionSort)是一种简单直观的排序算法。其基本思想是在未排序序列中找到最小(或最大)元素,存放到排序序列的起始位置,再从剩余未排序元素中继续寻找最小(或最大)元素,然后放到已排序序列的末尾。选择排序的时间复杂度为O(n^2)。算法描述:(1)从数组的第一个元素开始,将当前位置设为最小值位置。(2)遍历数组的剩余部分,寻找比当前位置更小的元素。(3)如果找到比当前位置更小的元素,更新最小值位置。(4)将最小值位置的元素与当前位置的元素交换。(5)重复步骤14,直到整个数组有序。4.3插入排序插入排序(InsertionSort)是一种简单的排序算法。其基本思想是将待排序的元素插入到已排序序列中,从而实现整个序列的有序排列。插入排序的时间复杂度为O(n^2)。算法描述:(1)从数组的第二个元素开始,将其设为待排序元素。(2)遍历已排序序列,从后向前比较待排序元素与已排序元素。(3)如果待排序元素小于已排序元素,将已排序元素向后移动一位。(4)将待排序元素插入到已排序序列的合适位置。(5)重复步骤14,直到整个数组有序。4.4快速排序快速排序(QuickSort)是一种高效的排序算法。其基本思想是选择一个基准元素,将数组分为两部分,一部分包含小于基准元素的值,另一部分包含大于基准元素的值。然后递归地对这两部分进行快速排序。快速排序的平均时间复杂度为O(nlogn)。算法描述:(1)选择一个基准元素,通常选择数组的最后一个元素。(2)将数组分为两部分,一部分包含小于基准元素的值,另一部分包含大于基准元素的值。(3)递归地对这两部分进行快速排序。(4)合并排序后的两部分,得到有序数组。第五章查找算法5.1线性查找线性查找,又称顺序查找,是最基本的查找算法。其基本思想是逐个检查数组中的元素,直至找到目标值或搜索完整个数组。线性查找的优点是算法实现简单,对数据结构无特殊要求,适用于小规模数据或无序数据的查找。算法描述:(1)从数组的首元素开始,逐个检查每个元素;(2)如果当前元素与目标值相等,则返回当前元素的索引;(3)如果搜索完整个数组仍未找到目标值,则返回1。时间复杂度:O(n)5.2二分查找二分查找,又称折半查找,是一种在有序数组中使用的查找算法。其基本思想是,将目标值与数组中间的元素进行比较,根据比较结果调整查找范围,逐步缩小查找区间,直至找到目标值或查找区间为空。算法描述:(1)确定查找区间的上界和下界;(2)计算中间位置:mid=(lowhigh)/2;(3)比较中间位置的元素与目标值:a.如果相等,则返回mid;b.如果中间位置的元素小于目标值,则将查找区间的下界调整为mid1;c.如果中间位置的元素大于目标值,则将查找区间的上界调整为mid1;(4)重复步骤2和3,直至找到目标值或查找区间为空。时间复杂度:O(logn)5.3哈希查找哈希查找,又称散列查找,是一种基于哈希表的查找算法。哈希表是一种通过哈希函数将键映射到表中的位置,以实现快速查找、插入和删除的数据结构。哈希查找的核心思想是,通过哈希函数计算目标值的哈希地址,直接访问数组中对应位置的数据。算法描述:(1)根据哈希函数计算目标值的哈希地址;(2)访问哈希表中对应地址的元素:a.如果元素与目标值相等,则返回该元素的索引;b.如果地址位置为空,则表示查找失败;c.如果发生冲突(多个元素具有相同的哈希地址),则采用冲突解决策略(如开放地址法、链地址法等)继续查找;(3)根据查找结果返回相应的值。时间复杂度:O(1)(理想情况下)第六章树与二叉树6.1树的基本概念树(Tree)是一种重要的数据结构,它模拟了自然界中树的结构,用于表示具有层次关系的数据。树由节点(Node)组成,每个节点包含数据和指向子节点的指针。在树中,每个节点有零个或多个子节点,且每个子节点有且仅有一个父节点。树的几个基本术语如下:根节点(Root):位于树的最顶端,没有父节点的节点。子节点(Child):直接连接到父节点的节点。父节点(Parent):拥有子节点的节点。兄弟节点(Sibling):具有相同父节点的节点。叶子节点(Leaf):没有子节点的节点。节点的层(Level):根节点为第一层,它的子节点为第二层,以此类推。树的高度(Height):树中节点的最大层数。节点的度(Degree):节点拥有的子节点数。6.2二叉树的实现二叉树(BinaryTree)是树的一种特殊形式,每个节点最多有两个子节点,分别为左子节点和右子节点。二叉树有多种实现方式,以下为两种常见的实现方法:(1)链式存储结构:通过节点类和指针实现,每个节点包含数据、指向左子节点的指针和指向右子节点的指针。(2)顺序存储结构:使用数组实现,将树中的节点按照层次遍历的顺序存入数组中。适用于完全二叉树或近似完全二叉树。6.3二叉树的基本操作二叉树的基本操作包括创建、插入、删除、查找、遍历等。以下为几种常见的操作:创建二叉树:根据输入的数据,构建二叉树的链式存储结构或顺序存储结构。插入节点:在二叉树的指定位置插入新的节点。删除节点:删除二叉树中的指定节点,并重新调整树的结构。查找节点:在二叉树中查找特定值的节点。遍历二叉树:按照一定的顺序访问二叉树中的所有节点。常见的遍历方法有前序遍历、中序遍历和后序遍历。6.4线索二叉树线索二叉树(ThreadedBinaryTree)是一种特殊的二叉树,它将二叉树中的空指针改为指向节点的前驱或后继,从而简化遍历操作。线索二叉树分为前序线索二叉树、中序线索二叉树和后序线索二叉树。线索二叉树的实现方法如下:(1)定义线索二叉树节点类,包含数据、左右子节点指针和线索标记。(2)根据遍历方法,将空指针替换为指向前驱或后继的指针,并设置相应的线索标记。(3)实现线索二叉树的遍历方法,利用线索标记直接访问前驱或后继节点。通过线索二叉树,可以简化二叉树的遍历操作,提高遍历效率。在实际应用中,可根据需求选择合适的遍历方法。第七章图7.1图的基本概念图是一种复杂的数据结构,由顶点(Vertex)和边(Edge)组成。在图中,顶点通常表示实体,而边表示实体之间的关系。图的应用非常广泛,如网络结构、社交网络、路径规划等领域。图可分为无向图和有向图。无向图的边没有方向,而有向图的边有方向。图还可以分为简单图和加权图。简单图中的边没有重复,加权图的边有权重,表示从一个顶点到另一个顶点的代价。7.2邻接矩阵与邻接表为了表示图的结构,可以使用邻接矩阵(AdjacencyMatrix)或邻接表(AdjacencyList)。邻接矩阵是一个二维数组,其中的元素表示顶点之间的关系。对于无向图,如果顶点i与顶点j之间存在边,则矩阵的第i行第j列和第j行第i列的元素为1;对于有向图,则第i行第j列的元素为1。邻接矩阵的优点是查找顶点之间的关系速度快,但空间复杂度较高。邻接表是一种链式存储结构,用于表示图中顶点之间的关系。对于无向图,每个顶点对应的链表中包含与该顶点相邻的所有顶点;对于有向图,链表中包含指向该顶点的所有顶点的邻接顶点。邻接表的空间复杂度较低,但查找顶点之间的关系速度较慢。7.3图的遍历图的遍历是指从图中的某个顶点出发,按照一定的顺序访问图中的所有顶点。图的遍历算法主要有深度优先遍历(DFS)和广度优先遍历(BFS)。深度优先遍历的基本思想是:从图的某个顶点出发,访问该顶点,然后递归地访问与该顶点相邻的未被访问的顶点。深度优先遍历的时间复杂度为O(VE),其中V表示顶点数,E表示边数。广度优先遍历的基本思想是:从图的某个顶点出发,访问该顶点,然后按照广度优先的顺序访问与该顶点相邻的未被访问的顶点。广度优先遍历的时间复杂度也为O(VE)。7.4最短路径算法最短路径算法用于求解图中两个顶点之间的最短路径。以下介绍两种经典的最短路径算法:(1)Dijkstra算法:适用于求解有向图中单个源点到其他所有顶点的最短路径。算法的基本思想是:从源点出发,逐步扩展到其他顶点,直到找到目标顶点的最短路径。Dijkstra算法的时间复杂度为O(V^2),但在使用优先队列优化后,时间复杂度可降为O((VE)logV)。(2)Floyd算法:适用于求解任意两个顶点之间的最短路径。算法的基本思想是:通过动态规划,逐步更新两个顶点之间的最短路径。Floyd算法的时间复杂度为O(V^3)。在实际应用中,可根据图的类型和需求选择合适的算法求解最短路径。第八章动态规划8.1动态规划的基本概念动态规划(DynamicProgramming,简称DP)是一种在数学、管理科学、经济学、生物信息学、计算机科学等领域解决特定类型问题的方法。它将复杂问题分解为多个重叠子问题,并存储这些子问题的解,以避免重复计算,从而降低计算复杂度。动态规划的核心思想是记住已经解决过的子问题的解,这通常通过一个表格来实现。动态规划的关键要素包括最优子结构、边界条件、状态转移方程以及状态压缩。8.2斐波那契数列斐波那契数列是一系列数字,其中每个数字是前两个数字的和。通常,数列的前两个数字是0和1。斐波那契数列在动态规划中经常作为入门案例,因为它可以清晰地展示动态规划如何避免重复计算。使用动态规划解决斐波那契数列问题通常涉及创建一个数组来存储中间结果,从而避免重复计算已解决的子问题。cintFibonacci(intn){if(n<=1)returnn;intdp[n1];dp[0]=0;dp[1]=1;for(inti=2;i<=n;i){dp[i]=dp[i1]dp[i2];}returndp[n];}8.3最长公共子序列最长公共子序列(LongestCommonSubsequence,LCS)问题是一个经典的动态规划问题。给定两个序列,LCS问题是要找出这两个序列的最长公共子序列的长度。动态规划解决LCS问题通常使用一个二维数组来存储子问题的解。对于两个序列`X[(1).m]`和`Y[(1).n]`,我们可以定义一个二维数组`dp[m1][n1]`,其中`dp[i][j]`表示`X[(1).i]`和`Y[(1).j]`的LCS的长度。defLCS(X,Y):m,n=len(X),len(Y)dp=[[0](n1)for_inrange(m1)]foriinrange(m1):forjinrange(n1):ifi==0orj==0:dp[i][j]=0elifX[i1]==Y[j1]:dp[i][j]=dp[i1][j1]1else:dp[i][j]=max(dp[i1][j],dp[i][j1])returndp[m][n]8.4最小路径和最小路径和问题通常是在一个二维网格中,从左上角到右下角找出一条路径,使得路径上的数字和最小。动态规划是解决此类问题的有效方法。在这个问题中,我们定义`dp[i][j]`为到达网格位置`(i,j)`的最小路径和。状态转移方程为:dp[i][j]=grid[i][j]min(dp[i1][j],dp[i][j1])其中`grid[i][j]`是网格在位置`(i,j)`的值。javapublicintminPathSum(intgrid){intm=grid.length;intn=grid[0].length;intdp=newint[m][n];dp[0][0]=grid[0][0];for(inti=1;i<m;i){dp[i][0]=dp[i1][0]grid[i][0];}for(intj=1;j<n;j){dp[0][j]=dp[0][j1]grid[0][j];}for(inti=1;i<m;i){for(intj=1;j<n;j){dp[i][j]=Math.min(dp[i1][j],dp[i][j1])grid[i][j];}}returndp[m1][n1];}第九章贪心算法9.1贪心算法的基本概念贪心算法是一种在每一步选择中都采取当前状态下最优的选择,从而希望导致结果是全局最优的算法策略。这种算法的核心思想是在每一步都做出一个局部最优的选择,希望通过局部最优的选择达到全局最优的结果。贪心算法简单直观,但并不总是能得到最优解。9.2活动选择问题
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年秋季开学高中擒敌拳分解动作课件
- 2026年秋季开学初中开学第一课(校园礼仪)课件
- 多层民房分层分套出租合同 同一房屋多户分开租住协议
- 数据资产化实践方案:数字化转型下的资产价值挖掘
- 企业盈利质量动态评估与收益稳定性机制研究
- 银行数字化转型的关键技术演进趋势探讨
- 新质生产力背景下人工智能应用场景协同效应分析
- 耐心资本在硬科技领域长期投资周期适应性机制研究
- 人工智能治理框架中的法律规范与伦理考量
- 政府科技管理者如何利用区域科技创新数智大脑实现精准招商
- 2025年海南三沙市事业单位公开招聘笔试试卷(含完整答案解析)
- 江苏盐城东台市2026年专职网格员招聘考试试卷-含答案解析
- 浙江省杭州市富阳区共同体学校2026-2027学年六上数学期末调研模拟试题含解析
- 2026年公务员遴选本土实务笔试习题及答案
- 2026年1月浙江省选考物理试题(纯答案版)
- 译林版三年级英语下册Unit2 Clean our classroom作业单
- 东方枢纽集团笔试题答案
- 中国平安IQ测评题库
- 食物与能量的转换
- 中级护士聘任申请书范文
- 2025年大学《精神医学-儿童少年精神病学》考试参考题库及答案解析
评论
0/150
提交评论