文章目录

  • 每日一练
  • 3.1
  • 3.2
  • 3.3
  • 3.4
  • 3.5
  • 3.6
  • 3.7
  • 3.8
  • 3.9
  • 3.10
  • 3.11
  • 3.12
  • 3.13
  • 3.14
  • 3.15
  • 3.16
  • 3.17
  • 3.18
  • 3.19
  • 3.20
  • 3.21
  • 3.22
  • 3.23
  • 3.24
  • 3.25
  • 3.26
  • 3.27
  • 3.28
  • 3.29
  • 3.30
  • 3.31


每日一练

3.1

  • 以下关于链式存储结构的叙述中,()是不正确的。

A. 结点除自身信息外还包括指针域,因此存储密度小于顺序存储结构。

B. 逻辑上相邻的结点物理上不必邻接

C. 可以通过计算直接确定第i个结点的存储地址

D. 插入、删除操作方便,不必移动结点

【答案】C

【解析】链式存储结构的主要特点有:①结点中除自身信息外,还有表示链接信息的指针域,因此存储密度小、存储空间利用率低;②逻辑上相邻的结点物理上不必相邻;③插入、删除操作灵活方便。线性存储结构可以通过计算直接确定第i个结点的储存地址,但链式存储结构不能够。

3.2

  • 从一个具有n个结点的单链表中查找值等于x的结点时,在查找成功的情况下,需平均比较()个结点。

A. n

B. n/2

C. (n-1)/2

D. (n+1)/2

【答案】D

【解析】由于单链表只能进行单向顺序查找,以从第一个结点开始查找为例,查找第m个结点需要比较的结点数f(m) = m,查找成功的最好情况是第一次就查找成功,只用比较1个结点,最坏情况是最后才查找成功,需要比较n个结点。所以,一共有n种情况,平均下来需要比较的结点为(1+2+3+…+(n-1)+n)/n = (n+1)/2。

3.3

  • 如果使用比较高效的算法判断单链表有没有环的算法中,至少需要几个指针?

A. 1

B. 2

C. 3

D. 4

【答案】B

【解析】判断链表有没有环,可以用快慢指针来实现,如果两个指针相遇,则表示有环。

3.4

  • 关于单向链表,以下说法正确的有()

A. 单向链表中指向头结点的指针First,可用于单向链表的判空依据

B. 单向链表中指向头结点的指针First,可用于定位所有其它结点的位置

C. 单向链表插入,删除的时间复杂度小于查找的时间复杂度

D. 单向链表允许在非表头进行插入或删除操作

【答案】A、B、C、D

【解析】A选项:如果单链表的头指针指向的结点为NULL,则单链表为空;B选项:利用链表的链式存储结构,可以通过头指针定位任意一个结点的位置;C选项:单链表的插入O(1),删除的时间复杂度O(1),小于查找的时间复杂度 O(n);D选项:单链表非头结点的插入删除只需要修改 next 指针的指向,并且增加或释放相应的结点即可。

3.5

  • 设单链表中结点的结构为(data, next)。若想删除结点*p的直接后继,则应执行下列哪一个操作?

A. p->next = p->next->next

B. p = p->next; p->next = p->next->next

C. p->next = p->next

D. p = p->next->next

【答案】A

3.6

  • 以下代码的执行结果是:
class Chinese {
    private static Chinese objref = new Chinese();
    private Chinese(){}
    public static Chinese getInstance() {
        return objref;
    }
}
public class TestChinese {
    public static void main(String[] args) {
        Chinese obj1 = Chinese.getInstance();
        Chinese obj2 = Chinese.getInstance();
        System.out.println(obj1 == obj2);
    }
}

A. true

B. false

C. TRUE

D. FALSE

【答案】A

3.7

  • 以下代码的执行结果是:
public class A implements B {
    public static void main(String[] args) {
        int i;
        A a1 = new A();
        i = a1.k;
        System.out.println("i="+i);
    }
}
interface B {
    int k = 10;
}

A. i=0

B. i=10

C. 程序有编译错误

D. i=true

【答案】B

3.8

  • 以下()不是队列的基本运算

A. 从队尾插入一个新元素

B. 从队列中删除第i个元素

C. 判断一个队列是否为空

D. 读取对头元素的值

【答案】B

【解析】队列基本操作包括:生成空队列;判断队列是否已满;将元素压入队列;判断队列是否为空;删除并返回队列头元素。

3.9

  • 最大容量为n的循环队列,队尾指针是rear,队头是front,则队满的条件是()。

A. (rear+1) MOD n==front

B. rear==front

C. rear+1==front

D. (rear-1) MOD n==front

【答案】A

【解析】循环队列为空:front == rear;循环队列满:(rear+1)%n == front

3.10

  • 假设以数组A[60]存放循环队列的元素,其头指针是front=47,当前队列有50个元素,则队列的尾指针值为()

A. 3

B. 37

C. 97

D. 50

【答案】B

【解析】队列中元素的个数:(rear - front + QueueSize) % QueueSize。根据题意得:(rear - 47 + 60) % 60 = 50 ==>> rear = 37。

3.11

  • 设循环队列的容量为50(序号从0到49),现经过一系列的入队和出队运算后,有 front=16,rear=5(rear指向队尾元素的后一位置),当前循环队列中元素个数为( )

A. 11

B. 39

C. 40

D. 12

【答案】B

【解析】根据求解循环队列中元素个数的公式:m = (rear - front + maxSize) % maxSize;maxSize 是循环队列的容量,m 应该大于等于 0 并且小于等于 maxSize。带入数据计算:m = (5 - 16 + 50) % 50 = 39。

3.12

  • 用链表方式存储的队列,在进行删除运算时()。

A. 仅修改头指针

B. 仅修改尾指针

C. 头、尾指针都要修改

D. 头、尾指针可能都要修改

【答案】D

【解析】本题既考察了队列的先进先出的特性,又需要考虑删除队列的不同状态。① 当有多于一个结点时,链表表示的队列的删除操作只需要修改头指针即可,将头指针定义为 head = head.next,此时不需要修改尾指针;② 当队列只有一个结点时,该结点既是头指针又是尾指针,如果 head == tail,则需要修改尾指针将队列置空。

3.13

  • 如下语句通过算术运算和逻辑运算之后 i 和 j 的结果是()
int i = 0;
int j = 0;
if((++i>0)||(++j>0))

A. i=0; j=0

B. i=1; j=1

C. i=0; j=1

D. i=1; j=0

【答案】D

3.14

  • given the following code, what will be the output?
class Value {
    public int i = 15;
}
public class Test {
    public static void main(String[] args) {
        Test t = new Test();
        t.first();
    }

    private void first() {
        int i = 5;
        Value v = new Value();
        v.i = 25;
        second(v, i);
        System.out.println(v.i);
    }

    private void second(Value v, int i) {
        i = 0;
        v.i = 20;
        Value val = new Value();
        v = val;
        System.out.println(v.i + " " + i);
    }
}

A. 15 0 20

B. 15 0 15

C. 20 0 20

D. 0 15 20

【答案】A

3.15

  • 若已知一个栈序列是 1,2,3,…,n,其输出序列为 p1,p2,p3,…,pn,若 p1=n,则 pi 为()。

A. i

B. n - i

C. n - i + 1

D. 不确定

【答案】C

【解析】栈的特点是后进先出,入栈序列是 1,2,3,…,n,输出对应的应该是 n,n-1,n-2,…,1,所以答案是 n - i + 1。

3.16

  • 设栈的顺序存储空间为 S(1:m) ,初始状态为 top=0 。现经过一系列正常的入栈与退栈操作后, top=m+1 ,则栈中的元素个数为( )

A. 不可能

B. m+1

C. 0

D. m

【答案】A

【解析】栈是一种特殊的线性表,它所有的插入与删除都限定在表的同一端进行。入栈运算即在栈顶位置插入一个新元素,退栈运算即取出栈顶元素赋予指定变量。栈为空时,栈顶指针 top=0,经过入栈和退栈运算,指针始终指向栈顶元素,栈满时,top=m。初始状态为 top=m+1是不可能的。

3.17

  • 一个栈的入栈序列为1,2,3,…,n ,其出栈序列是 p 1 ,p 2 ,p 3 ,…p n 。若p 2 = 3,则 p 3 可能取值的个数是()

A. n-3

B. n-2

C. n-1

D. 无法确定

【答案】C

【解析】栈是先进后出原则。根据题意可得

  • 当 n = 3,p2 = 3 时,那么 p1 有两种情况 1 和 2:若 p1 = 1,则 p3 = 2;若 p1 = 2,则 p3 = 1。
  • 当 n > 3,p2 = 3 时,那么 p1 的可能情况有三种:1, 2, 4:
  • 若 p1 = 1,则 p3 = 2, 4, 5, …, n,(n-2)个
  • 若 p1 = 2,则 p3 = 1, 4, 5, …, n,(n-2)个
  • 若 p1 = 4,则 p3 = 2, 5, 6, …, n,(n-3)个
  • 此时我们就可以看到 p3 的情况有 1, 2, 4, 5, …, n,(n - 1) 个。

3.18

  • 若已有一个栈,进栈顺序为 ABCD,出栈顺序为 BCDA,若用 I 表示进栈,O 表示出栈,则进栈操作的顺序是()

A. IOIOIIOO

B. IIOOIIOO

C.IIOIOIOO

D.IIOIOOIO

【答案】C

【解析】栈是先进后出原则。ABCD顺序进栈,AB进,B出,C进,C出,D进,D出,A出。

3.19

  • 已知一个栈的进栈序列为 p1, p2, p3, …, pn,输出序列为 1, 2, 3, …, n,若 p3 = 1,则 p1()。

A. 可能是2

B. 一定是2

C. 不可能是2

D. 不可能是3

【答案】C

【解析】p3 = 1 且 1 是第一个出栈的元素,说明 p1、p2、p3 这三个元素连续出栈(在 p3 出栈前 p1 和 p2 没有出栈 );第二个出栈元素是2,而此时栈顶是 p2,栈底是 p1,因此只可能是 p2, p4, p5, …, pn,这些元素之一为 2,p1 不可能为 2。

3.20

  • 下面的哪些声明式合法的?()

A. long l = 499

B. int i = 4L

C. float f = 1.1

D. Double d = 34.4

【答案】AD

【解析】B 选项 4L 是 long 类型的写法;C 选项 1.1 是 double 类型,正确写法是 float f = 1.1f;

3.21

  • 下列哪些表达式返回 true?
String s = new String(“hello”);
String t = new String(“hello”);
char c [ ] ={‘h’,’e’,’l’,’l’,’o’};

A. s.equals(t);

B. t.equals©;

C. s == t;

D. t.equals(new String(“hello”));

E. t == c

【答案】AD

【解析】String类的equals方法覆盖了 Object 类的 equals 方法,比较的是两个字符串的内容是否相等,双等号比较的是两个对象的的内存地址是否相等。

3.22

  • 以下程序段,其中n为正整数,则最后一行的语句频度在最坏情况下是()

A. O(n)

B. O(nlogn)

C. O(n^3)

D. O(n^2)

【答案】D

【解析】此算法为冒泡排序算法的核心语句,最坏情况下的时间复杂度为O(n^2)

3.23

  • 线性表最常用的操作是在最后一个节点之后插入一个节点或删除第一个节点,则采用()存储方式最节省时间。

A. 单链表

B. 仅有头结点的单循环链表

C. 双链表

D. 仅有尾结点的指针的单循环链表

【答案】D

【解析】D 选项对于这两个操作的时间复杂度均为O(1)

3.24

  • 输入序列为A,B,C,当输出序列为C,B,A时,经过到的栈操作为()。

A. push, pop, push, pop, puush, pop

B. push, push, push, pop, pop, pop

C. push, push, pop, pop, push, pop

D. push, pop, push, push, pop, pop

【答案】B

3.25

  • 设n个元素进栈序列是1, 2, 3, ……, n,其输出序列是p1, p2, p3, ……, pn。若p1=3,则p2的值()

A. 一定是2

B. 一定是1

C. 不可能是1

D. 以上都不对

【答案】C

【解析】此时1处在栈底,栈顶元素是2,因此p2的值不可能是1。

3.26

  • 最不适合用作队列的链表是()

A. 只带队首指针的非循环双链表

B. 只带队首指针的循环双链表

C. 只带队尾指针的循环双链表

D. 只带队尾指针的循环单链表

【答案】A

【解析】A选项的链表无法在 O(1) 时间内定位队尾元素。

3.27

  • 给定以下代码,程序将输出()
class A {
    public A() {
        System.out.println("A");
    }
}

class B extends A {
    public B() {
        System.out.println("B");
    }
    public static void main(String[] args) {
        B b = new B();
    }
}

A. 不能通过编译

B. 通过编译,输出AB

C. 通过编译,输出B

D. 通过编译,输出A

【答案】B

【解析】在继承关系下,创建子类对象,先执行父类的构造方法,再执行子类的构造方法。

3.28

  • 下列关于关键字的使用说法错误的是()(选择一项)

A. abstract不能与final并列修饰同一个类

B. abstract类中可以有private的成员

C. abstract方法必须在abstract类中

D. static方法能处理非static的属性

【答案】D

【解析】因为static的方法在装载class时首先完成,比构造方法早,此时非static的属性和方法还没有完成初始化,所以不能调用。

3.29

  • 利用二叉树表存储森林时,根节点的右指针是()

A. 指向最左兄弟

B. 指向最右兄弟

C. 一定为空

D. 不一定为空

【答案】D

【解析】森林与二叉树具有对应关系,因此,我们存储森林时应该将森林转为二叉树,转换的方法就是左儿子右兄弟”,与树不同的是,若存在第二棵树,则二叉链表的根节点的右指针指向的就是森林中第二棵数的根节点。若森林只有一棵树,则根节点的右指针为空。因此,右指针可能为空也可能不为空。

3.30

  • 已知一棵有2011个节点的树,其叶节点个数为116,该树对应的二叉树无右孩子的节点个数是()

A. 115

B. 116

C. 1895

D. 1896

【答案】D

【解析】树转化为二叉树时,树的每个分支节点的所有子节点中的最右节点无右孩子,根节点转换后也没有右孩子,因此,对应二叉树中无右孩子的节点个数为:分支节点数+1 = 2011-116+1=1896。

3.31

  • 若森林F有15条边、25个结点,则F包含树的个数是()

A. 8

B. 9

C. 10

D. 11

【答案】C

【解析】树有一个很重要的性质,即在 n 个结点的树中有 n-1 条边,那么对于每棵树,其结点数比边数多 1。题中的森林中的结点比边数多 10,即 25 - 15 = 10,显然共有 10 棵数。