考研数据结构大题整合
四、LB组
LB组一
四、 (1) (8分)
一个5*4的整型矩阵(行优先)在存储器中的排列如下:0,4,0,3,0,6,0,0,0,0,0,0,0,2,0,0,1,0,5,0,写出这一矩阵,再用三元组形式表示。设计一个时间复杂性为O(n+t)的算法(其中n表示矩阵的列数,t表示非零元素个数),把三元组表示的矩阵转置,结果仍用三元组表示。写出此例子的转置过程。
(2)画出下图从结点1开始的深度优先生成树和广度优先生成树:(7分)
深度优先序列:
广度优先序列:
(3)写出下面广义表的存储结构示意图: F= ( a, b, ( c, ( ( d ) ) ), e, F ) (7分)
(4)用给出的一组权值{4,2,3,5,7,8,1},建立一棵哈夫曼树。(8分)
五、 (1) 读程序: 4分
void reverse(int n)
{
if (n > 0)
{
cout << n % 10;
reverse(n / 10);
}
else
cout << endl; // 递归出口
}
此函数的功能是:_________
调用语句reverse(69)的结果是:__________
reverse(1234)的结果是 _____________
(2)快速排序:对a[low]…a[high]的元素按关键码降序排序 6分
void QuickSort(Datatype a[], int low, int high)
{
int i = low, j = high;
Datatype temp = a[low];
while (i < j)
{
while (i < j && _____________________)
j--;
if (i < j)
a[i++] = a[j];
while (i < j && a[i].key >= temp.key)
_____________________;
if (i < j)
a[j--] = a[i];
}
a[i] = temp;
if (low < i)
QuickSort(a, low, i - 1);
if (i < high)
_____________________;
}
void QuickSort(Datatype a[], int n)
{
QuickSort(a, 0, n - 1);
}
(3)朴素的模式匹配 :6分
int mymatching(char *str, char *t, int start)
// 在主串str中从start位置开始查找与串t的相同的子串,若找到,返回起始下标,若没找到,则返回-1
{
int i = start, j = 0;
while (i < (int)strlen(str) && j < (int)strlen(t))
if (str[i] == t[j])
{
i++;
_________________;
}
else
{
i = ++start;
________________;
}
if (j >= (int)strlen(t))
return (________________);
else
return (-1);
}
(4)简述以下算法的功能:4分
void BB(LNode *s, LNode *q)
{
p = s;
while (p->next != q)
p = p->next;
p->next = s;
}
void AA(LNode *pa, LNode *pb)
{ // pa和pb分别指向单循环链表中的两个结点
BB(pa, pb);
BB(pb, pa);
}
LB组二
四、 (1)设二叉树BT的根结点指针为6,存储结构如下所示,画出该二叉树的逻辑结构。6分
(2)画出广义表B=(a,(b,©))的链式存储结构图。6分
(3) 设有三对角矩阵(aij)n*n(1<=i,j<=n),将其三条对角线上的元素逐行地存于向量B[1…3n-2]中,使得B[k]=aij,求:
(1) 用i,j表示k的下标变换公式:(3分)
(2) 用k表示i,j的下标变换公式。(6分)
(4)写出堆排序的中间部分过程:(9分)
输入序列是 6,2,1,8,4,9,3,7,5,分别存于r[0]…r[n-1],请在空结点中填入恰当的数:
五、 阅读程序(其中程序填空每格2分)
1. 设G是一个网(带权图),试指出下述算法的功能,输出的序列是G的什么序列?
void Demo(Mgraph G, VertexType u)
{ // G是网的邻接矩阵表示,u为其中的一个顶点
// 记录从顶点集U到V-U的代价最小的边的辅助数组定义:
// struct { VertexType adjvex; // 邻接点
// VRType lowcost; // 权值
// }closedge[MAX_VERTEX-NUM];
k = LocateVex(G, u); // 查找u在G中的序号
for (j = 0; j < G.vexnum; ++j) // 辅助数组初始化
if (j != k)
{
closedge[j].adjvex = u;
closedge[j].lowcost = G.arcs[k][j].adj;
}
closedge[k].lowcost = 0; // 初始,U={u}
for (i = 1; i < G.vexnum; ++i) // 选择其余G.vexnum-1个顶点
{
k = minimum(closedge); // 选择成员lowcost值最小的元素
// 此时,closedge[k].lowcost=MIN{closedge[vi].lowcost | closedge[vi].lowcost>0, vi∈V-U}
printf(closedge[k].adjvex, G.vexs[k]);
closedge[k].lowcost = 0; // 第k个顶点并入U集
for (j = 0; j < G.vexnum; ++j)
if (G.arcs[k][j].adj < closedge[j].lowcost)
{
closedge[j].adjvex = G.vexs[k];
closedge[j].lowcost = G.arcs[k][j].adj;
}
}
}
答:(6分)
2.阅读程序,回答问题并填空:
下面的floyd算法中,distance[i][j]初值为边(i,j)的权重,MaxWeight为一个足够大的数,表示无穷大。
void floyd(AdjMWGraph &g) // AdjMWGraph是用邻接矩阵表示的图的类
{
int i, j, k;
int n = g.NumOfVertices(); // 成员函数NumOfVertices()返回图的结点数目
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
{
path[i][j] = -1;
distance[i][j] = g.GetWeight(i, j);
}
for (k = 0; k < n; k++)
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
{
if (distance[i][k] < MaxWeight && distance[k][j] < MaxWeight &&
(distance[i][k] + distance[k][j]) < distance[i][j])
{
distance[i][j] = distance[i][k] + distance[k][j];
path[i][j] = k;
}
}
}
函数printpath是算法执行之后,用递归方法输出顶点 i 到顶点 j 的最短路径:
void printpath(AdjMWGraph &g, int i, int j)
{
int k = path[i][j];
if (k != -1)
{
__________________;
cout << "-->" << g.GetValue(k); // GetValue(k)返回结点k的名称
__________________;
}
}
问:path[i][j]的值有什么含义?(2分)
3.若已知两棵二叉树B1和B2皆为空,或者皆不空且B1的左、右子树和B2的左、右子树分别相似,则称二叉树B1和B2相似。编写算法,判别给定两棵二叉树是否相似。
int bitree_like(Bitree t1, Bitree t2)
{
if (t1 == NULL && (t2 == NULL))
return (____________________);
if ((t1 != NULL && t2 == NULL) || (t2 != NULL && t1 == NULL))
return (________________);
if (bitree_like(t1->lc, t2->lc))
return (________________);
else
return (________________);
}
LB组三
四、 (1)请对图中所示的二叉树给出其后序线索示意图(5分)和相应的森林示意图。(4分):
(2)找出满足下面条件的所有二叉树:前序序列与中序序列相同。(6分)
(3)画出关键字插入序列为[45,24,53,12,30,6,16,18]的二叉排序树以及在此基础上删除关键字24之后的二叉排序树。(8分)
(4)某无向图的邻接矩阵如下,要求画出该图,另画出一棵最小生成树。(7分)
∞ 3 ∞ 1 6 8 ∞ ∞
3 ∞ 4 ∞ 3 ∞ ∞ ∞
∞ 4 ∞ 2 5 ∞ 9 7
1 ∞ 2 ∞ ∞ ∞ 3 1
6 3 5 ∞ ∞ 2 2 ∞
8 ∞ ∞ ∞ 2 ∞ 8 ∞
∞ ∞ 9 3 2 8 ∞ 4
∞ ∞ 7 1 ∞ ∞ 4 ∞
五、 (1) 读程序: 5分
void Warshall(AdjMWGraph &g) // AdjMWGraph是图的邻接矩阵的类
{
int i, j, k;
int n = g.NumOfVertices(); // NumOfVertices是返回结点数目的成员函数
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
distance[i][j] = g.GetWeight(i, j); // GetWeight返回边(i,j)的权值
for (k = 0; k < n; k++)
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
distance[i][j] = distance[i][j] || distance[i][k] && distance[k][j];
}
distance[i][j]的意义是:
此函数求出图g的什么特性?
(2)整理长度为n的无序线性顺序表(表元素为正整数),使得所有的奇数排在所有的偶数前面,要求复杂度O(n)。 (6分)
i = 0;
j = n - 1;
while (i <= j)
{
while (s[i] % 2 == 1 && i <= j)
i++;
while (________________)
____________;
if (____________)
{
int temp = s[i];
s[i++] = s[j];
s[j++] = temp;
}
}
(3) 指出下面函数的功能:(5分)
string demo(s : string)
{
if (length(s) > 0)
{
s1 = demo(substr(s, 2, length(s) - 1));
s2 = cancat(s1, substr(s, 1, 1));
}
else
assign(s2, s);
return (s2);
}
函数demo的功能是:
demo(“abcdefg”)返回:
(4)计算树的叶结点的数目:(4分)
template <class T>
int CountLeaf(BTNode<T> *&t)
{
if (t == NULL)
return 0;
else if (t->Left() == NULL && t->Right() == NULL)
return 1;
else
return ________________ + _______________;
}
LB组四
四、 (1) (8分)
已知一个堆为(12,15,40,38,26,52,48,64),若需要从堆中依次删除四个最小的元素,请给出每删除一个元素后堆的状态(和题目一样用列表方法表示)。
(2)有七个带权结点,其权值分别为3,7,8,2,6,10,14,试以它们为叶子结点构造一棵哈夫曼树,并计算出带权路径长度WPL。(8分)
(3)对于如图所示的有向图,试写出:(6分)
(1) 从顶点b出发进行深度优先搜索所得到的深度优先生成树;
(2) 从顶点b出发进行广度优先搜索所得到的广度优先生成树;
(4)试分别找出满足以下条件的所有二叉树,用语言描述即可:(8分)
(1) 二叉树的前序序列与中序序列相同;
(2) 二叉树的中序序列与后序序列相同;
(3) 二叉树的前序序列与后序序列相同。
五、 程序填空:
(1) 求链表中的最大整数
int List ::Max(ListNode *f)
{ // 递归算法 : 求链表中的最大值
if (f->link == NULL)
return f->data;
int temp = Max(f->link); // 在当前结点的后继链表中求最大值
if (f->data > temp)
return _______________;
else
return ______________;
}
(2)求链表的结点个数
int List ::Num(ListNode *f)
{ // 递归算法 : 求链表中结点个数
if (f == NULL)
return 0; // 空表, 返回0
return _________________;
}
(3)判别输入的字符串里,左右括号是否匹配:
void main(void)
{
SeqStack mystack; // 已定义了栈类
char str[80];
cout << "输入字符序列,回车换行符结束:" << endl;
cin.getline(str, 80);
int h = strlen(str);
for (int i = 0; i < h; i++)
{
if (str[i] == '(')
mystack.Push(str[i]);
else if (str[i] == ')')
if (mystack.StackEmpty())
{
cout << "_______________" << endl; // 填“匹配”或“不匹配”
return;
}
else
mystack.Pop();
}
if (mystack.StackEmpty())
cout << " _______________ " << endl; // 填“匹配”或“不匹配”
else
cout << "_______________" << endl; // 填“匹配”或“不匹配”
}
(4)读程序:
int p(int k, int a[])
{
int m, i, c = 0;
for (m = 2; m <= k; m++)
{
for (i = 2; i <= m; i++)
if (!(m % i))
break;
if (i == m)
a[c++] = m;
}
return c;
}
#define MAXN 20
void main()
{
int i, m, s[MAXN];
m = p(13, s);
for (i = 0; i < m; i++)
printf(“% 4d\t”, s[i]);
printf(“\n”);
}
程序的输出结果是__________________;
函数int p(int k,int a[])的功能是__________________