860 likes | 951 Views
数据结构习题. 1 、下面程序段的时间复杂度为( ) for(int i=0;i<m;i++) for(int j=0;j<n;j++) a[i][j]=i*j; A. O(m 2 ) B. O(n 2 ) C. O(m*n) D. O(m+n). 答案: C. 设 n 为正整数 , 分析下列各程序段中加下划线的语句的程序步数。 for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) {
E N D
1、下面程序段的时间复杂度为( ) for(int i=0;i<m;i++) for(int j=0;j<n;j++) a[i][j]=i*j; A. O(m2) B. O(n2) C. O(m*n) D. O(m+n) 答案:C
设n为正整数, 分析下列各程序段中加下划线的语句的程序步数。 for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) { c[i][j] = 0.0; for (int k = 1; k <= n; k++) c[i][j] = c[i][j] + a[i][k] * b[k][j]; }
(2)x = 0; y = 0; for (int i = 1; i <= n; i++) for (int j = 1; j <= i; j++) for (int k = 1; k <= j; k++) x = x + y;
(3) int i = 1, j = 1; while (i<=n && j<=n) { i = i + 1; j = j + i; } i = 1时,i = 2,j = j + i = 1 + 2 = 2 + 1, i = 2时,i = 3,j = j + i = ( 2 + 1 ) + 3 = 3 + 1 + 2, i = 3时,i = 4,j = j + i = ( 3 + 1 + 2 ) + 4 = 4 + 1 + 2 + 3, i = 4时,i = 5,j = j + i = ( 4 + 1 + 2 + 3 ) + 5 = 5 + 1 + 2 + 3 + 4, …… i = k时,i = k + 1,j = j + i = ( k + 1 ) + ( 1 + 2 + 3 + 4 + … + k ),
2、下面算法的时间复杂度为( ) int f(unsigned int n){ if(n==0 || n==1) return 1; else return n*f(n-1); } A. O(1) B. O(n) C. O(n2) D. On!) 答案:B
栈是一种线性表,它的特点是A 。设用一维数组A[1,…,n]来表示一个栈,A[n]为栈底,用整型变量T指示当前栈顶位置,A[T]为栈顶元素。往栈中推入(PUSH)一个新元素时,变量T的值B ;从栈中弹出(POP)一个元素时,变量T的值C 。设栈空时,有输入序列a,b,c,经过PUSH,POP,PUSH,PUSH,POP操作后,从栈中弹出的元素的序列是D ,变量T的值是E 。 • 供选择的答案:A: ① 先进先出 ②后进先出 ③进优于出 ④出优于进 ⑤ 随机进出 • B,C: ① 加1 ②减1 ③不变 ④清0 ⑤ 加2 ⑥减2 • D:① a,b ②b,c ③c,a ④b,a ⑤ c,b ⑥ a,c • E:① n+1 ②n+2 ③ n ④ n-1 ⑤ n-2 • ABCDE=2, 2, 1, 6, 4
在做进栈运算时,应先判别栈是否A ;在做退栈运算时,应先判别栈是否B 。当栈中元素为n个,做进栈运算时发生上溢,则说明该栈的最大容量为C 。 • 为了增加内存空间的利用率和减少溢出的可能性,由两个栈共享一片连续的内存空间时,应将两栈的D 分别设在这片内存空间的两端,这样,只有当E 时,才产生上溢。 • 供选择的答案:A,B:①空 ② 满 ③ 上溢 ④ 下溢 • C: ①n-1 ② n ③ n+1 ④ n/2 • D: ① 长度 ②深度 ③ 栈顶 ④ 栈底 • E:①两个栈的栈顶同时到达栈空间的中心点 ②其中一个栈的栈顶到达栈空间的中心点 • ③两个栈的栈顶在达栈空间的某一位置相遇 ④两个栈均不空,且一个栈的栈顶到达另一个栈的栈底 • ABCDE=2, 1, 2, 4, 3
O(n) O(m*n) • 从一维数组a[n]中顺序查找出一最大值元素的时间复杂度为( ),输出一个二维数组b[m][n]中所有元素的时间复杂度为( ) • 在顺序表中插入和删除一个结点需平均移动多少个结点?具体的移动次数取决于哪两个因素? 答:在等概率情况下,顺序表中插入一个结点需平均移动n/2个结点。删除一个结点需平均移动(n-1)/2个结点。具体的移动次数取决于顺序表的长度n以及需插入或删除的位置i。i越接近n则所需移动的结点数越少。
何时选用顺序表、何时选用链表作为线性表的存储结构为宜?何时选用顺序表、何时选用链表作为线性表的存储结构为宜? 答:1.基于空间的考虑。当要求存储的线性表长度变化不大,易于事先确定其大小时,为了节约存储空间,宜采用顺序表;反之,当线性表长度变化大,难以估计其存储规模时,采用动态链表作为存储结构为好。2.基于时间的考虑。若线性表的操作主要是进行查找,很少做插入和删除操作时,采用顺序表做存储结构为宜;反之, 若需要对线性表进行频繁地插入或删除等的操作时,宜采用链表做存储结构。并且,若链表的插入和删除主要发生在表的首尾两端,则采用尾指针表示的单循环链表为宜。
为什么在单循环链表中设置尾指针比设置头指针更好?为什么在单循环链表中设置尾指针比设置头指针更好? 答:尾指针是指向终端结点的指针,用它来表示单循环链表可以使得查找链表的开始结点和终端结点都很方便,设一带头结点的单循环链表,其尾指针为rear,则开始结点和终端结点的位置分别是rear->next->next 和 rear, 查找时间都是O(1)。 若用头指针来表示该链表,则查找终端结点的时间为O(n)。
在单链表、双链表和单循环链表中,若仅知道指针p指向某结点,不知道头指针,能否将结点*p从相应的链表中删去?若可以,其时间复杂度各为多少? 答:我们分别讨论三种链表的情况。1. 单链表。当我们知道指针p指向某结点时,能够根据该指针找到其直接后继,但是由于不知道其头指针,所以无法访问到p指针指向的结点的直接前趋。因此无法删去该结点。 2. 双链表。由于这样的链表提供双向链接,因此根据已知结点可以查找到其直接前趋和直接后继,从而可以删除该结点。其时间复杂度为O(1)。3. 单循环链表。根据已知结点位置,我们可以直接得到其后相邻的结点位置(直接后继),又因为是循环链表,所以我们可以通过查找,得到p结点的直接前趋。因此可以删去p所指结点。其时间复杂度应为O(n)。
下述算法的功能是什么?LinkList Demo(LinkList L){ // L 是无头结点单链表ListNode *Q,*P; if(L&&L->next){ Q=L;L=L->next; P=L; while (P->next) P=P->next; P->next=Q; Q->next=NULL; } return L; }// Demo 答:将开始结点摘下链接到终端结点之后成为新的终端结点,而原来的第二个结点成为新的开始结点,返回新链表的头指针。
链栈中为何不设置头结点? 答:链栈不需要在头部附加头结点,因为栈都是在尾部进行操作的,如果加了头结点,等于要对头结点之后的结点进行操作,反而使算法更复杂,所以只要有链表的头指针就可以了。
循环队列的优点是什么? 如何判别它的空和满? 答:循环队列的优点是:它可以克服顺序队列的“假溢出”现象,能够使存储队列的向量空间得到充分的利用。判别循环队列的“空”或“满”不能以头尾指针是否相等来确定,一般是通过以下几种方法: 一是另设一变量来区别队列的空和满。二是少用一个元素的空间。每次入队前测试入队后头尾指针是否会重合,如果会重合就认为队列已满。三是设置一计数器记录队列中元素总数,不仅可判别空或满,还可以得到队列中元素的个数。
设数组data[m]作为循环队列SQ的存储空间,front为队头指针,rear为队尾指针,则执行出队操作后其头指针front值为( ) A.front=front+1 B.front=(front+1)%(m-1) C.front=(front-1)%m D.front=(front+1)%m D
设长度为n的链队用单循环链表表示,若设头指针,则入队出队操作的时间为何? 若只设尾指针呢? 答:当只设头指针时,出队的时间为1,而入队的时间需要n,因为每次入队均需从头指针开始查找,找到最后一个元素时方可进行入队操作。若只设尾指针,则出入队时间均为1。因为是循环链表,尾指针所指的下一个元素就是头指针所指元素,所以出队时不需要遍历整个队列。
在一个带头结点的单循环链表中,p指向尾结点的直接前驱,则指向头结点的指针head可用p表示为head=_____。 • p->next->next
数组Q[n]用来表示一个循环队列,f为当前队列头元素的前一位置,r为队尾元素的位置,假定队列中元素的个数小于n,计算队列中元素的公式为 (A)r-f; (B)(n+f-r)% n; (C)n+r-f; (D)(n+r-f)% n D
为了提高内存的利用效率,减少溢出机会,可以让两个栈共享一段连续内存空间,应如何设置两个栈?为了提高内存的利用效率,减少溢出机会,可以让两个栈共享一段连续内存空间,应如何设置两个栈? • 栈底分别设在内存的两端
设有编号为1,2,3,4的四辆列车,顺序进入一个栈式结构的车站,具体写出这四辆列车开出车站的所有可能的顺序。 • ① 全进之后再出情况,只有1种:4,3,2,1 • ② 进3个之后再出的情况,有3种,3,4,2,1 3,2,4,1 3,2,1,4 • ③ 进2个之后再出的情况,有4种,2,4,3,1 2,3,4,1 2,1, 3,4 2,1,4,3 • ④ 进1个之后再出的情况,有5种,1,4,3,2 1,3,2,4 1,3,4,2 1, 2,3,4 1,2,4,3
设有一个顺序栈S,元素s1, s2, s3, s4, s5, s6依次进栈,如果6个元素的出栈顺序为s2, s3, s4, s6, s5, s1,则顺序栈的容量至少应为多少? • 3
指出下述程序段的功能是什么? • void Demo1(SeqStack *S){ int i; arr[64] ; n=0 ; while ( !StackEmpty(S)) arr[n++]=Pop(S); for (i=0, i< n; i++) Push(S, arr); } 答:程序段的功能是将一栈中的元素按反序重新排列,也就是原来在栈顶的元素放到栈底,栈底的元素放到栈顶。此栈中元素个数限制在64个以内。
SeqStack S1, S2, tmp; DataType x; ...//假设栈tmp和S2已做过初始化while ( ! StackEmpty (&S1)) { x=Pop(&S1) ; Push(&tmp,x); } while ( ! StackEmpty (&tmp) ) { x=Pop( &tmp); Push( &S1,x); Push( &S2, x); } 答:程序段的功能是利用tmp栈将一个非空栈的所有元素按原样复制到一个空栈当中去。
void Demo2( SeqStack *S, int m) { // 设DataType 为int 型SeqStack T; int i; InitStack (&T); while (! StackEmpty( S)) if(( i=Pop(S)) !=m) Push( &T,i); while (! StackEmpty( &T)) { i=Pop(&T); Push(S,i); } } 答:程序段的功能是将一个非空栈中值等于m的元素全部删去 。
void Demo3( CirQueue *Q) { // 设DataType 为int 型int x; SeqStack S; InitStack( &S); while (! QueueEmpty( Q )) {x=DeQueue( Q); Push( &S,x);} while (! StackEmpty( &s)) { x=Pop(&S); EnQueue( Q,x );} }// Demo3 答:程序段的功能是将一个循环队列反向排列,原来的队头变成队尾,原来的队尾变成队头。
CirQueue Q1, Q2; // 设DataType 为int 型int x, i , m = 0; ... // 设Q1已有内容, Q2已初始化过 while ( ! QueueEmpty( &Q1) ) { x=DeQueue( &Q1 ) ; EnQueue(&Q2, x); m++;} for (i=0; i< m; i++) { x=DeQueue(&Q2) ; EnQueue( &Q1, x) ; EnQueue( &Q2, x);} 答:这段程序的功能是将队列1的所有元素复制到队列2中去,但其执行过程是先把队列1的元素全部出队,进入队列2,然后再把队列2的元素复制到队列1中。
假设有如下的串说明:char s1[30]="Stocktom,CA", s2[30]="March 5 1999", s3[30];int p; (1)在执行如下的每个语句后p的值是什么? p=index(s1,'t‘,2); p=index(s2,'9‘,1); p=index(s2,'6‘,1); 答:index(*s,*c,pos)函数的功能是查找在串s第pos个字符后第一次出现串c的位置,若找到,则返回该位置,否则返回NULL。因此:执行p=index(s1,'t‘,1);后p的值是指向字符t的位置, 也就是p=6。执行p=index(s2,'9‘,1);后p的值是指向s2串中第一个9所在的位置,也就是p=10。执行p=index(s2,'6‘,1);之后,p的返回值是0 。
假设有如下的串说明:char s1[30]="Stocktom,CA", s2[30]="March 5 1999", s3[30];int p; 在执行下列语句后,s3的值是什么? strcpy(s3,s1); strcat(s3,","); strcat(s3,s2); 答:strcpy函数功能是串拷贝,strcat函数的功能是串联接。所以:在执行strcpy(s3,s1); 后,s3的值是"Stocktom,CA"在执行strcat(s3,","); 后,s3的值变成"Stocktom,Ca,"在执行完strcat(s3,s2);后,s3的值就成了"Stocktom,Ca,March 5,1999"
假设有如下的串说明:char s1[30]="Stocktom,CA", s2[30]="March 5 1999", s3[30];int p; 调用函数strcmp(s1,s2)的返回值是什么? 答:函数strcmp(串1,串2)的功能是串比较,按串的大小进行比较,返回大于0,等于0或小于0的值以表示串1比串2 大,串1等于串2 ,串1小于串2。因此在调用函数strcmp(s1,s2)后,返回值是大于0的数(字符比较是以ascii码值相比的)
假设有如下的串说明:char s1[30]="Stocktom,CA", s2[30]="March 5 1999", s3[30];int p; 调用函数strcmp(&s1[5],"ton")的返回值是什么? 答:首先,我们要知道&s1[5]是一个地址,当放在函数strcmp中时,它就表示指向以它为首地址的一个字符串,所以在strcmp( &s1[5],"ton")中,前一个字符串值是"tom,CA",用它和"ton"比较,应该是后者更大,所以返回值是小于0的数。
假设有如下的串说明:char s1[30]="Stocktom,CA", s2[30]="March 5 1999", s3[30];int p; 调用函数strlen(strcat(s1,s2))的返回值是什么? 答:strlen是求串长的函数,我们先将s1,s2联接起来,值是"Stocktom,CAMarch 5,1999",数一数有几个字符,返回值是23 。
若目标串的长度为n,模式串的长度为[n/3],则执行模式匹配算法时,在最坏情况下的时间复杂度是( )若目标串的长度为n,模式串的长度为[n/3],则执行模式匹配算法时,在最坏情况下的时间复杂度是( ) A.O(1 ) B.O(n) C.O(n2) D.O(n3) C
设串s1=’ABCDEFG’,s2=’PQRST’,函数con(x,y)返回x和y串的连接串,subs(s, i, j)返回串s的从序号i开始的j个字符组成的子串,len(s)返回串s的长度,则con(subs(s1, 2, len(s2)), subs(s1, len(s2), 2))的结果串是: • A.BCDEF B.BCDEFG C.BCPQRST D.BCDEFEF • D
假设有二维数组A6×8,每个元素用相邻的6个字节存储,存储器按字节编址。已知A的起始存储位置(基地址)为1000,则数组A的体积(存储量)为;末尾元素A57的第一个字节地址为;若按行存储时,元素A14的第一个字节地址为;若按列存储时,元素A47的第一个字节地址为。 288 B 1282 (8+4)×6+1000=1072 (6×7+4)×6+1000)=1276
设数组a[1…60, 1…70]的基地址为2048,每个元素占2个存储单元,若以列序为主序顺序存储,则元素a[32,58]的存储地址为___________________ • 三元数组表中的每个结点对应于稀疏矩阵的一个非零元素,它包含有三个数据项,分别表示该元素的、和。 [(58-1)*60+(32-1)]*2+2048=8950 行下标 列下标 元素值
二维数组M的成员是6个字符(每个字符占一个存储单元)组成的串,行下标i的范围从0到8,列下标j的范围从1到10,则存放M至少需要( )个字节;M的第8列和第5行共占( )个字节;若M按行优先方式存储,元素M[8][5]的起始地址与当M按列优先方式存储时的( )元素的起始地址一致。 • A.90 B.180 C.240 D.540 • A.108 B.114 C.54 D.60 • A.M[8][5] B.M[3][10] C.M[5][8] D.M[0][9] • 答案:D A B
数组A中,每个元素A的长度为3个字节,行下标i从1到8,列下标j从1到10,从首地址SA开始连续存放在存储器内,该数组按行存放时,元素A[8][5]的起始地址为( ) • A.SA+141 B.SA+144 C.SA+222 D.SA+225 • C
稀疏矩阵一般的压缩存储方式有两种,即( ) 答案:三元组和十字链表 有一个10阶对称矩阵A,采用压缩存储方式(以行序为主存储,且A[0][0]=1),则A[8][5]的地址是 () 答案:42
若采用三元组压缩技术存储稀疏矩阵,只要把每个元素的行下标和列下标互换,就完成了对该矩阵的转置运算,这种观点( ) • A.正确 B.错误 • B
C C B C • 1.广义表((a),a)的表头是( ),表尾是( ). • A. a B. b C. (a) D. ((a)) • 2.广义表((a))的表头是( ),表尾是( ). • A. a B. (a) C. ( ) D. ((a)) • 3.广义表((a,b),c,d)的表头是( ),表尾是( ). • A. a B. b C. (a,b ) D. (c,d) • 4 .广义表(a,b,c,d)的表头是( ),表尾是( ). • A. a B. b C. (a,b ) D. (b,c,d) • 5. 广义表((a,b,c,d))的表头是( ),表尾是( ). • A. a B. ( ) C. (a,b,c,d ) D. ((a,b,c,d)) • 6.一个广义表的表头是一个广义表,这个断言是( ). • A. 正确的 B. 错误的 • 7. 一个广义表的表尾是一个广义表,这个断言是( ). • A. 正确的 B. 错误的 C D A D C B B A
利用广义表的head和tail操作写出函数表达式,把以下各题中的单元素banana从广义表中分离出来:利用广义表的head和tail操作写出函数表达式,把以下各题中的单元素banana从广义表中分离出来: • (1) L1(apple, pear, banana, orange) • (2) L2((apple, pear), (banana, orange)) • (3) L3(((apple), (pear), (banana), (orange))) • (4) L4((((apple))), ((pear)), (banana), orange) • (5) L5((((apple), pear), banana), orange) • (6) L6(apple, (pear, (banana), orange))
L1(apple, pear, banana, orange) T(L1) L(pear,banban,orange) T(L) L(banana,orange) H(L) banana H(T(T(L1)))
L2((apple, pear), (banana, orange)) • T(L2) L( (banana,orange)) • H(L) L(banana,orage) • H(L) banana • H(H(T(L2)))
L3(((apple), (pear), (banana), (orange))) • H(L3) L((apple),(pear),(banana),(orange)) • T(L) L((pear),(banana),(orange)) • T(L) L((banana),(orange)) • H(L) L(banana) • H(L) banana • H(H(T(T(H(L3)))))
L4((((apple))), ((pear)), (banana), orange) • T(L4) L(((pear)),(banana),orange) • T(L) L((banana),orange) • H(L) L(banana) • H(L) banana • H(H(T(T(L4))))
L5((((apple), pear), banana), orange) • H(L5) L(((apple),pear),banana) • T(L) L(banana) • H(L) banana • H(T(H(L5)))
(6) L6(apple, (pear, (banana), orange)) • T(L6) L((pear,(banana),orange)) • H(L) L(pear,(banana),orange) • T(L) L((banana),orange) • H(L) L(banana) • H(L) banana • H(H(T(H(T()))))
C • 如图的4棵树二叉树中,( )不是完全二叉树。 • A B C D
B • 在线索化二叉树中,t所指结点没有左子树的充要条件是( ) • A. t->left=NULL B. t->ltag=1 • C.t->ltag=1且t->left=NULL D.以上都不对 • 二叉树按某种顺序线索化后,任意结点均有指向其前驱和后继的线索,这种说法( ) • A. 正确 B. 错误 • 用二叉链表法存储包含 n 个结点的二叉树,结点的 2n 个指针区域中有 n+1 个为空指针。 • A. 正确 B. 错误 B A