Java训练题16

一、选择题

1、二叉树是非线性数据结构,所以(C )
A. 它不能用顺序存储结构存储;
B. 它不能用链式存储结构存储;
C. 顺序存储结构和链式存储结构都能存储;
D. 顺序存储结构和链式存储结构都不能使用
答案解析:C
二叉树既可以用链式存储,也可以用顺序存储,不同的类型的二叉树适合不同的存储方式;
比如完全二叉树适合顺序存储,这样比较节省空间;普通的二叉树可以用链式存储。
2、执行(B )操作时,需要使用队列作为辅助存储空间。
A. 查找哈希(hash)表
B. 层序遍历
C. 先序(根)遍历二叉树
D. 深度优先搜索图
答案解析:B
二叉树的层序遍历是从根节点开始从上到下,从左到右每一层进行遍历。
二叉树进行层序遍历时,需要利用队列的先进先出原则,将每一个结点的左孩子和右孩子依次放入队列,防止下一层节点丢失
或者结点的顺序被打乱。
3、中序遍历为abcd的二叉树可能是下面的哪棵【多选】(C D )
A.在这里插入图片描述

B.在这里插入图片描述

C. 在这里插入图片描述

D. 在这里插入图片描述
答案解析:C D
中序遍历就是先访问二叉树的左子树,在访问二叉树的根节点,最后访问二叉树的右子树;
A图中序遍历的结果是:dbac
B图中序遍历的结果是:cbda
C图中徐遍历的结果是:abcd
D图中徐遍历的结果是:abcd
所以选择 C D
4、关于堆数据结构,下面描述中不恰当的一项是:(D )
A. 用堆可以实现优先队列(priority_queue)
B. 使用堆可以实现排序算法,复杂度为NlogN
C. 堆是一棵完全二叉树
D. 在大顶堆的二叉树中,第N层中的所有元素比第N+1层中的所有元素都要大
答案解析:D
堆是一棵完全二叉树;
优先队列的底层实现是堆结构;
堆排序是一种经典的排序算法,时间复杂度为NlogN;
大顶堆只能保证根节点的元素值比左右子树的元素值大,但是如果某一层有很多结点,我们只能保证每一个结点满足这样的规
律,但并不意味着某一个结点的值大于其它结点的左右孩子。
5、下列关键字序列为堆的是(A )
A. 100,60,70,50,32,65
B. 60,70,65,50,32,100
C. 65,100,70,32,50,60
D. 70,65,100,32,50,60
答案解析:A
堆分为大根堆和小根堆;大根堆中每一个结点的值都大于其左右子树的值,小根堆中每一个结点的值小于其左右子树的值;
A选项中的数据序列为大根堆,按照序列
100为根节点,100的左子树为60,右子树为70,得出根节点值大于左右子树结点值
60的左子树为50,右子树为32,70的左子树为65,左子树和右子树的结点值也分别遵循大根堆的规律;所以选A

二、编程题

1、用队列实现栈
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和
empty)。实现 MyStack 类:
void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。
OJ链接

示例:
输入:
["MyStack", "push", "push", "top", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 2, 2, false]
解释:
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // 返回 2
myStack.pop(); // 返回 2
myStack.empty(); // 返回 False

加粗样式【解题思路】:
使用一个队列时,为了满足栈的特性,即最后入栈的元素最先出栈,同样需要满足队列前端的元素是最后入栈的元
素。入栈操作时,首先获得入栈前的元素个数 n,然后将元素入队到队列,再将队列中的前 n 个元素(即除了新入栈
的元素之外的全部元素)依次出队并入队到队列,此时队列的前端的元素即为新入栈的元素,且队列的前端和后端分
别对应栈顶和栈底。由于每次入栈操作都确保队列的前端元素为栈顶元素,因此出栈操作和获得栈顶元素操作都可以
简单实现。出栈操作只需要移除队列的前端元素并返回即可,获得栈顶元素操作只需要获得队列的前端元素并返回即
可(不移除元素)。由于队列用于存储栈内的元素,判断栈是否为空时,只需要判断队列是否为空即可。

class MyStack {
    private Queue<Integer> queue;
    public MyStack() {
        queue = new LinkedList<>();
    }
    public void push(int x) {
        // 获取当前队列元素个数
        int n = queue.size();
        // 1.先入队
        queue.add(x);
        // 2+3.将前n个元素依次出队再入队
        for (int i = 0; i < n; i++) {
            queue.add(queue.poll());
        }
    }
    public int pop() {
        return queue.poll();
    }
    public int top() {
        return queue.peek();
    }
    public boolean empty() {
        return queue.isEmpty();
    }
}

2、用栈实现队列
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):实
现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
OJ链接

示例:
输入:
["MyQueue", "push", "push", "peek", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 1, 1, false]
解释:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false

解题思路】:
一个队列是 FIFO 的,但一个栈是 LIFO 的。这就意味着最新压入的元素必须得放在栈底。为了实现这个目的,我们首先需要把 s1 中所有的元素移到 s2 中,接着把新元素压入 s2。最后把 s2 中所有的元素弹出,再把弹出的元素压入s1。
在这里插入图片描述

class MyQueue {
    // s1存储具体元素
    private Stack<Integer> s1;
    // s2作为辅助
    private Stack<Integer> s2;
    public MyQueue() {
        s1 = new Stack<>();
        s2 = new Stack<>();
    }
    public void push(int x) {
        if (s1.isEmpty()) {
            s1.push(x);
        }else {
            while (!s1.isEmpty()) {
                s2.push(s1.pop());
            }
            // 直接将队尾元素入s1
            s1.push(x);
            // 将s2的所有元素依次出栈再入s1
            while (!s2.isEmpty()) {
                s1.push(s2.pop());
            }
        }
    }
    public int pop() {
        return s1.pop();
    }
    public int peek() {
        return s1.peek();
    }
    public boolean empty() {
        return s1.isEmpty();
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
(1)非递归定义 树(tree)是由n(n≥0)个结点组成的有限集合。n=0的树称为空树;n>0的树T: ① 有且仅有一个结点n0,它没有前驱结点,只有后继结点。n0称作树的根(root)结点。 ② 除结点外n0 , 其余的每一个结点都有且仅有一个直接前驱结点;有零个或多个直接后继结点。 (2)递归定义 一颗大树分成几个大的分枝,每个大分枝再分成几个小分枝,小分枝再分成更小的分枝,… ,每个分枝也都是一颗树,由此我们可以给出树的递归定义。 树(tree)是由n(n≥0)个结点组成的有限集合。n=0的树称为空树;n>0的树T: ① 有且仅有一个结点n0,它没有前驱结点,只有后继结点。n0称作树的根(root)结点。 ② 除根结点之外的其他结点分为m(m≥0)个互不相交的集合T0,T1,…,Tm-1,其每个集合Ti(0≤i<m)本身又是一棵树,称为根的子树(subtree)。 2、掌握树的各种术语: (1) 父母、孩子与兄弟结点 (2) 度 (3) 结点次、树的高度 (4) 边、路径 (5) 无序树、有序树 (6) 森林 3、二叉树的定义 二叉树(binary tree)是由n(n≥0)个结点组成的有限集合,此集合或者为空,或者由一个根结点加上两棵分别称为左、右子树的,互不相交的二叉树组成。 二叉树可以为空集,因此根可以有空的左子树或者右子树,亦或者左、右子树皆为空。 4、掌握二叉树的五个性质 5、二叉树的二叉链表存储。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值