📜  数据结构和算法 | 2套

📅  最后修改于: 2021-09-27 22:37:52             🧑  作者: Mango

以下问题已在 GATE CS 考试中提出。

1. 考虑下面定义的函数f。

struct item 
{ 
  int data; 
  struct item * next; 
}; 
  
int f(struct item *p) 
{ 
  return (
          (p == NULL) || 
          (p->next == NULL) || 
          (( P->data <= p->next->data) && f(p->next))
         ); 
} 

对于给定的链表 p,函数f 返回 1 当且仅当 (GATE CS 2003)
a) 列表为空或只有一个元素
b) 列表中的元素按数据值的非降序排列
c) 列表中的元素按数据值的非递增顺序排序
d) 并非列表中的所有元素都具有相同的数据值。

答案(二)
函数f() 的工作原理如下
1) 如果链表为空返回 1
2) Else 如果链表只有一个元素返回 1
3) 否则,如果 node->data 小于等于 node->next->data 并且同样的事情适用于列表的其余部分,则返回 1
4) 否则返回 0

2. 考虑在标记二叉树上通过以下对遍历获得的标记序列。这些对中的哪一个唯一地标识了一棵树(GATE CS 2004)?
i) 预购和后购
ii) 中序和后序
iii) 前序和中序
iv) 级序和后序

a) (i) 仅
b) (ii), (iii)
c) (iii) 仅
d) (iv) 仅

答案(二)
请参阅此帖子以获取解释。

3. 将下列数按给定的顺序插入一棵空二叉搜索树中:10, 1, 3, 5, 15, 12, 16. 二叉搜索树的高度是多少(高度是一棵最大距离从根开始的叶节点)? (GATE CS 2004)
a2
b) 3
c) 4
d) 6

答案(二)
构建的二叉搜索树将…

10
                  /     \
                 1       15
                 \      /  \
                  3    12   16
                    \
                     5

4. 需要一种数据结构来存储一组整数,以便可以在 (log n) 时间内完成以下每个操作,其中 n 是该集合中元素的数量。

o    Deletion of the smallest element 
   o    Insertion of an element if it is not already present in the set

下列哪些数据结构可用于此目的?

(a) 可以使用堆,但不能使用平衡二叉搜索树
(b) 可以使用平衡二叉搜索树,但不能使用堆
(c) 平衡二叉搜索树和堆都可以使用
(d) 既不能使用平衡二叉搜索树,也不能使用堆

答案(二)
包含 n 个项目的自平衡平衡二叉搜索树允许在 O(log n) 最坏情况下查找、插入和删除项目。由于它是一个自平衡 BST,我们可以很容易地在 O(logn) 时间内找出最小元素,它总是最左边的元素(请参阅在二叉搜索树中查找具有最小值的节点)。

由于堆是平衡二叉树(或几乎完全二叉树),堆的插入复杂度为 O(logn)。此外,在最小堆中获得最小值的复杂性是 O(logn),因为删除根节点会导致调用 heapify(从数组中删除第一个元素后)以维护堆树属性。但是堆不能用于上述目的,如问题所述 – 如果元素尚不存在,则插入该元素。对于堆,我们无法在 O(logn) 中找出元素是否存在。感谢游戏提供了正确的解决方案。

5. 一个循环链表用于表示一个队列。单个变量 p 用于访问队列。 p 应该指向哪个节点,这样 enQueue 和 deQueue 操作都可以在恒定时间内执行? (2004 年大门)

ll

a) 后节点
b) 前端节点
c) 不能用单个指针
d) 靠近前面的节点

答案(一)
答案不是“(b)前端节点”,因为我们不能在 O(1) 中从前端得到后端,但是如果 p 是后端,我们可以在 O(1) 中同时实现 enQueue 和 deQueue 因为从后端我们可以得到O(1) 中的前面。下面是示例函数。请注意,这些功能只是示例,无法正常工作。缺少处理基本情况的代码。

/* p is pointer to address of rear (double pointer).  This function adds new 
   node after rear and updates rear which is *p to point to new node  */
void  enQueue(struct node **p, struct node *new_node)
{
    /* Missing code to handle base cases like *p is NULL */
       
     new_node->next = (*p)->next;
     (*p)->next = new_node;
     (*p) = new_node /* new is now rear */
     /* Note that p is again front and  p->next is rear */
 }
  
/* p is pointer to rear. This function removes the front element and 
    returns the new front */
struct node *deQueue(struct node *p)
{
    /* Missing code to handle base cases like p is NULL,
        p->next is NULL,...  etc */
  
    struct node *temp = p->next->next;
    p->next = p->next->next;
    return temp;
    /* Note that p is again front and  p->next is rear */
}