数据结构考研知识点总结
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构考研真题及知识点解析
考察目标
1. 理解数据结构的基本概念、基本原理和基本方法。
2. 掌握数据的逻辑结构、存储结构及基本操作的实现,能够对算法进行基本的时间复杂度与空间复杂度的分析。
3. 能够运用数据结构的基本原理和方法进行问题的分析与求解,具备采用C、C++或Java语言设计与实现算法的能力。
第2章线性表
一、考研知识点
(一)线性表的定义和基本操作
(二)线性表的实现
1.顺序存储
2.链式存储
3.线性表的应用
二、考研真题
(一)选择题
近两年第2章没有考选择题,因为此章主要是线性表的操作,而且又是这门课的一个基础,考综合题的可能性比较大,而且可以和第3章、第9章和第10章的内容结合来出题。
1.(11年)设n是描述问题规模的非负整数,下面程序片段的时间复杂度是()。
x=2;
while(x A.O(logn) B.O(n) C.O(nlogn) D.O(n2) 分析:答案是A,此题考查的是算法时间复杂度的计算。可以放在第二章,实际这内容贯穿每一章内容中算法的度量。 (二)综合题 1.(09年)已知一个带有表头结点的单链表结点结构为(data,link),假设该链表只给出了头指针list。在不改变链表的前提下,请设计一个尽可能高效的算法,查找链表中倒数第k个位置上的结点(k为正整数)。若查找成功,算法输出该结点的data值,并返回1;否则,只返回0。要求: (1)描述算法的基本设计思想; (2)描述算法的详细实现步骤; (3)根据设计思想和实现步骤,采用程序设计语言描述算法(使用C或C++或JAVA语言实现),关键之处给出简要注释。 分析:此题考查线性表的链式存储,主要是线性表的基本操作的应用。做此题时要把握算法的效率。 (1)算法基本思想如下:从头到尾遍历单链表,并用指针p指向当前结点的前k个结点。当遍历到链表的最后一个结点时,指针p所指向的结点即为所查找的结点。 (2)详细实现步骤:增加两个指针变量和一个整型变量,从链表头向后遍历,其中指针p1指向当前遍历的结点,指针p指向p1所指向结点的前k个结点,如果p1之前没有k 个结点,那么p指向表头结点。用整型变量i表示当前遍历了多少结点,当i>k时,指针p 随着每次遍历,也向前移动一个结点。当遍历完成时,p或者指向表头结点,或者指向链表中倒数第k个位置上的结点。 (3)算法描述: int locate(Linklist list, int k) { p1=list->link; p=list; i=1; while(p1) { p1=p1->link; i++; if(i>k)p=p->next; //如果i>k,则p也后移 } if(p==list)return 0; //链表没有k个结点 else { printf(“%\n”,p->data); return 1; } } 2.(10年)设将n(n,1)个整数存放到一维数组R中,试设计一个在时间和空间两方面尽可能有效的算法,将R中保有的序列循环左移P(0﹤P﹤n)个位置,即将R中的数据由(X0 X1 ……Xn-1)变换为(Xp Xp+1 ……Xn-1 X0 X1 ……Xp-1)要求:(1)给出算法的基本设计思想。 (2)根据设计思想,采用C或C++或JAVA语言表述算法,关键之处给出注释。 (3)说明你所设计算法的时间复杂度和空间复杂度 分析:此题考查的是数组的操作,线性表的顺序存储的核心就是数组,因此此题实质上是考查的线性表的顺序存储的操作及其应用。做此题时要考虑算法的时间和空间复杂度。 解法一: (1)算法的基本设计思想:可以将这个问题看做是把数组ab转化成数组ba(a代表数组的前p个元素,b代表数组中余下的n-p个元素),先将a逆置得到a-1b,再将b逆置得到a-1b-1,最后将整个a-1b-1逆置得到(a-1b-1)-1=ba。设reverse函数执行将数组元素逆置的操作,对abcdefgh向左循环移动3(p=3)个位置的过程如下: reverse(0,p-1)得到cbadefgh; reverse(p,n-1)得到cbahgfde; reverse(0,n-1)得到defghabc。 注:reverse中,两个参数分别表示数组中待转换元素的始末位置。 (2)算法描述: void reverse(int R[], int low, int high) {//将数组中从low到high的元素逆置 int temp; for(i=0;i<=(high-low)/2;i++) { temp=R[low+i]; R[l0ow+i]=R[high-i]; R[high-i]=temp; } } void converse(int R[], int n, int p) { reverse(R,0,p-1); reverse(R,p,n-1); reverse(R,0,n-1); } (3)上述算法中三个reverse函数的时间复杂度分别是O(p/2)、O((n-p)/2)、O(n/2),故所设计算法的时间复杂度为O(n),空间复杂度为O(1)。 解法二: 算法思想:创建大小为p的辅助数组S,将R中前p个整数依次暂存在S中,同时将R 中后n-p个整数左移,然后将S中暂存的p个数依次放回到R中的后续单元。 时间复杂度为O(n),空间复杂度为O(p)。 3.(11年)一个长度为L(L>=1)的生序列S,处在第┌L/2┐个位置的数称为S的中位数,例如,若序列S1=(11,13,15,17,19),则S1的中位数是15,两个序列的中位数是含它们所有元素的升序序列的中位数。例如,若S2=(2,4,6,8,20),则S1和S2的中位数是11。现在有两个等长升序序列A和B,试设计一个在时间和空间方面都尽可能高效的算法,找出两个序列A和B的中位数。要求: (1)给出算法的基本设计思想。 (2)根据设计思想,采用C或C++或JAVA语言描述算法,关键之处给出注释。 解答:此题考查线性表的顺序存储,主要是线性表的基本操作的应用。做此题时要把握算法的效率。 (1)算法的基本设计思想如下: 分别求出序列A 和B的中位数,设为a和b,求序列A和B的中位数过程如下: 1)若a=b,则a或b即为所求中位数,算法结束; 2)若a 3)若a>b,则舍弃序列A中较大的一半,同时舍弃序列B中较小的一半,要求舍弃的长度相等; 在保留的两个升序序列中,重复过程1)-3),直到两个序列中只含一个元素时为止,较小者即为所求的中位数。 (2)算法实现如下: int M_search(int A[],int B[].int n) { int s1=0,d1=n-1,m1,s2=0,d2=n-1,m2; //分别表示序列A和B的首位数、末尾数和中位数 While(s1!=d1||s2!=d2) { m1=(s1+d1)/2; m2=(s2+d2)/2; if(A[m1]==B[m2]) return A[m1]; else if(A[m1