《数据结构》试题 (B卷) 一、单选题 [从供选择的答案中选出正确的答案,将其编号填入下列叙述中的( )内](每小题3分,共24分) (1) 向一个有127个元素的顺序表中插入一个新元素并保持原来顺序不变,平均要移动( A )个元素。 (2) 设有一个二维数组A[m][ n],假设A[0][0] 存放位置在644(10),A[2][2]存放位置在676(10),每个元素占一个空间,则A[4][5] 在( B )位置,(10)表明用10进数表示。 (3) 一个有序顺序表有255个对象,采用顺序搜索法查表, 平均搜索长度为( C )。 (4) 含5个结点(元素值均不相同)的二叉搜索树有( D )种。 (5) 在分析折半搜索的性能时常加入失败结点,即外结点,从而形成扩充的二叉树。若设失败结点i所在层次为li,那么搜索失败到达失败结点时所做的数据比较次数是( E )。 (6) 设有一个含200个表项的散列表,用线性探查法解决冲突,按关键码查询时找到一个表项的平均探查次数不超过1.5,则散列表项应能够至少容纳( F )个表项。(设搜索成功的平均搜索长度为 Snl={ 1 + 1 / (1 -α) } / 2, 其中α为装填因子) (7) n个顶点的连通图至少有( G )条边。 (8) 一个二叉树按顺序方式存储在一个一维数组中, 如图 0  1  2  3  4  5  6  7  8  9  10  11  12  13  14   A  B  C  D   E  F   G    H   I  J  则结点E在二叉树的第( H )层。 【供选择的答案】 A : ( 8 ( 63.5 ( 63 ( 7 B : ( 692(10) ( 626(10) ( 709(10) ( 724(10) C : ( 128 ( 127 ( 126 ( 255 D : ( 54 ( 42 ( 36 ( 65 F : ( li +1 ( li +2 ( li - 1 ( li G : ( 400 ( 526 ( 624 ( 676 I : ( n-1 ( n ( n+1 ( 0 J : ( 1 ( 2 ( 3 ( 4 二、阅读理解题 [说明下列递归过程的功能] (10分) int unknown ( BinTreNode * t ) { ////指针t是二叉树的根指针。 if ( t == NULL ) return 0; else if ( t→leftChild == NULL && t→rightChild == NULL ) return 1; else return unknown ( t→leftChild ) + unknown ( t→rightChild ); } 三、简答题 (每小题10分,共30分) 1、如下所示的连通图,请画出 (1) 以顶点①为根的深度优先生成树; (5分) (2) 如果有关节点,请找出所有的关节点。 (5分)  2、设有13个初始归并段,其长度分别为28,16,37,42,5,9,13,14,20,17,30,12,18。试画出4路归并时的最佳归并树,并计算它的带权路径长度WPL。 3、设散列表为HT[0..12],即表的大小为m = 13。采用双散列法解决冲突。散列函数和再散列函数分别为: H0( key ) = key % 13; 注:%是求余数运算(= mod ) Hi = ( Hi-1 + REV ( key + 1) % 11 + 1) %13; i = 1, 2, 3, (, m-1 其中,函数REV(x)表示颠倒10进制数x的各位,如REV(37) = 73,REV(7) = 7等。若插入的关键码序列为{ 2, 8, 31, 20, 19, 18, 53, 27 }。试画出插入这8个关键码后的散列表。 四、综合算法题 有一种简单的排序算法,叫做计数排序(count Sorting)。这种排序算法对一个待排序的表(用数组表示)进行排序,并将排序结果存放到另一个新的表中。必须注意的是,表中所有待排序的关键码互不相同。计数排序算法针对表中的每个记录,扫描待排序的表一趟,统计表中有多少个记录的关键码比该记录的关键码小。假设针对某一个记录,统计出的计数值为c,那么,这个记录在新的有序表中的合适的存放位置即为c。 (1) 给出适用于计数排序的数据表定义; (4分) (2) 使用C++ 语言编写实现计数排序的算法; (10分) (3) 对于有n个记录的表,关键码比较次数是多少? (4分) 五、填空题 下面给出的是一个在二叉树中查找值为x的结点,并打印该结点所有祖先结点的算法。在此算法中,假设值为x的结点不多于一个。此算法采用后序的非递归遍历形式。因退栈时需要区分其左、右子树是否已经遍历,故在结点进栈时附带有一个标志,=0,进入左子树,=1,进入右子树。用栈ST保存结点指针ptr及其标志tag。top是栈顶指针。 void print ( BinTreeNode * t; Type &x ) { stack ST; int i, top; top = 0; //置空栈 while ( t != NULL && t→data != x || top != 0 ) { while ( t != NULL && t→data != x ) { //寻找值为x的结点 ① ;   ST [top].ptr = t; //进栈 ST [top].tag = 0; ② ;  } if ( t != NULL && t→data == x ) //找到值为x的结点 for ( i = 1;  ③ ; i++ )  cout << ST[i].ptr→data << endl; else { while ( top > 0 && ST [top].tag == 1 ) //未找到值为x的结点 top--; if ( top > 0 ) { ST [top].tag = 1; //转向右子树 ④ ;  } } } } /*print*/  (1) 请将缺失的语句补上 (8分) ( ( ( ( (2) 请给出对于右图所示的二叉树,使用上述算法搜索值为9的结点和值为10的结点的结果,以及在栈ST中的变化。(top是栈顶指针) (10分) 试题解答 一、单选题 【解答】 A : ( B : ( C : ( D : ( E : ( F : ( G : ( H : ( 二、阅读理解题 [说明下列递归过程的功能] 【解答】 计算二叉树的叶结点的个数。 三、简答题 1、【解答】 (1) 该连通图从①出发做深度优先搜索,得到的深度优先生成树为:  结果不唯一 (2) 关节点为①、②、③、⑦、⑧ 2、【解答】 答案是否定的。举个反例:看下图粗线所示的路径 S1 = { 15 }, S2 = { 25, 30, 35, 40 }, S3 = { 40, 50, 65, 70 } 40 ( S3,45 ( S2,45< 40不成立。 3、【解答】 因为 (13 - 1) % (4 - 1) = 12 % 3 = 0,所以不需要添加空段。最佳归并树为  WPL = ( 5 + 9 + 13 + 12 + 16 + 14 + 17 + 18 + 28 + 37 + 20 + 30 ) * 2 + 42 = 480 4、【解答】 散列表 HT[0..12],散列函数与再散列函数为 H0( key ) = key mod 13; Hi = ( Hi-1 + REV ( key + 1 ) mod 11 + 1 ) mod 13; 插入关键码序列为 { 2, 8, 31, 20, 19, 18, 53, 27 } H0( 2 ) = 2, 比较次数为1 H0( 8 ) = 8, 比较次数为1 H0( 31 ) = 5, 比较次数为1 H0( 20 ) = 7, 比较次数为1 H0( 19 ) = 6, 比较次数为1 H0( 18 ) = 5, 冲突,H1 = 9,比较次数为2 H0( 53 ) = 1,比较次数为1 H0( 27 ) = 1,冲突,H1 = 7,冲突,H2 = 0,比较次数为3 插入8个关键码后的散列表 0 1 2 3 4 5 6 7 8 9 10 11 12  27 53  2   31 19 20  8 18      四、综合算法题 (1) 数据表定义 【解答】 const int DefaultSize = 100; template <class Type> class datalist //数据表的前视声明 template <class Type> class Element { //数据表元素类的定义 private: Type key; //关键码 field otherdata; //其它数据成员 public: Type getKey ( ) { return key; } //取当前结点的关键码 void setKey ( const Type x ) { key = x; } //将当前结点的关键码修改为x } template <class Type> class datalist { //用顺序表来存储待排序的元素,这些元素的类型是Type public: datalist ( int MaxSz = DefaultSize ) : MaxSize ( Maxsz ), CurrentSize (0) { Vector = new Element <Type> [MaxSz]; } private: Element <Type> * Vector; //存储待排序元素的向量 int MaxSize, CurrentSize; //最大元素个数与当前元素个数 } (2) 计数排序的算法 【解答1】 template <class Type> void countsort ( datalist<Type> & initList, datalist<Type> & resultList ) { int i, j, c; Type refer; for ( i = 0; i < initList.CurrentSize; i++ ) { c = 0; refer := initList.Vector[i].getKey ( ); for ( j = 0; j < initList.CurrentSize; j++ ) if (initList.Vector[j].getKey ( ) < refer ) c++; resultList.Vector[c] = initList.Vector[i] } resultList.CurrentSize = initList.CurrentSize; } 【解答2】 template <class Type> void countsort ( datalist<Type> & initList, datalist<Type> & resultList ) { int *c = new int[initList.CurrentSize]; for ( int i = 0; i < initList.CurrentSize; i++ ) c[i] = 0; for ( i = 0; i < initList.CurrentSize-1; i++ ) for ( int j = i+1; j < initList.CurrentSize; j++ ) if (initList.Vector[j].getKey ( ) < initList.Vector[i].getKey ( ) ) c[i]++; else c[j]++; for ( i = 0; i < initList.CurrentSize; i++ ) resultList.Vector[ c[i] ] = initList.Vector[i]; resultList.CurrentSize = initList.CurrentSize; } (3) 对于n个记录的表,【解答1】关键码比较次数为n2,【解答2】关键码比较次数为n(n-1)/2。 五、填空题 【解答】 (1) 请将缺失的语句补上 ( top++ ( t = t→leftChild ( i <= top ( t = ST[top].ptr→rightChild  (2) 搜索值为9的结点          → ( 0  → ( 0  ( 1   ( 0  ( 0   ( 0  ( 0   ptr tag ptr tag 搜索值为10的结点   → ( 0 → ( 1               ( 0  ( 0 → ( 1        → ( 0  ( 1  ( 1  ( 1    → ( 0   ( 0  ( 0  ( 0  ( 0 → ( 1  ( 0   ( 0  ( 0  ( 0  ( 0  ( 0  ( 1   ptr tag ptr tag ptr tag ptr tag ptr tag ptr tag                → ( 0 → ( 1            ( 1  ( 1 → ( 0 → ( 1      ( 0  ( 0  ( 1  ( 1      ( 1  ( 1  ( 1  ( 1      ptr tag ptr tag ptr tag ptr tag ptr tag