跳转至

2019-2020-1 数据结构 期末试卷

2018级

科目: 数据结构 主讲教师: 胡卉芪 出卷人: 胡卉芪

一、选择题(8分)

(1)以下说法正确的是()

A 每个函数至少要有一个参数 B 每个函数都必须返回一个值

C 函数在被调用之前必须先声明 D 函数不能自己调用自己

(2)下列关于对象初始化的叙述中,正确的是()

A 定义对象的时候不能对对象进行初始化

B 可以为一个对象多次调用构造函数初始化

C 定义对象时将自动调用构造函数进行初始化

D 在一个类中必须显式地定义构造函数实现初始化

(3)对类成员访问权限的控制,是通过设置成员的访问控制属性实现的,下列不是访问控制属性的是( )

A 公有类型 B私有类型 C 保护类型 D友元类型

(4)下列关于基类和派生类关系的叙述中,正确的是 ( )

A 每个类最多只能有一个直接基类

B 派生类中的成员可以访问基类中的任何成员

C 基类的构造函数必须在派生类的构造函数体中调用

D 派生类除了继承基类的成员,还可以定义新的成员

二、请写出程序运行的结果 (6分)

#include<iostream> 
using namespace std; 
class base{
public: 
    virtual void print() const { cout<<"base::f()"<<endl; } 
};
class derived: public base { 
public: 
    virtual void print() const { cout<<"derived::f()"<<endl;}
}; 
void print(const base& obj) 
{ 
    obj.print(); 
} 
int main() 
{ 
  base* pb1=new derived(); 
  print(*pb1); 
  base* pb2=new base(*pb1); 
  print(*pb2); 
  base b; 
  print(b);
  delete pb1; 
  delete pb2; 
  return 0; 
} 

三、请指出下述C++代码中三处语法或执行时的错误,每个指出的错误简述可能的解决方案, 并填入下述表格的错误1-3中(多写不加分)。(9分)

#include <stdio.h>
#include <string.h>
class CBuffer
{
    char * m_pBuffer;
    int m_size;
public:
    CBuffer()
    {
        m_pBuffer = NULL;
    }
    ~CBuffer()
    {
        Free();
    }
    void Allocte(int size){
        m_size = size;
        m_pBuffer = new char[size];
    }
private:
    void Free()
    {
            delete m_pBuffer;
            m_pBuffer = NULL;
    }
public:
    void SaveString(const char* pText) const
    {
        strcpy(m_pBuffer, pText);
        m_size = sizeof(pText);
    }
    char* GetBuffer() const
    {
        return m_pBuffer;
    }
};
int main(int argc, char* argv[])
{
    CBuffer buffer1;
    CBuffer buffer2(buffer1);
    buffer1.SaveString("Microsoft");
    printf (buffer1.GetBuffer());   
    return 0;
}

错误 类型 错误描述 改正方法
错误1
错误2
错误3

四、 栈和队列 (6分)

给出栈采用顺序存储(数组存储),在栈的存储结构中如何判别栈空与栈满?

设top用来存放栈顶元素的下标。 S->top表示栈顶。 数组大小为Stack_Size。 必要时可以引入栈内元素个数, S->count。

(1) 判断栈S空:

(2) 判断栈S满:

五、 迷宫问题 (8分)

用下述二维数组matrix[][]描述迷宫,初始时其中-1表示迷宫的墙, 0表示没有墙,可通行。现在起点在src位置,终点在des位置 (src位置的值为1, des位置的值为0)。

1 (src) -1 -1 -1 0
0 -1 -1 0 0
0 0 -1 -1 0
0 0 0 0 0
0 -1 -1 -1 0 des

现在Pos src为起点, 通过调用DFS(src, 1) 函数, 请画出完整执行后的迷宫数组,填写在下面。 代码中Pos是一个结构体:

struct Pos {
    int row; //表示数组的行
    int col; //表示数组的列
};
void DFS(Pos cur, int step) {
    //迷宫终点找到
    if (cur.row ==4 && cur.col == 4) {      
return;
    }
    //按照左,上,右,下的顺序探索迷宫
    int dir[4][2] = {{0,-1},{-1,0},{0,1},{1,0}}; 
    Pos next;
    for (int z = 0; z < 4; z++) {
        next.row = cur.row + dir[z][0];
        next.col = cur.col + dir[z][1];
         if (matrix[cur.row][cur.col] == 0) {
            matrix[next.row][next.col] = step + 1;
            DFS_(next, step + 1);
         }
    }
}

待填写的二维数组:

六、 排序,二分查找 (7分)。

设有一组序列为(13,90,83,50,35,47,18,24,62)

1、给出第四趟的插入排序的结果:

2、排序完成之后,采用二分查找的方法,要求计算出查找关键字62时的比较次数。

七、 二叉排序树 (8分)。

已知二叉排序树由八个连续整数1-8组成,先序,后序遍历序列分别为

先序:4,2,1,3,5,8,6,7

后序:1,3,2,7,6,8,5,4

(1)画出二叉排序树的逻辑结构。

image-20260429143635865

(2)画出删除节点4后的二叉排序树的逻辑结构。

image-20260429143711620

八、堆(9分)。

现有一个以数组存储的完全二叉树:{15,9,7,8,20,1,5,4}。

(1)画出对应的完全二叉树。

image-20260429143756988

(2)通过堆构建的方法,将该完全二叉树调整成一个小顶堆,画出该小顶堆。

image-20260429143834910

(3)利用小顶堆堆排序的方法对数组进行降序排序,写出第二趟排序后数组的存储序列。(提示,小顶堆每次产生的最小值会放到数组末尾)

15,8,5,9,20,7,4,1 或 5,8,7,9,20,15,4,1

九、图(12分)。

给定一个无向带权图的邻接表:

image-20260429143924222

(1)画出该无向带权图。

image-20260429144006827

(2)从指定节点A开始,按照邻接表中的访问顺序,写出广度优先遍历序列。

A,B,C,D,E,F,G;

(3)从指定节点A开始,画出按prim算法求得的最小生成树。

image-20260429144051715

十(7分)

已知两个长度为n的数组,分别存放两个升序的序列,现通过对换两个数组中的成员对两个数组进行调整,要求调整后两个序列仍然各自升序,且第一个序列的最后一个元素小于等于第二个序列的第一个元素。 例如,

第一个数组为 4, 12, 28

第二个数组为 1, 9 , 29

输出为

第一个数组 1, 4, 9

第二个数组 12,28,29

(1)排除这两个数组本身,设计空间复杂度 O(n)的算法实现上述功能。

(2) 排除这两个数组本身,设计空间复杂度O(1)的算法实现上述功能。

十一(8分)

程序设计题1.给定两个单链表,它们相同的节点定义如下:

struct Node
{
Elemtype data;
Node *next;
};

判断该这两个单链表中是否交汇,交汇的例子如下图所示,即在某个节点两个链表归并为同一个链表。

image-20260429144205098

如果有,找到相交的节点。按照下列给出的接口和输入输出用伪代码实现相应功能。允许增加函数,也允许使用其他的数据结构,但请做详尽解释。

接口: Node* findLoopStart(Node *h1, Node *h2); 输入:指向链表头节点的指针h1和h2, h1, h2相当于两个链表的第一个节点,并且它们一定都不为空;输出:如果相交,返回相交节点的指针,否则返回NULL。

十二、程序设计题2(12分)

给定一棵二叉树BT,树中节点定义如下:

struct BTNode 
{
Elemtype data;
BTNode *lchild;
BTNode *rchild;
};

假设该二叉树已经构建好,root是指向BT根节点的指针,请按照下列给出的接口和输入输出用伪代码实现相应功能。允许增加函数,也允许使用其他的数据结构,但请做详尽解释。

(1)求BT中节点的最大距离,即BT中相距最远的两个节点之间的距离。接口:

int GetMaxDistance(root); 输入:指向BT根节点的指针root;输出:BT中相距最远的两个节点之间的距离。

int GetMaxDistance(root)
{
     int left_depth,right_depth;
     GetMaxDistance_2(root,left_depth,right_depth);
}

int GetMaxDistance_2(root,left_depth,right_depth)
{
     int ll_depth,lr_depth,rl_depth,rr_depth;
     int left_maxdist,right_maxdist;

     if(root == NULL)
     {  left_depth = 0;
        right_depth = 0;
        return 0;
     }

     left_maxdist = GetMaxDistance_2(root->lchild,ll_depth,lr_depth);
     left_depth = max(ll_depth,lr_depth);

     right_maxdist = GetMaxDistance_2(root->rchild,rl_depth,rr_depth);
     right_depth = max(rl_depth,rr_depth);

     return max(max(left_maxdist,right_maxdist),left_depth+right_depth);
}

(2)假设有一颗空的二叉树BT_copy,根节点指针为root_copy, 请将二叉树BT复制到BT_copy。接口:void CopyBTree(root,root_copy); 输入:指向BT根节点的指针root和指向BT_copy根节点的指针root_copy; 输出:无返回值。

void CopyBTree(root, root_copy)
{
    if(root==NULL)
       return;
    else{
       root_copy=(BTNode)malloc(sizeof(BTNode));
       root_copy->data=root->data;
       CopyBTree(root->lchild,root_copy->lchild);
       CopyBTree(root->rchild,root_copy->rchild);
     }   
}