本文正在参加「金石计划」
41.(13 分)已知非空二叉树 T 的结点值均为正整数,采用顺序存储方式保存,数据结构定义如下:
typeof struct{ //MAX_SIZE 为已定义常量
int SqBiTNode[MAX_SIZE]; //保存二叉树节点值的数值
int ElemNum;//实际占用的数组元素个数
}SqBiTree;
T中不存在的结点在数组SqBiTNode中用−1 表示。例如,对于下图所示的两棵非空二叉树T1
和T2,
T1 的存储结果如下:
T1.SqBiTNode
T1.ElemNum=10
T2 的存储结果如下:
T2.SqBiTNode
T2.ElemNum=11
请设计一个尽可能高效的算法,判定一颗采用这种方式存储的二叉树是否为二叉搜索树,若
是,则返回true,否则,返回false.要求:
- 给出算法的基本设计思想。
- 根据设计思想,采用?或 C++语言描述算法,关键之处给出注释。
【解析】
(1)利用二叉搜索树的性质的推论:中序遍历为单调递增序列。
void inorder(SqBiTree T, int i, int *a, int *j)
{
if (i >= T.ELemNum || T.SqBiTNode[i] == -1)
{ // 越界或者为空
结点
return;
}
inorder(T, 2 * i + 1, a, j);
a[(*j)++] = T.SqBiTNode[i];
inorder(T, 2 * i + 2, a, j);
}
bool isValidBST(SqBiTree T)
{
int *a = (int *)malloc(sizeof(int) * MAX_SIZE);
int j = 0;
inorder(T, 0, a, &j);
for (int k = 0; k < j - 1; k++)
{
if (a[k] >= a[k + 1])
{
return false;
}
}
return true;
}
42.(10 分)现有n(n > 100000)个数保存在一维数M中,需要在找M中最小的 10 个数。
请回答下列问题。
(1)设计一个完成上述查找任务的算法,要求平均情况下的比较次数尽可能少,简述其算
法思想(不要程序实现) (2)说明你所设计的算法平均情况下的时间复杂度和空间复杂度
【解析】
(1)先用 A[1: 10] 建立大顶堆 B[1: 10](注意:这里不能用小顶堆),遍历A[11: n],每个元
素A[i]逐一和堆顶元素比较,其中 11 ≤ i ≤ n,如果 A[i] 大于等于堆顶元素 B[1],不进行任
何操作,如果该元素小于堆顶元素 B[1],那么就删除堆顶元素,将该元素放入堆顶,即
令 B[1] = A[i],然后将 B[1: 10] 重新调整为大顶堆。最后堆 B[1: 10] 中留存的元素即为最小的 10 个数。
(2)时间复杂度: O(n) ,由于堆大小为常量,所以建堆,维护堆的代价为 O(1) ,仅需要
遍历一遍数组,该算法时间复杂度为 O(n) 。
空间复杂度: O(1) ,该算法用了大小为 10 的堆的辅助数组,该算法的空间复杂度为 O(1)