当前位置:文档之家› 数据结构与算法面试题

数据结构与算法面试题

数据结构与算法面试题
数据结构与算法面试题

目录

1. 数组 (3)

2. 链表 (5)

3. 栈 (9)

4. 队列 (10)

5. 堆(优先队列) (12)

6. 二叉树 (15)

7. 二叉查找树 (24)

8. 字典树 (26)

9. 平衡树(AVL) (26)

10. 红黑树 (26)

11. B树/B+树 (28)

12. 哈希 (29)

13. 图 (31)

14. 字符串 (33)

15. 排序 (36)

16. 二分查找 (40)

17. 跳跃列表 (41)

18. 动态规划 (42)

1.数组

应用场景:

1)数据比较少

2)经常做的运算是按序号访问数据元素

面试题

选择题:

1)对于长度为n的线性表,建立其对应的单链表的时间复杂度为()。

O(1)

O(log2n)

O(n)

O(n^2)

2)下列哪些不是线性表?

队列

关联数组

链表

3)稀疏矩阵一般的压缩存储方法有两种,即()

二维数组和三维数组

三元组和散列

三元组和十字链表

散列和十字链表

4)将10阶对称矩阵压缩存储到一维数组A中,则数组A的长度最少为

100

40

55

80

5)

设A是n*n的对称矩阵,将A的对角线及对角线上方的元素以列为主的次序存放在一维数组B[1..n(n+1)/2]中,对上述任一元素aij (1≤i,j≤n,且i≤j)在B中的位置为()

i(i-1)/2+j

j(j-1)/2+i

j(j-1)/2+i-1

i(i-1)/2+j-1

6)若有定义:

int c[4][5],( *pc)[5];

pc=c;

那么,下列对数组C的元素引用正确的是( )。

pc+1

* (pc+3)

* (pc+1) +3

* (*pc+2)

问答题:

1)数组和链表的区别

思路:

从逻辑结构上来看,数组必须实现定于固定的长度,不能适应数据动态增减的情况,即数组的大小一旦定义就不能改变。当数据增加是,可能超过原先定义的元素的个数;当数据减少时,造成内存浪费;链表动态进行存储分配,可以适应数据动态地增减的情况,且可以方便地插入、删除数据项。

从内存存储的角度看;数组从栈中分配空间(用new则在堆上创建),对程序员方便快速,但是自由度小;链表从堆中分配空间,自由度大但是申请管理比较麻烦。

从访问方式类看,数组在内存中是连续的存储,因此可以利用下标索引进行访问;链表是链式存储结构,在访问元素时候只能够通过线性方式由前到后顺序的访问,所以访问效率比数组要低。

2)输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)

思路:

Step1.从头到尾逐个累加数组中的每个数字,初始化和为0;(nCurrSum=0,nGreatestNum=int.MinValue)

Step2.首先加上第一个数字,从第二个数字开始累加,依次将累加和保存到一个临时变量(nCurrSum)中;

Step3.如果当前累加和(nCurrSum)小于0,那抛弃前面的子数组和,从下一个数字开始重新累加;相反,则将当前累加和(nCurrSum)与返回累加和(nGreatestNum)进行比较,如果nCurrSum>nGreatestNum,则更新nGreatestNum。

3)给定一个n个整型元素的数组a,其中有一个元素出现次数超过n / 2,求这个元素

思路:

方法一:对数组进行排序,因为一个元素已经超过了一半,则中间位置的元素就必为该元素。方法二:火拼方法。

4)给定一个含有n个元素的数组,找出数组中的两个元素X和Y使得abs(x-y)最小

思路:

先排序,然后遍历元素。

5)求两个有序数组的共同元素

思路:

充分利用数组有序的性质,用两个指针i和j分别指向a和b,比较a[i]和b[j],根据比较结果移动指针,则有如下三种情况

a[i] < b[j],则i增加1,继续比较

a[i] == b[j],则i和j皆加1,继续比较

a[i] < b[j],则j加1,继续比较

重复以上过程直到i或j到达数组末尾。

6)给定两个有序整型数组a和b,各有n个元素,求两个数组中满足给定和的数对,即对a 中元素i和b中元素j,满足i + j = d(d已知)

思路:

两个指针i和j分别指向数组的首尾,然后从两端同时向中间遍历。

7)给定含有n个元素的整型数组a,其中包括0元素和非0元素,对数组进行排序,要求:排序后所有0元素在前,所有非零元素在后,且非零元素排序前后相对位置不变,且不能使用额外存储空间

思路:

从尾部开始设置两个指针,last指针指向后面第一个出现0的位置,first指向last前面的第一个非0元素,如果first是非0,则将值赋给last,然后last++,first++;如果first指向0,则继续前进first++。

8)给定一个有序整数序列(非递减序),可能包含负数,找出其中绝对值最小的元素,比如给定序列-5, -3, -1, 2, 8 则返回1

思路:

如果给定的序列中所有的数都是正数,那么数组的第一个元素即是结果。

如果给定的序列中所有的数都是负数,那么数组的最后一个元素即是结果。

如果给定的序列中既有正数又有负数,那么绝对值得最小值一定出现在正数和负数的连接处。

9)未排序数组,找出两个元素值等于target值,并返回下标,小的下标在前面。

思路:

定义一个空字典,values存储nums数组索引,keys存储nums数据的值。循环整个数组,判定target-num[i]是否在字典在,在执行相应操作

2.链表

使用场景:

1)数据量较小

2)不需要预先知道数据规模

3)适应于频繁的插入操作

面试题

选择题:

1)在一个单链表中,q的前一个节点为p,删除q所指向节点,则执行()。

delete q

q->next=p->next;delete p

p->next=q->next;delete p

p->next=q->next;delete q

delete p

q->next=p->next;delete q

2)从表中任意一个节点出发可以依次访问到表中其他所有节点的结构是()

线性单链表

双向链表

循环链表

线性链表

3)若某表最常用的操作是在最后一个结点之后插入一个结点或删除最后一个结点,则采用存储方式最节省运算时间。

单链表

给出表头指针的单循环链表

双链表

带头结点的双循环链表

4)和顺序栈相比,链栈有一个比较明显的优势是()

通常不会出现栈满的情况

通常不会出现栈空的情况

插入操作更容易实现

删除操作更容易实现

5)某指针变量p指向双向链表中结点A,指针变量s指向被插入的结点X,则在结点A的后面插入结点X的操作序列为()。

p->right=s;s->left=p;p->right->left=s;s->right=p->right;

s->left=p;s->right=p->right;p->right=s;p->right->left=s;

p->right=s;p->right->left=s;s->left=p;s->right=p->right;

s->left=p;s->right=p->right;p->right->left=s;p->right=s;

6)

某单链表有5个元素,设单链表的节点结构为(data,next),5个元素的data依次为(1、2、3、4、5),已知指针q指向节点3,指针p指向节点4,那么下面操作能将链表变为data依次为(1、2、3、5)的是____。(其中temp为节点类型指针,默认指向NULL)

q=p->next;

p=q->next;

p->next=q->next;

q->next=p->next; delete q;

p->data=p->next->data; p->next=p->next->next; delete p->next;

temp = p->next; p->next=temp->next; p->data=temp->data; delete temp;temp=NULL;

问答题:

1)寻找单链表的中间元素

思路:

设置两个指针slow、fast 起始都指向单链表的头节点。其中fast 的移动速度是slow 的2倍。当fast 指向末尾节点的时候,slow 正好就在中间了。想想一下是不是这样假设一个链表长度为6 ,slow 每次一个节点位置,fast 每次移动两个节点位置,那么当fast = 5的时候slow = 2 正好移动到2 的节点的位置。

2)已知一个单链表求倒数第N 个节点

思路:

快慢指针法,让快指针先走n-1 步后,然后让慢指针出发。快慢指针每次都只移动一个位置,当快指针移动到链表末尾的时候,慢指针就正处于倒数第N 个节点的位置。

3)删除单链表的倒数第n 个节点

思路:

想操作链表的某个节点(添加,删除)还必须知道这个节点的前一个节点。所以我们删除倒数第n 个元素就要找到倒数第n + 1 个元素。然后将倒数第n + 1个元素p 的next 指针p.next 指向p.next.next 。

4)翻转一个单链表,要求额外的空间复杂度为O(1)

思路:

找到当前要反转的节点的下一个节点并用变量保存因为下一次要反转的是它

然后让当前节点的next 指向上一个节点,上一个节点初始null 因为头结点的翻转后变为尾节点

当前要反转的节点变成了下一个要比较元素的上一个节点,用变量保存

当前要比较的节点赋值为之前保存的未翻转前的下一个节点

当前反转的节点为null 的时候,保存的上一个节点即翻转后的链表头结点

5)单链表的归并排序

代码:

private Node merge(Node l, Node r) {

//创建临时空间

Node aux = new Node();

Node cur = aux;

//由于链表不能方便的拿到链表长度所以一般使用while l == null 表示链表遍历到尾部

while (l != null && r != null) {

if (l.value < r.value) {

cur.next = l;

cur = cur.next;

l = l.next;

} else {

cur.next = r;

cur = cur.next;

r = r.next;

}

}

//当有一半链表遍历完成后另外一个链表一定只剩下最后一个元素(链表为基数)if (l != null) {

cur.next = l;

} else if (r != null) {

cur.next = r;

}

return aux.next;

}

6)单链表的插入排序

代码:

public Node insertionSortList(Node head) {

if (head == null || head.next == null) return head;

Node dummyHead = new Node(0);

Node p = head;

dummyHead.next = head;

//p 的值不小于下一节点元素考察下一节点

while (p.next != null) {

if (p.value <= p.next.value) {

p = p.next;

} else {

//p 指向4

Node temp = p.next;

Node q = dummyHead;

p.next = p.next.next;

//从头遍历链表找到比当前temp 值小的第一个元素插入其后边整个位置一定在头节点与q 节点之间

while (q.next.value < temp.value && q.next != q)

q = q.next;

temp.next = q.next;

//重新连接链表注意else 的过程并没有改变p 指针的位置

q.next = temp;

}

}

return dummyHead.next;

}

3.栈

应用场景:

1)数制转换

2)括号匹配检验

3)迷宫求解

4)表达式求值& 中缀表达式转后缀表达式

5)二叉树的非递归遍历

面试题

选择题:

1)一个栈的入栈列序是a,b,c,d,e,出栈的不可能的输出序列是()

edcba

decba

dceab

Abcde

2)下列叙述中正确的是()。

在栈中,栈中元素随栈底指针与栈顶指针的变化而动态变化

在栈中,栈顶指针不变,栈中元素随栈底指针的变化而动态变化

在栈中,栈底指针不变,栈中元素随栈顶指针的变化而动态变化

以上说法均不正确

3)表达式a*(b+c)-d的后缀表达式是()

abcd*+-

abc+*d-

abc*+d-

-+*abcd

4)若栈采用链式存储结构,则下列说法中正确的是()

需要判断栈满但不需要判断栈空

不需要判断栈满也不需要判断栈空

需要判断栈满且需要判断栈空

不需要判断栈满但需要判断栈空

5)若进栈序列为a,b,c,则通过入出栈操作可能得到的a,b,c的出栈的不同排列个数为( ) 4

5

6

7

6)栈是先进后出的数据结构。给定一个大小为3的初始状态为空的栈,已知一组数据经过这个栈后,最终的数据顺序依次为:1 3 2 4 ,问原始的进栈数据不可能是以下的那组?

2 3 1 4

1 4

2 3

4 2 3 1

3 1 2 4

7)设栈S初始状态为空。元素a,b,c,d,e,f依次通过栈S,若出栈的顺序为c,f,e,d,b,a,则栈S 的容量至少应该为?

3

4

5

6

8)下列叙述中正确的是()

在循环队列中,队头指针和队尾指针的动态变化决定队列的长度

在循环队列中,队尾指针的动态变化决定队列的长度

在带链的队列中,队头指针与队尾指针的动态变化决定队列的长度

在带链的栈中,栈顶指针的动态变化决定栈中元素的个数

问答题:

1)实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值)的时间复杂度为O(1) 思路:

入栈,第一个元素入栈时(当前栈为空),push 两次第一个数据,第一次push 的数据代表当前入栈的数据,第二次push 的数据代表当前栈中最小的元素;第二个元素入栈时,先将该数据与当前栈顶的数据进行比较并记录下二者当中较小的数据,然后push 第二个数据,接个push 比较后记录的较小的那个数据(该数据就是当前栈中的最小值);后面入栈的数据做同样的处理

出栈,出栈时需pop 两次,第一次pop 的结果是当前栈中最小的元素,第二次pop 的结果是真真意义上的栈顶元素

取最小值:当前栈顶的元素就是栈中所有元素的最小值

2)用两个栈实现队列

思路:

起初的时候,两个栈都为空,那么只要有元素来,那么默认插入到第一个栈。这是,如果要求删除一个元素,那么元素已经不在栈顶,在第一个栈中肯定无法直接删除了,此时我们发现第二个栈还没有派上用场,这里用到了,把第一个栈中的元素压入到第二个栈中,可以发现原来在第一个栈中栈底的元素已经出现在第二个栈的栈顶上,所以删除的功能就实现了。如果这个时候,“队列”里还有元素,我们还可以继续出队,而且,现在要出队的元素就在第二个栈的栈顶,所以直接出栈即可。如果栈2不为空,同时又需要出队,那么顺其自然直接弹出即可。如果栈2为空,那么从栈1中逐个弹出压入,那么完整的实现了先进先出的功能。

4.队列

应用场景:

1)消息队列

面试题

选择题:

1)以下哪一个不是队列的基本运算?()

在队列第i个元素之后插入一个元素

从队头删除一个元素

断一个队列是否为空

读取队头元素的值

2)一个队列的入列序为ABCD ,则队列的可能输出序列为()

DCBA

ABCD

ADCB

CBDA

3)循环队列的存储空间为Q(1:200) ,初始状态为front=rear=200 。经过一系列正常的入队与退队操作后,front=rear=1 ,则循环队列中的元素个数为()

0或200

1

2

199

4)设循环队列的结构是:

const int Maxsize=100;

typedef int Data Type;

typedef struct {

Data Type data[Maxsize];

int front, rear;

}Queue;

若一个Queue 类型的队列Q ,试问判断队列满的条件应是下列哪一个语句

Q.front==Q.rear;

Q.front-Q.rear==Maxsize;

Q.front+Q.rear=Maxsize;

Q.front==(Q.rear+1)%Maxsize;

5)若用一个大小为6的数组来实现循环队列,且当前rear和front的值分别为0和3,当从队列中删除一个元素,再加入两个元素后,rear和front的值分别为多少?()

1和5

2和4

4和2

5和1

6)现有一循环队列,其队头指针为front,队尾指针为rear;循环队列长度为N。其队内有效长度为?(假设队头不存放数据)

(rear - front + N) % N + 1

(rear - front + N) % N

(rear - front) % (N + 1)

(rear - front + N) % (N - 1)

7)下列叙述中正确的是()。

循环队列是队列的一种链式存储结构

循环队列是队列的一种顺序存储结构

循环队列是非线性结构

循环队列是一种逻辑结构

8)在循环队列中,若front 与rear 分别表示对头元素和队尾元素的位置,则判断循环队列空的条件是。

front==rear+1

rear==front+1

front==rear

front==0

9)已知循环队列存储在一维数组A[0..n-1]中,且队列非空时front 和rear 分别指向队头和队尾元素。若初始时队列为空,且要求第 1 个进入队列的元素存储在A[0]处,则初始时front和rear 的值分别是()。

0,0

0,n-1

n-1,0

n-1,n-1

问答题:

1)用两个队列实现栈。

思路:

起初的时候,两个队列都是空的,那么当“栈”要压入一个元素,我们就默认将该元素压入到队列1中。接下来继续压入剩余的元素。接下来考虑,如果我们想要弹出一个元素如何操作。栈中要求出栈的为栈顶元素,那么即为最后插入的元素,但是该元素在队列的尾部,必须要求前面的元素出队后才能访问,说到这里,你也就发现思路的:出队前面的元素,到另一个队列中,那么就可以在原队列中弹出唯一的元素了。现在我们再考虑另一个情况,队列里面还有元素,“栈”又进来了新的元素,那么就将新元素,压入到存在元素的那一个队列中,剩余的操作,上面已经提到了,一样的操作。

5.堆(优先队列)

应用场景:

1)查找第K大(小)元素

2)堆排序

面试题

选择题:

1)以下序列不是堆的是()

(100,85,98,77,80,60,82,40,20,10,66)

(100,98,85,82,80,77,66,60,40,20,10)

(10,20,40,60,66,77,80,82,85,98,100)

(100,85,40,77,80,60,66,98,82,10,20)

2)下列关键字序列中,()是堆。

16,72,31,23,94,53

16,23,53,31,94,72

94,23,31,72,16,53

16,53,23,94,31,72

3)下列关键字序列为堆的是()?

100,60,70,50,32,65

60,70,65,50,32,100

65,100,70,32,50,60

70,65,100,32,50,60

32,50,100,70,65,60

50,100,70,65,60,32

4)以下关于堆的叙述中正确的是()

Ⅰ.在一个大根堆中,最小关键字的记录一定属于最底层的叶子结点层

Ⅱ.在一个小根堆中,从根结点到某个叶子结点所经路径上的结点构成一个递增有序序列Ⅲ.堆一定是一棵完全二叉树

Ⅳ.由某关键字序列构造的一棵完全二叉树经过一次筛选便可以变成一个堆

仅Ⅰ、Ⅲ

仅Ⅱ、Ⅲ

仅Ⅱ、Ⅲ、Ⅳ

仅Ⅰ、Ⅱ、Ⅲ

5)最小堆[0,3,2,5,7,4,6,8],在删除堆顶元素0之后,其结果是()

[3,2,5,7,4,6,8]

[2,3,5,7,4,6,8]

[2,3,4,5,7,8,6]

[2,3,4,5,6,7,8]

6)下列关于堆和栈的区别描述错误的有?

申请方式的不同,堆是系统自动分配,栈是自己申请

栈的大小是固定的,堆的大小受限于系统中有效的虚拟内存

栈的空间由系统决定何时释放,堆需要自己决定何时去释放

堆的使用容易产生碎片,但是用起来最方便

7)【0、2、1、4、3、9、5、8、6、7】是以数组形式存储的最小堆,删除堆顶元素0后的结果是()

【2、1、4、3、9、5、8、6、7】

【1、2、5、4、3、9、8、6、7】

【2、3、1、4、7、9、5、8、6】

【1、2、5、4、3、9、7、8、6】

8)关于数据结构,下面叙述中正确的是()

直接选择排序是一种稳定的排序方法

哈弗曼树带权路径长度最短的树,路径上权值较大的结点离根较近

拓扑排序是指结点值得有序排序

当从一个最小堆中删除一个元素时,需要把堆尾元素填补到堆顶位置,然后再按条件把它逐层向下调整到合适位置

问答题:

1)TopK问题,求数组中最大的K个元素

代码:

public class heap_test {//求第k大的数,维护一个大小为k的最小堆private static int k,n;

private static int []a=new int [101];

public static void down(int i,int n){

int t,temp;

while(i*2<=n){

if (a[i]>a[i*2]){

t=i*2;

}else{

t=i;

}

if (a[t]>a[i*2+1]){

t=i*2+1;

}

if (t!=i){

temp=a[t];

a[t]=a[i];

a[i]=temp;

i=t;

}else break;

}

}

public static void main(String[] args) {

Scanner cin=new Scanner(System.in);

k=cin.nextInt();//读取k

n=0;

while(cin.hasNextInt()){

n++;

a[n]=cin.nextInt();

}

cin.close();

if (k<=n){

for (int i=k/2;i>=1;i--){

down(i,k);

}

int num=n;

for (int i=k+1;i<=num;i++){

if (a[i]>a[1]){//如果更大

a[1]=a[i];

down(1,i);

}

}

System.out.println(a[1]);

}

}

}

6.二叉树

面试题

选择题:

1)设某二叉树的后序序列为cba,中序序列为abc,则前序序列为什么

CBA

ABC

CAB

BCA

2)一棵二叉树有67个结点,这些结点的度要么是0,要么是2。这棵二叉树中度为2的结点有______________个

33

34

32

30

3)下列关于m阶的B-树的论述不正确的是

B-树是一种平衡的多路查找树

树中每个结点至多有m棵子树

若根结点不是叶子结点,则至少有两棵子树

树中的叶子结点可出现在不同层次上

4)设树T的度为4,其中度为1,2,3和4的结点个数分别为4,2,1,1,则T中的叶子数为()

5

6

7

8

6)已知二叉树Node定义如下, 现在需要设计一个方法交换左子树和右子树, 下列方法中, 可以实现交换的是? ()

class Node {

public:

Node* left;

Node* right;

char content;

Node(char content);

private:

Node(const Node&);

Node& operator=(const Node& node);

};

void swap(Node root) {Node* temp=root.left;root.left=root.right;root.right=temp;}

void swap(Node& left, Node& right) {Node temp=left; left=right;right=temp;}

void swap(Node* left, Node* right) {Node* temp=left; left=right;right=temp;}

void swap(Node*& left, Node*& right) {Node* temp=left; left=right;right=temp;}

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

115

116

1895

1896

问答题:

1)前序遍历

递归代码:

public static void preorderTraversalRec(TreeNode root){

if (root == null) {

return;

}

System.out.print(root.val + "->");

preorderTraversalRec(root.left);

preorderTraversalRec(root.right);

}

非递归代码:

public void preOrder1(BinaryNode Node)

{

Stack stack = new Stack<>();

while(Node != null || !stack.empty())

{

while(Node != null)

{

System.out.print(Node.element + " ");

stack.push(Node);

Node = Node.left;

}

if(!stack.empty())

{

Node = stack.pop();

Node = Node.right;

}

}

}

1)中序遍历

递归代码:

public static void inorderTraversalRec(TreeNode root){ if (root == null) {

return;

}

inorderTraversalRec(root.left);

System.out.print(root.val + "->");

inorderTraversalRec(root.right);

}

非递归代码:

public void midOrder1(BinaryNode Node) {

Stack stack = new Stack<>();

while(Node != null || !stack.empty())

{

while (Node != null)

{

stack.push(Node);

Node = Node.left;

}

if(!stack.empty())

{

Node = stack.pop();

System.out.print(Node.element + " ");

Node = Node.right;

}

}

}

2)后序遍历

递归代码:

public static void postorderTraversalRec(TreeNode root){ if (root == null) {

return;

}

postorderTraversalRec(root.left);

postorderTraversalRec(root.right);

System.out.print(root.val + "->");

}

非递归代码:

public void posOrder1(BinaryNode Node) {

Stack stack1 = new Stack<>();

Stack stack2 = new Stack<>();

int i = 1;

while(Node != null || !stack1.empty())

{

while (Node != null)

{

stack1.push(Node);

stack2.push(0);

Node = Node.left;

}

while(!stack1.empty() && stack2.peek() == i)

{

stack2.pop();

System.out.print(stack1.pop().element + " ");

}

if(!stack1.empty())

{

stack2.pop();

stack2.push(1);

Node = stack1.peek();

Node = Node.right;

}

}

}

3)层序遍历

递归代码:

public static void levelTraversal(TreeNode root){

if(root == null) {

return;

}

Queue queue = new LinkedList<>(); // 对列保存树节点queue.add(root);

while (!queue.isEmpty()) {

TreeNode temp = queue.poll();

System.out.print(temp.val + "->");

if (temp.left != null) { // 添加左右子节点到对列

queue.add(temp.left);

}

if (temp.right != null) {

queue.add(temp.right);

}

}

}

非递归代码:

public void levelOrder1(BinaryNode Node) {

if (Node == null) {

return;

}

BinaryNode binaryNode;

Queue queue = new LinkedList<>();

queue.add(Node);

while (queue.size() != 0) {

binaryNode = queue.poll();

System.out.print(binaryNode.element + " ");

if (binaryNode.left != null) {

queue.offer(binaryNode.left);

}

if (binaryNode.right != null) {

queue.offer(binaryNode.right);

}

}

}

4)求二叉树中的节点个数

代码:

public static int getNodeNumRec(TreeNode root) {

if (root == null) {

return 0;

}

return getNodeNumRec(root.left) + getNodeNumRec(root.right) + 1; }

5)求二叉树的深度(高度)

代码:

public static int getDepth(TreeNode root) {

if (root == null) {

return 0;

}

int currentLevelCount = 1; // 当前层的节点数量

int nextLevelCount = 0; // 下一层节点数量

int depth = 0; // 树的深度

Queu面试题:

e queue = new LinkedList<>(); // 对列保存树节点

queue.add(root);

while (!queue.isEmpty()) {

TreeNode temp = queue.remove(); // 移除节点

currentLevelCount--; // 当前层节点数减1

if (temp.left != null) { // 添加左节点并更新下一层节点个数

queue.add(temp.left);

nextLevelCount++;

}

if (temp.right != null) { // 添加右节点并更新下一层节点个数

queue.add(temp.right);

nextLevelCount++;

}

if (currentLevelCount == 0) { // 如果是该层的最后一个节点,树的深度加1 depth++;

currentLevelCount = nextLevelCount; // 更新当前层节点数量并且重置下一层节点数量

nextLevelCount = 0;

}

}

return depth;

}

6)求二叉树第k层的节点个数

代码:

public static int getNodeNumKthLevelRec(TreeNode root, int k) {

if (root == null || k < 1) {

return 0;

}

if (k == 1) {

return 1;

}

return getNodeNumKthLevelRec(root.left, k - 1) + getNodeNumKthLevelRec(root.right, k - 1); }

7)求二叉树中叶子节点的个数

代码:

public static int getNodeNumLeafRec(TreeNode root) {

if (root == null) {

return 0;

}

if (root.left == null && root.right == null) {

return 1;

}

return getNodeNumLeafRec(root.left) + getNodeNumLeafRec(root.right);

}

8)判断两棵二叉树是否相同的树

代码:

public static boolean isSameRec(TreeNode r1, TreeNode r2) {

if (r1 == null && r2 == null) { // 都是空

return true;

} else if (r1 == null || r2 == null) { // 有一个为空,一个不为空

return false;

}

if (r1.val != r2.val) { // 两个不为空,但是值不相同

return false;

}

return isSameRec(r1.left, r2.left) && isSameRec(r1.right, r2.right); // 递归遍历左右子节点}

9)求二叉树的镜像

代码:

public static TreeNode mirrorRec(TreeNode root) {

if (root == null) {

return root;

}

TreeNode left = mirrorRec(root.right); // 递归镜像左右子树

TreeNode right = mirrorRec(root.left);

root.left = left; // 更新根节点的左右子树为镜像后的树

root.right = right;

return root;

}

10)判断两个二叉树是否互相镜像

代码:

public static boolean isMirrorRec(TreeNode r1, TreeNode r2) {

if (r1 == null && r2 == null) {

return true;

} else if (r1 == null || r2 == null) {

return false;

}

if (r1.val != r2.val) {

return false;

}

// 递归比较r1的左子树的镜像是不是r2右子树

// 和r1的右子树的镜像是不是r2的左子树

return isMirrorRec(r1.left, r2.right) && isMirrorRec(r1.right, r2.left);

}

11)求二叉树中两个节点的最低公共祖先节点

代码:

public static TreeNode getLastCommonParentRec2(TreeNode root, TreeNode n1, TreeNode n2) { if (root == null) {

return null;

}

// 如果有一个match,则说明当前node就是要找的最低公共祖先

if (root.equals(n1) || root.equals(n2)) {

return root;

}

TreeNode commonLeft = getLastCommonParentRec2(root.left, n1, n2);

TreeNode commonRight = getLastCommonParentRec2(root.right, n1, n2);

// 如果一个在左子树找到,一个在右子树找到,则说明root是唯一可能得最低公共祖先

if (commonLeft != null && commonRight != null) {

return root;

}

// 其他情况是要不然在左子树要不然在右子树

if (commonLeft != null) {

return commonLeft;

}

return commonRight;

}

12)判断是否为二分查找树BST

代码:

public boolean isValidBST2(TreeNode root){

Stack stack = new Stack<>();

//设置前驱节点

TreeNode pre = null;

while(root != null || !stack.isEmpty()){

while (root != null) { // 将当前节点,以及左子树一直入栈,循环结束时,root==null stack.push(root);

root = root.left;

}

root = stack.pop();

//比较并更新前驱,与普通遍历的区别就在下面四行

if(pre != null && root.val <= pre.val){

return false;

}

数据结构与算法模拟试题

一、选择题 1.在逻辑上可以把数据结构分成() A.线性结构和非线性结构 B.动态结构和静态结构 C.紧凑结构和非紧凑结构 D.内部结构和外部结构 2.单链表中各结点之间的地址() A.必须连续 B.部分必须连续 C.不一定连续 D.以上均不对 3.在一个长度为n的顺序表中向第i个元素(0front==L C.P==NULL D.P->rear==L 12. 已知P为单链表中的非首尾结点,删除P结点的后继结点Q的语句为()。 A.P->NEXT=Q->NEXT;FREE(Q); B.Q->NEXT=P; FREE(Q); C.Q->NEXT=P->NEXT;FREE(Q); D.P->NEXT=S;S->NEXT=P; 13.循环队列SQ队满的条件是()。 A.SQ->rear==SQ->front B. (SQ->rear+1)%MAXLEN==SQ->front C.SQ->rear==0 D. SQ->front==0 14.一组记录的排序码为(46,79,56,38,40,84),则利用堆排序的方法建立的初始堆为()。 A、79,46,56,38,40,80 B、84,79,56,38,40,46 C、84,79,56,46,40,38 D、84,56,79,40,46,38 15.排序趟数与序列原始状态(原始排列)有关的排序方法是()方法。 A、插入排序 B、选择排序 C、冒泡排序 D、快速排序 16.下列排序方法中,()是稳定的排序方法。 A、直接选择排序 B、二分法插入排序

力 扣 数 据 结 构 与 算 法

前端如何搞定数据结构与算法(先导篇) 「观感度:?」 「口味:锅包肉」 「烹饪时间:20min」 本文已收录在Github? 为什么要学习数据结构与算法? 在0202年的今天,由于每天被无数的信息轰炸,大多数人已经变得越来越浮躁了,并且丧失了独立思考的能力。 你可能会经常听到这样的感慨: 技术人究竟能走多远?我遇到了天花板 35岁的程序员要如何面对中年危机? 技术更新太快,好累,学不动了 然后,你也变得焦虑起来。那你有没有静下心来想过,如何才能抵御年龄增长并且使自己增值呢? 无非是终身学习,持续修炼自己的内功。内功也就是基础知识和核心概念,这些轰轰烈烈发展的技术本质,其实都是基础知识,也就是我们在大学里学过的基础课-程。 操作系统 计算机组成原理 计算机网络 编译原理

设计模式 数据结构与算法 这也就是为什么越靠谱的面试官越注重你基础知识的掌握程度,为什么越牛的的企业越重视你的算法能力。因为当你拥有了这些,你已经比大多数人优秀了。你的天花板由你自己来决定,大家口中的中年危机可能并不会成为你的危机。新技术来临时,你对它的本质会看得更加透彻,学起来会一通百通。这样的人才,公司培养你也会花费更少的成本。 (不过,一辈子做个开开心心的 CRUD Boy 也是一种选择。) 数据结构与算法之间的关系 Rob Pikes 5 Rules of Programming中的第五条是这样说的: Data dominates. If youve chosen the right data structures and organized things well, the algorithms will almost always be self-evident. Data structures, not algorithms, are central to programming. 数据占主导。如果您选择了正确的数据结构并组织得当,那么这些算法几乎总是不言而喻的。数据结构而非算法是编程的核心。 瑞士计算机科学家,Algol W,Modula,Oberon 和 Pascal 语言的设计师 Niklaus Emil Wirth 写过一本非常经典的书《Algorithms + Data Structures = Programs》,即算法 + 数据结构 = 程序。 我们可以得出结论,数据结构与算法之间是相辅相成的关系。数据结构服务于算法,算法作用于特定的数据结构之上。 数据结构与算法好难,怎么学?

数据结构与算法复习题10(C语言版)

习 9解答 判断题: 1.用向量和单链表表示的有序表均可使用折半查找方法来提高查找速度。 答:FALSE (错。链表表示的有序表不能用折半查找法。) 2.有n 个数据放在一维数组A[1..n]中,在进行顺序查找时,这n 个数的排列有序或无序其平均查找长度不同。 答:FALSE (错。因顺序查找既适合于有序表也适合于无序表;对这两种表,若对于每个元素的查找概率相等,则顺序查找的ASL 相同,并且都是(n+1)/2;对于查找概率不同的情况,则按查找概率由大到小排序的无序表其ASL 要比有序表的ASL 小。) 3.折半查找是先确定待查有序表记录的范围,然后逐步缩小范围,直到找到或找不到该记录为止。( ) 答:TRUE 4.哈希表的查找效率主要取决于哈希表哈希表造表时选取的哈希函数和处理冲突的方法。 答:TRUE 5.查找表是由同一类型的数据元素(或记录)构成的集合。 答:TRUE 单选题: 6.对于18个元素的有序表采用二分(折半)查找,则查找A[3]的比较序列的下标为( )。 A. 1、2、3 B. 9、5、2、3 C. 9、5、3 D.9、4、2、3 答:D (第一次??2/)181(+ = 9,第二次??2/)81(+ = 4,第三次??2/)31(+ = 2, (第四次??2/)33(+ = 3,故选D. 7. 顺序查找法适合于存储结构为____________的线性表。 A.散列存储 B.顺序存储或链式存储 C.压缩存储 D.索引存储 答:B 8.对线性表进行二分查找时,要求线性表必须( )。 A .以顺序方式存储 B. 以链接方式存储 C .以顺序方式存储,且结点按关键字有序排序 D. 以链接方式存储,且结点按关键字有序排序 答:C 9.设哈希表长m=14,哈希函数为H(k) = k MOD 11。表中已有4个记录(如下图

数据结构与算法习题及答案

第1章绪论 习题 1.简述下列概念:数据、数据元素、数据项、数据对象、数据结构、逻辑结构、存储结构、抽象数据类型。2.试举一个数据结构的例子,叙述其逻辑结构和存储结构两方面的含义和相互关系。 3.简述逻辑结构的四种基本关系并画出它们的关系图。 4.存储结构由哪两种基本的存储方法实现 5.选择题 (1)在数据结构中,从逻辑上可以把数据结构分成()。 A.动态结构和静态结构B.紧凑结构和非紧凑结构 C.线性结构和非线性结构D.内部结构和外部结构 (2)与数据元素本身的形式、内容、相对位置、个数无关的是数据的()。 A.存储结构B.存储实现 C.逻辑结构D.运算实现 (3)通常要求同一逻辑结构中的所有数据元素具有相同的特性,这意味着()。 A.数据具有同一特点 B.不仅数据元素所包含的数据项的个数要相同,而且对应数据项的类型要一致 C.每个数据元素都一样 D.数据元素所包含的数据项的个数要相等 (4)以下说法正确的是()。 A.数据元素是数据的最小单位 B.数据项是数据的基本单位 C.数据结构是带有结构的各数据项的集合 D.一些表面上很不相同的数据可以有相同的逻辑结构 (5)以下与数据的存储结构无关的术语是()。 A.顺序队列B.链表C.有序表D.链栈 (6)以下数据结构中,()是非线性数据结构 A.树B.字符串C.队D.栈 6.试分析下面各程序段的时间复杂度。 (1)x=90;y=100; while(y>0) if(x>100) {x=x-10;y--;} elsex++; (2)for(i=0;i

[第1题-60题汇总]微软数据结构+算法面试100题

精选微软等公司数据结构 精选微软等公司数据结构++算法面试100题 -----[第1题-60题总] 资源说明: 此份,是为微软等公司数据结构+算法面试100题,之前60题的汇总。 总结整理了前第1题-第60题。特此并作此一份上传。以飨各位。:)。 -------------------------------- 相关资源,包括答案,下载地址: [答案V0.2版]精选微软数据结构+算法面试100题[前20题]--答案修正 https://www.doczj.com/doc/5c1451343.html,/source/2813890 //此份答案是针对最初的V0.1版本,进行的校正与修正。 [答案V0.1版]精选微软数据结构+算法面试100题[前25题] https://www.doczj.com/doc/5c1451343.html,/source/2796735 [第二部分]精选微软等公司结构+算法面试100题[前41-60题]: https://www.doczj.com/doc/5c1451343.html,/source/2811703 [第一部分]精选微软等公司数据结构+算法经典面试100题[1-40题] https://www.doczj.com/doc/5c1451343.html,/source/2778852 更多资源,下载地址: http://v_july_https://www.doczj.com/doc/5c1451343.html,/ 很快,我将公布第21-40题的答案,敬请期待。:).. 如果你对以下的前第1-60题,有好的思路,和算法,欢迎跟帖回复, 或者,联系我,发至我的邮箱, zhoulei0907@https://www.doczj.com/doc/5c1451343.html,。 My CSDN Blog:https://www.doczj.com/doc/5c1451343.html,/v_JULY_v My sina Blog:https://www.doczj.com/doc/5c1451343.html,/shitou009 帖子维护地址: [整理]算法面试:精选微软经典的算法面试100题[前1-60题] https://www.doczj.com/doc/5c1451343.html,/u/20101023/20/5652ccd7-d510-4c10-9671-307a56006e6d.html -------------------------------------- July、2010、/11.12.请享用。:)。 1

北京交通大学数据结构与算法期末测验考试参考答案

北京交通大学考试试题(A卷) 课程名称:数据结构与算法2011-2012学年第一学期出题教师:张勇 (请考生注意:(1)本试卷共有六道大题,(2)答案一律写在答题纸上,(3)试卷不得带出考场) 1. 在顺序表中访问任意一个元素的时间复杂度均为,因此顺序表也称为 的数据结构。 2.三维数组a[4][3][2](下标从0开始),假设a[0][0][0]的地址为50,数据以行序优先方式存储,每个元素的长度为2字节,则a[2][1][1]的地址是。 3. 直接插入排序用监视哨的作用是。 4. 已知广义表Ls=(a, (b, c), (d, e)), 运用head和tail函数取出Ls中的原子d的运算 是。 5.对有14个元素的有序表A[1..14]进行折半查找,当比较到A[4]时算法结束。被比较元素除A[4]外,还有。 6. 在AOV网中,顶点表示,边表示。 7. 有向图G可进行拓扑排序的判别条件是。 8. 若串S1=‘ABCDEFGHIJK’,S2=‘451223’,S3=‘####’,则执行 Substring(S1,Strlength(S3),Index(S2,‘12’,1))的结果是。 二、选择题(每空2分,共20分) 1.在下列存储形式中,哪一个不是树的存储形式?() A.双亲表示法B.孩子链表表示法 C.孩子兄弟表示法D.顺序存储表示法 2.查找n个元素的有序表时,最有效的查找方法是()。 A.顺序查找B.分块查找 C.折半查找D.二叉查找 3.将所示的s所指结点加到p所指结点之后,其语句应为()。 p (A) s->next=p+1 ; p->next=s;

(B) (*p).next=s; (*s).next=(*p).next; (C) s->next=p->next ; p->next=s->next; (D) s->next=p->next ; p->next=s; 4. 在有向图的邻接表存储结构中,顶点v 在链表中出现的次数是( )。 A. 顶点v 的度 B. 顶点v 的出度 C. 顶点v 的入度 D. 依附于顶点v 的边数 5. 算法的时间复杂度为O (nlog 2n )、空间复杂度为O(1)的排序算法是( )。 A. 堆排序 B. 快速排序 C. 归并排序 D.直接选择 6. 设矩阵A 是一个对称矩阵,为了节省存储,将其 下三角部分(如右图所示)按行序存放在一维数组B[ 1, n(n-1)/2 ]中,对下三角部分中任一元素ai,j(i ≤j), 在一维数组B 中下标k 的值是( ): A.i(i-1)/2+j-1 B.i(i-1)/2+j C.i(i+1)/2+j-1 D.i(i+1)/2+j 7. 由一个长度为11的有序表,按二分查找法对该表进行查找,在表内各元素等概率情 况下,查找成功的平均查找长度是( )。 A .29/11 B. 31/11 C. 33/11 D.35/11 8. AVL 树是一种平衡的二叉排序树,树中任一结点的( )。 A. 左、右子树的高度均相同 B. 左、右子树高度差的绝对值不超过1 C. 左子树的高度均大于右子树的高度 D. 左子树的高度均小于右子树的高度 9. 下列四种排序方法中,不稳定的方法是( )。 A. 直接插入排序 B. 冒泡排序 C. 归并排序 D. 堆排序 10. 设树的度为4,其中度为1,2,3,4的结点个数分别为4, 2, ,1, 1, 则T 中的叶子数为 ( )。 A .5 B .6 C .7 D .8 三、 判断题(10分,每小题1分) 1. 顺序存储方式的优点是存储密度大,且插入、删除运算效率高。( ) 2. 数组不适合作任何二叉树的存储结构。( ) 3. 广义表的取表尾运算,其结果通常是个表,但有时也可是个原子。( ) 4. 在含有n 个结点的树中,边数只能是n-1条。( ) 5. 所谓一个排序算法是否稳定,是指该算法在各种情况下的效率是否相差不大。( ) 6. 简单选择排序在最好情况下的时间复杂度为O(n)。( ) 7. 在二叉排序树中插入一个新结点,总是插入到叶结点下面。( ) 8. 采用线性探测处理冲突,当从哈希表中删除一个记录时,不应将该记录所在位置置 空,因为这会影响以后的查找。( ) 9. 有n 个数存放在一维数组A[1..n]中,在进行顺序查找时,这n 个数的排列有序或无 ?????? ? ???? ? ??=n n n n a a a a a a A ,2,1,2 ,21,21 ,1Λ Λ

阿里校园招聘历年经典面试题汇总:算法工程师

阿里校园招聘历年经典面试题汇总:算法工程师 (1)、jvm 原理 (2)、minor GC 与 Full GC (3)、HashMap 实现原理 (4)、java.util.concurrent 包下使用过哪些 (5)、concurrentMap 和 HashMap 区别 (6)、信号量是什么,怎么使用? (7)、阻塞队列了解吗?怎么使用? (8)、JAVA NIO 是什么? (9)、类加载机制是怎样的 (10)、什么是幂等性 (11)、有哪些 JVM 调优经验 (12)、分布式 CAP 了解吗? (13)、hdfs怎么添加Datanode,添加后hdfs会有什么操作? (14)、Hbase 跟关系数据库对比优缺点?为什么 Hbase 索引速度快 (15)、Hbase 大压缩与小压缩区别 (16)、Hive 与 Hbase 的使用场景 (17)、简单说说Spark功能,spark 与hive有无依赖关系? (18)、zookeeper 有什么应用场景,怎么选举的?3 个节点挂掉一个能正常工作吗? (19)、Hbase 中 zookeaper 作用 (20)、Hbase 写操作什么时候返回 (21)、mysql 有哪些存储引擎?各自特点 (22)、用过哪些设计模式?怎样实现线程安全单例模式? (23)、用过哪些RPC框架? (24)、什么是AOP? (25)、决策树算法怎么实现的? (26)、java垃圾回收会出现不可回收的对象吗?怎么解决内存泄露问题?怎么

定位问题源? (27)、终止线程有几种方式?终止线程标记变量为什么是 valotile 类型?(28)、用过哪些并发的数据结构? cyclicBarrier 什么功能?信号量作用?数据库读写阻塞怎么解决? (29)、乐观锁与悲观锁,怎么实现乐观锁? (30)、开发过分布式框架?怎么实现分布式事务? (31)、spark streaming与storm区别? (32)、找到最大子数组的 start,和end下标 (33)、用过 CDH中什么任务调度? (34)、spark streaming时间间隔设置很小会出现什么状况? (35)、搜索引擎了解多少?你认为搜索引擎的难点在哪里? (36)、RPC 了解吗?怎么监控 RPC 状态,找出出现问题的 RPC 连接?(37)、spring 框架了解多少? (38)、flume应用场景 (39)、找出一串字符中第一个不重复字符的下标。 点击查看详细面经〉〉〉〉〉〉〉〉〉〉〉〉 更多精品干货>>>>>>>>>>> 更多阿里机器学习/数据挖掘经典面试题 其他名企机器学习/数据挖掘经典面试题

数据结构与算法复习题及参考答案

复习题集─参考答案 一判断题 (√)1. 在决定选取何种存储结构时,一般不考虑各结点的值如何。 (√)2. 抽象数据类型与计算机部表示和实现无关。 (×)3. 线性表采用链式存储结构时,结点和结点部的存储空间可以是不连续的。 (×)4. 链表的每个结点中都恰好包含一个指针。 (×)5.链表的删除算法很简单,因为当删除链中某个结点后,计算机会自动地将后续的各个单元向前移动。(×)6. 线性表的每个结点只能是一个简单类型,而链表的每个结点可以是一个复杂类型。 (×)7. 顺序表结构适宜于进行顺序存取,而链表适宜于进行随机存取。 (×)8. 线性表在物理存储空间中也一定是连续的。 (×)9. 顺序存储方式只能用于存储线性结构。 (√)10.栈是一种对所有插入、删除操作限于在表的一端进行的线性表,是一种后进先出型结构。 (√)11.对于不同的使用者,一个表结构既可以是栈,也可以是队列,也可以是线性表。 (√)12.栈是一种对所有插入、删除操作限于在表的一端进行的线性表,是一种后进先出型结构。 (√)13.两个栈共享一片连续存空间时,为提高存利用率,减少溢出机会,应把两个栈的栈底分别设在这片存空间的两端。 (×)14.二叉树的度为2。 (√)15.若二叉树用二叉链表作存贮结构,则在n个结点的二叉树链表中只有n—1个非空指针域。 (×)16.二叉树中每个结点的两棵子树的高度差等于1。 (√)17.用二叉链表法存储包含n个结点的二叉树,结点的2n个指针区域中有n+1个为空指针。 (√)18.具有12个结点的完全二叉树有5个度为2的结点。 (√)19.二叉树的前序遍历序列中,任意一个结点均处在其孩子结点的前面。 (×)20.在冒泡法排序中,关键值较小的元素总是向前移动,关键值较大的元素总是向后移动。 (×)21.计算机处理的对象可以分为数据和非数据两大类。[计算机处理的对象都是数据] (×)22.数据的逻辑结构与各数据元素在计算机中如何存储有关。 (×)23.算法必须用程序语言来书写。 (×)24.判断某个算法是否容易阅读是算法分析的任务之一。 (×)25.顺序表是一种有序的线性表。[任何数据结构才用顺序存储都叫顺序表] (√)26.分配给顺序表的存单元地址必须是连续的。 (√)27.栈和队列具有相同的逻辑特性。[它们的逻辑结构都是线性表] (√)28.树形结构中每个结点至多有一个前驱。 (×)29.在树形结构中,处于同一层上的各结点之间都存在兄弟关系。 (×)30.如果表示图的邻接矩阵是对称矩阵,则该图一定是无向图。 (×)31.如果表示图的邻接矩阵是对称矩阵,则该图一定是有向图。 (×)32.顺序查找方法只能在顺序存储结构上进行。 (×)33.折半查找可以在有序的双向链表上进行。

数据结构与算法分析习题与参考答案

大学 《数据结构与算法分析》课程 习题及参考答案 模拟试卷一 一、单选题(每题 2 分,共20分) 1.以下数据结构中哪一个是线性结构?( ) A. 有向图 B. 队列 C. 线索二叉树 D. B树 2.在一个单链表HL中,若要在当前由指针p指向的结点后面插入一个由q指向的结点, 则执行如下( )语句序列。 A. p=q; p->next=q; B. p->next=q; q->next=p; C. p->next=q->next; p=q; D. q->next=p->next; p->next=q; 3.以下哪一个不是队列的基本运算?() A. 在队列第i个元素之后插入一个元素 B. 从队头删除一个元素 C. 判断一个队列是否为空 D.读取队头元素的值 4.字符A、B、C依次进入一个栈,按出栈的先后顺序组成不同的字符串,至多可以组成( ) 个不同的字符串? A.14 B.5 C.6 D.8 5.由权值分别为3,8,6,2的叶子生成一棵哈夫曼树,它的带权路径长度为( )。 以下6-8题基于图1。 6.该二叉树结点的前序遍历的序列为( )。 A.E、G、F、A、C、D、B B.E、A、G、C、F、B、D C.E、A、C、B、D、G、F D.E、G、A、C、D、F、B 7.该二叉树结点的中序遍历的序列为( )。 A. A、B、C、D、E、G、F B. E、A、G、C、F、B、D C. E、A、C、B、D、G、F E.B、D、C、A、F、G、E 8.该二叉树的按层遍历的序列为( )。

A.E、G、F、A、C、D、B B. E、A、C、B、D、G、F C. E、A、G、C、F、B、D D. E、G、A、C、D、F、B 9.下面关于图的存储的叙述中正确的是( )。 A.用邻接表法存储图,占用的存储空间大小只与图中边数有关,而与结点个数无关 B.用邻接表法存储图,占用的存储空间大小与图中边数和结点个数都有关 C. 用邻接矩阵法存储图,占用的存储空间大小与图中结点个数和边数都有关 D.用邻接矩阵法存储图,占用的存储空间大小只与图中边数有关,而与结点个数无关 10.设有关键码序列(q,g,m,z,a,n,p,x,h),下面哪一个序列是从上述序列出发建 堆的结果?( ) A. a,g,h,m,n,p,q,x,z B. a,g,m,h,q,n,p,x,z C. g,m,q,a,n,p,x,h,z D. h,g,m,p,a,n,q,x,z 二、填空题(每空1分,共26分) 1.数据的物理结构被分为_________、________、__________和___________四种。 2.对于一个长度为n的顺序存储的线性表,在表头插入元素的时间复杂度为_________, 在表尾插入元素的时间复杂度为____________。 3.向一个由HS指向的链栈中插入一个结点时p时,需要执行的操作是________________; 删除一个结点时,需要执行的操作是______________________________(假设栈不空而 且无需回收被删除结点)。 4.对于一棵具有n个结点的二叉树,一个结点的编号为i(1≤i≤n),若它有左孩子则左 孩子结点的编号为________,若它有右孩子,则右孩子结点的编号为________,若它有 双亲,则双亲结点的编号为________。 5.当向一个大根堆插入一个具有最大值的元素时,需要逐层_________调整,直到被调整 到____________位置为止。 6.以二分查找方法从长度为10的有序表中查找一个元素时,平均查找长度为________。 7.表示图的三种常用的存储结构为_____________、____________和_______________。 8.对于线性表(70,34,55,23,65,41,20)进行散列存储时,若选用H(K)=K %7 作为散列函数,则散列地址为0的元素有________个,散列地址为6的有_______个。 9.在归并排序中,进行每趟归并的时间复杂度为______,整个排序过程的时间复杂度为 ____________,空间复杂度为___________。 10.在一棵m阶B_树上,每个非树根结点的关键字数目最少为________个,最多为________ 个,其子树数目最少为________,最多为________。 三、运算题(每题 6 分,共24分) 1.写出下列中缀表达式的后缀形式: (1)3X/(Y-2)+1 (2)2+X*(Y+3) 2.试对图2中的二叉树画出其: (1)顺序存储表示的示意图; (2)二叉链表存储表示的示意图。 3.判断以下序列是否是小根堆? 如果不是, 将它调 图2 整为小根堆。 (1){ 12, 70, 33, 65, 24, 56, 48, 92, 86, 33 } (2){ 05, 23, 20, 28, 40, 38, 29, 61, 35, 76, 47, 100 } 4.已知一个图的顶点集V和边集E分别为: V={1,2,3,4,5,6,7};

数据结构算法面试100题

数据结构+算法面试100题~~~摘自CSDN,作者July 1.把二元查找树转变成排序的双向链表(树) 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。 要求不能创建任何新的结点,只调整指针的指向。 10 / / 6 14 / / / / 4 8 12 16 转换成双向链表 4=6=8=10=12=14=16。 首先我们定义的二元查找树节点的数据结构如下: struct BSTreeNode { int m_nValue; // value of node BSTreeNode *m_pLeft; // left child of node BSTreeNode *m_pRight; // right child of node }; 2.设计包含min函数的栈(栈) 定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。 要求函数min、push以及pop的时间复杂度都是O(1)。 参见C:\Users\Administrator\Desktop\demo\Stack 分析:min时间复杂度要达到O(1),需要我们在栈中存储最小元素 3.求子数组的最大和(数组) 题目: 输入一个整形数组,数组里有正数也有负数。 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。要求时间复杂度为O(n)。 例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,因此输出为该子数组的和18。 分析:根据dp思想 #include #define N 8 int main() { int i, a[N] = {1, -2, 3, 10, -4, 7, 2, -5}; int from[N], result[N], max;

数据结构与算法试题

数据结构与算法试题 一、单选题 1、在数据结构的讨论中把数据结构从逻辑上分为 (C ) A 内部结构与外部结构 B 静态结构与动态结构 C 线性结构与非线性结构 D 紧凑结构与非紧凑结构。 2、采用线性链表表示一个向量时,要求占用的存储空间地址(D ) A 必须就是连续的 B 部分地址必须就是连续的 C 一定就是不连续的 D 可连续可不连续 3、采用顺序搜索方法查找长度为n的顺序表时,搜索成功的平均搜索长度为( D )。 A n B n/2 C (n-1)/2 D (n+1)/2 4、在一个单链表中,若q结点就是p结点的前驱结点,若在q与p之间插入结点s,则执行( D )。 A s→link = p→link;p→link = s; B p→link = s; s→link = q; C p→link = s→link;s→link = p; D q→link = s;s→link = p; 5、如果想在4092个数据中只需要选择其中最小的5个,采用( C )方法最好。 A 起泡排序 B 堆排序 C 锦标赛排序 D 快速排序 6、设有两个串t与p,求p在t中首次出现的位置的运算叫做( B )。 A 求子串 B 模式匹配 C 串替换 D 串连接 7、在数组A中,每一个数组元素A[i][j]占用3个存储字,行下标i从1到8,列下标j从1到10。所有数组元素相继存放于一个连续的存储空间中,则存放该数

组至少需要的存储字数就是( C )。 A 80 B 100 C 240 D 270 8、将一个递归算法改为对应的非递归算法时,通常需要使用( A )。 A 栈 B 队列 C 循环队列 D 优先队列 9、一个队列的进队列顺序就是1, 2, 3, 4,则出队列顺序为( C )。 10、在循环队列中用数组A[0、、m-1] 存放队列元素,其队头与队尾指针分别为front与rear,则当前队列中的元素个数就是( D )。 A ( front - rear + 1) % m B ( rear - front + 1) % m C ( front - rear + m) % m D ( rear - front + m) % m 11、一个数组元素a[i]与( A )的表示等价。 A *(a+i) B a+i C *a+i D &a+i 12、若需要利用形参直接访问实参,则应把形参变量说明为( B )参数。 A 指针 B 引用 C 值 D 变量 13、下面程序段的时间复杂度为( C ) for (int i=0;i

典型数据结构面试题

数据结构 1?在一个单链表中p所指结点之前插入一个s (值为e)所指结点时,可执行如下操作: q=head; while (q->next!=p)q=q->next; s= newNode;s->data=e; q->next=;// 填空 s->next=;// 填空 2.线性表的顺序存储结构是一种的存储结构,而链式存储结构是一种___的 存储结构。 A.随机存取 B.索引存取 C.顺序存取 D.散列存取 3.线性表若采用链式存储结构时,要求内存中可用存储单元的地址___。 A.必须是连续的 B.部分地址必须是连续的 C.一定是不连续的 D.连续或不连续都可以 4?在一个单链表中,已知q所指结点是p所指结点的前驱结点,若在q和p 之间插入s结点,则执行_。 A.s->next=p->next;p->next=s; B.p->next=s->next;s->next=p;

C.q->next=s;s->next=p; D.p->next=s;s->next=q; 5.在一个单链表中,若p 所指结点不是最后结点,在p 之后插入s 所指结点,则执行__。 A.s->next=p;p->next=s; B.s->next=p->next;p->next=s; C.s->next=p->next;p=s; C. p->next=s;s->next=p; 6.在一个单链表中,若删除p 所指结点的后续结点,则执行__。 A.p->next= p->next->next; B.p= p->next;p->next= p->next->nex;t C.p->next= p->next; D.p= p->next->next; 7.链表不具备的特点是__。 A 可随机访问任何一个元素 B 插入、删除操作不需要移动元素 C无需事先估计存储空间大小D所需存储空间与线性表长度成正比 8.以下关于线性表的说法不正确的是。 A 线性表中的数据元素可以是数字、字符、记录等不同类型。 B 线性表中包含的数据元素个数不是任意的。 C 线性表中的每个结点都有且只有一个直接前趋和直接后继。 D 存在这样的线性表:表中各结点都没有直接前趋和直接后继。 9?在一个长度为n的顺序表中删除第i个元素,要移动个元素。如果要在第 i 个元素前插入一个元素,要后移()个元素。N-I N-I+1

算法与数据结构试题及答案

数据结构模拟试题... 一、简答题(15分,每小题3分) 1.简要说明算法与程序的区别。 2.在哈希表中,发生冲突的可能性与哪些因素有关?为什么? 3.说明在图的遍历中,设置访问标志数组的作用。 4.说明以下三个概念的关系:头指针,头结点,首元素结点。 5.在一般的顺序队列中,什么是假溢出?怎样解决假溢出问题? 二、判断题(10分,每小题1分) 正确在括号内打√,错误打× ( )(1)广义表((( a ), b), c ) 的表头是(( a ), b),表尾是( c )。 ( )(2)在哈夫曼树中,权值最小的结点离根结点最近。 ( )(3)基数排序是高位优先排序法。 ( )(4)在平衡二叉树中,任意结点左右子树的高度差(绝对值)不超过1。 ( )(5)在单链表中,给定任一结点的地址p,则可用下述语句将新结点s插入结点p的后面:p->next = s; s->next = p->next; ( )(6)抽象数据类型(ADT)包括定义和实现两方面,其中定义是独立于实现的,定义仅给出一个ADT的逻辑特性,不必考虑如何在计算机中实现。 ( )(7)数组元素的下标值越大,存取时间越长。 ( )(8)用邻接矩阵法存储一个图时,在不考虑压缩存储的情况下,所占用的存储空间大小只与图中结点个数有关,而与图的边数无关。 ( )(9)拓扑排序是按AOE网中每个结点事件的最早发生时间对结点进行排序。 ( )(10)长度为1的串等价于一个字符型常量。 三、单项选择题(10分, 每小题1分) 1.排序时扫描待排序记录序列,顺次比较相邻的两个元素的大小,逆序时就交换位置。这是哪种排序方法的基本思想? A、堆排序 B、直接插入排序 C、快速排序 D、冒泡排序 2.已知一个有向图的邻接矩阵表示,要删除所有从第i个结点发出的边,应该: A)将邻接矩阵的第i行删除B)将邻接矩阵的第i行元素全部置为0 C)将邻接矩阵的第i列删除D)将邻接矩阵的第i列元素全部置为0 3.有一个含头结点的双向循环链表,头指针为head, 则其为空的条件是: A.head->priro==NULL B. head->next==NULL C. head->next==head D. head->next-> priro==NULL 4. 在顺序表( 3, 6, 8, 10, 12, 15, 16, 18, 21, 25, 30 ) 中,用折半法查找关键码值11,所需的关键码比

国家二级ACCESS机试选择题(数据结构与算法)模拟试卷15

国家二级ACCESS机试选择题(数据结构与算法)模拟试卷15 (总分:64.00,做题时间:90分钟) 一、选择题(总题数:32,分数:64.00) 1.设循环队列为Q(1:m),其初始状态为front=rear=m。经过一系列入队与退队运算后,front=15,rear=20。现要在该循环队列中寻找最大值的元素,最坏情况下需要比较的次数为 (分数:2.00) A.4 √ B.6 C.m-5 D.m-6 解析:解析:初始状态为:front=rear=m,rear-front=0,此时队列为空。经过一系列入队与退队运算后,front=15,rear=20。队尾大于队头,则队尾rear减队头front等于5个元素。此时队列中有5个元素,而查找最大项至少要比较n.1次,就是4次。因此选项A正确。 2.下列叙述中正确的是 (分数:2.00) A.循环队列属于队列的链式存储结构 B.双向链表是二叉树的链式存储结构 C.非线性结构只能采用链式存储结构 D.有的非线性结构也可以采用顺序存储结构√ 解析:解析:顺序存储方式不仅能用于存储线性结构,还可以用来存放非线性结构。例如,完全二叉树是属于非线性结构,但其最佳存储方式是顺序存储方式。 3.某二叉树中有n个叶子结点,则该二叉树中度为2l的结点数为 (分数:2.00) A.n+1 B.n-1 √ C.2n D.n/2 解析:解析:任意一棵二叉树,如果叶结点数为N 0,而度数为2的结点总数为N 2,则N 0 =N 2 +1;N 2 =N 0 -1。所以如果二叉树中有n个叶子结点,则该二叉树中度为2的结点数为n-1。因此选项B正确。4.下列叙述中错误的是 (分数:2.00) A.算法的时间复杂度与算法所处理数据的存储结构有直接关系 B.算法的空间复杂度与算法所处理数据的存储结构有直接关系 C.算法的时间复杂度与空间复杂度有直接关系√ D.算法的时间复杂度与空间复杂度没有必然的联系 解析:解析:算法的时间复杂度,是指执行算法所需要的计算工作量。算法的空间复杂度,是指执行这个算法所需要的内存空间。两者与算法所处理数据的存储结构都有直接关系,但两者之间没有直接关系,因此选项C错误。 5.设栈的顺序存储空间为S(0:49),栈底指针bottom=49,栈顶指针top=30(指向栈顶元素)。则栈中的元素个数为 (分数:2.00) A.30 B.29 C.20 √ D.19

全国计算机二级考试 数据结构与算法

全国计算机二级考试 第一章数据结构与算法 1.一个算法一般都可以用_____、_____ 、 _____三种控制结构组合完成。 [解析]顺序、选择(分支)、循环(重复) 一个算法通常由两种基本要素组成:一是对数据对象的运算和操作,二是________。 [解析]算法的控制结构 在一般的计算机系统中,有算术运算、逻辑运算、关系运算和________四类基本的操作和运算。 [解析]数据传输 2.常用于解决“是否存在”或“有多少种可能”等类型的问题(例如求解不定方程的问题)的算法涉及基本方法是() A.列举法 B.归纳法 C.递归法 D.减半递推法 [解析]列举就是列举出所有可能性,将所有可能性统统列举出来,然后解决问题的方法。所以A 3.根据提出的问题,列举所有可能的情况,并用问题中给定的条件检验哪些是需要的,哪些是不需要的,这是算法设计基本方法中的____。 [解析]列举法

4.通过列举少量的特殊情况,经过分析,最后找出一般的关系的算法设计思想是() A.列举法 B.归纳法 C.递归法 D.减半递推法 [解析]B 5.在用二分法求解方程在一个闭区间的实根时,采用的算法设计技术是() A.列举法 B.归纳法 C.递归法 D.减半递推法 [解析]二分法就是从一半处比较,减半递推技术也称分治法,将问题减半。所以D 6.将一个复杂的问题归结为若干个简单的问题,然后将这些较简单的问题再归结为更简单的问题,这个过程可以一直做下去,直到最简单的问题为止,这是算法设计基本方法中的___。如果一个算法P显式地调用自己则称为___。如果算法P调用另一个算法Q,而算法Q又调用算法P,则称为_____. [解析]递归法直接递归间接递归调用 7.算法中各操作之间的执行顺序称为_____。描述算法的工具通常有_____、_____ 、 _____。 [解析]控制结构传统流程图、N-S结构化流程图、算法描述语言 8.从已知的初始条件出发,逐步推出所要求的各中间结果和最后结果,这

数据结构与算法试卷(B卷)

广西科技大学2015 —2016 学年第 1 学期课程考核试题试卷 考核课程数据结构与算法( B 卷)考核班级物联网141 学生数36 印数40 考核方式闭卷考核时间120 分钟 一、单项选择题(在每小题的四个备选答案中,选出一个正确答案。每小题1分,共33分) 1、算法是()。 A. 计算机程序 B. 解决问题的计算方法 C. 排序算法 D. 解决问题的有限运算序列 2、一个顺序表的第一个元素的存储地址是90,每个元素的长度为2,则第8个元素的存储地址是()。 A. 102 B. 104 C. 106 D. 108 3、在一个长度为n的顺序表中删除第i个元素,需要向前移动()个元素。 A. n-i B. n-i+1 C. n-i-1 D. i+1 4、在头指针为head且表长大于1的单循环链表中,指针p指向表中某个结点,若p->next->next==head,则()。 A. p指向头结点 B. p指向尾结点 C. p的直接后继是头结点 D. p的直接后继是尾结点 5、在以下的叙述中,正确的是()。 A. 线性表的顺序存储结构优于链表存储结构 B. 线性表的顺序存储结构适用于频繁插入/删除数据元素的情况 C. 线性表的链表存储结构适用于频繁插入/删除数据元素的情况 D. 线性表的链表存储结构优于顺序存储结构 6、在一个单链表中,已知q所指结点是p所指结点的前驱结点,若在q和p之间插入一个结点s,则执行()。 A. s->next=p->next; p->next=s; B. p->next=s->next; s->next=p; C. q->next=s; s->next=p; D. p->next=s; s->next=q; 7、在双向循环链表中,在p指针所指的结点后插入一个指针q所指向的新结点,修改指针的操作是()。 A. p->next=q; q->prior=p; p->next->prior=q; q->next=q; B. p->next=q; p->next->prior=q; q->prior=p; q->next=p->next; C. q->prior=p; q->next=p->next; p->next->prior=q; p->next=q; D. q->next=p->next; q->prior=p; p->next=q; p->next=q; 8、在单链表中,指针p指向元素为x的结点,实现删除x的后继的语句是()。 A. p=p->next; B. p->next=p->next->next; C. p->next=p; D.p=p->next->next; 9、在表长为n的顺序表中,当在任何位置删除一个元素的概率相同时,删除一个元素所需移动的平均个数为()。 A. (n-1)/2 B. n/2 C. (n+1)/2 D. n 10、将长度为n的单链表连接在长度为m的单链表之后的算法的时间复杂度为()。 A. O(1) B. O(n) C. O(m) D. O(m+n) 11、线性表的顺序存储结构是一种()存储结构。 A. 随机存取 B. 顺序存取 C. 索引存取 D. 散列存取 12、循环链表的主要优点是()。 A. 不再需要头指针 B. 已知某结点位置后能容易找到其直接前驱 C. 在进行插入、删除运算时能保证链表不断开 D. 在表中任一结点出发都能扫描整个链表 13、在下列对顺序表进行的操作中,算法时间复杂度为O(1)的是()。

相关主题
文本预览
相关文档 最新文档