赞
踩
在长度为 X 的顺序表下标为 i 的位置前插入一个元素( 1 ≤ i ≤ X+1 ),元素的移动次数为( )
A. X - i + 1
B. X - i
C. X
D. X-1
答案解析:B
1.顺序表插入元素,需要移动元素,这里需要把[i, X - 1]区间的元素全部向后移动一次,故移动的次数为X - 1 - i +1
2.举一个例子:顺序表中元素为{ 1,2,3,4,5,6,7}总共7个元素,i=3(4的位置)在第i个位置前插入元素data需要搬移元素个数, 需要移动, 7, 6, 5, 4,才能在在原本4之前空出位置插入data, 也符合X-i, 即 7(顺序表长度) -3(i的位置) = 4(移动4次)
综上:选择B选项
现有一循环队列,其队头指针为 front ,队尾指针为 rear ;循环队列长度为 N 。其队内有效长度为?(假设队头不存放数据)( )
A. (rear - front + N) % N + 1
B. (rear - front + N) % N
C. (rear - front) % (N + 1)
D. (rear - front + N) % (N - 1)
答案解析:B
这道题是考虑循环队列,对于循环队列,空间长度为N是固定的
举个简单例子:循环队列为 1,2,3,4,5,6, 空间长度为6
本题中 front 不存数据, 这个要敲黑板
1.如果front <= rear,则(rear-front)> 0, 实际空间长度就是(rear-front)。
举例 front = 1,rear = 4
2.如果front > rear,则(rear-front)< 0,实际长度就是(rear+N-front)。
举例front = 5,rear= 2
结论:为了统一两种情况 所以给出的结果为(rear-front+N)% N
扩展:如果front中也存放数据时,则结果为:(rear-front+1+N)% N
综上:选择B选项
若用一个大小为 6 的数组来实现循环队列,且当 rear 和 front 的值分别为 0 和 3 。当从队列中删除一个元素,再加入两个元素后,rear 和 front 的值分别为( )
A.1和5
B.2和4
C.4和2
D.5和1
答案解析:B
1.队列添加元素是在对尾,删除元素是在对头;
2.添加元素,尾指针rear+1;删除元素,头指针front+1;
3.本题中,删除一个元素,front+1,也就是3+1=4;添加2个元素,rear+2,也就是0+2=2;
可以参考下面的图解:
一个栈的入栈序列为 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
首先,栈的先进后出原则大家应该是知道的。
根据题意 p 2 = 3,可以知道 p1 的可能情况有三种:1,2 或 4 。(看到有些人只想到了 1,2)
为啥这样想呢?这里估计还有一个关键是要考虑到 n 的大小。
当 n = 3 时, p2 = 3 的话,那么 p 1 有两种情况 1 和 2 。
如果 p 1 = 1 , 那么 p 3 = 2 ;
如果 p 1 = 2 ,那么 p 3 = 1 ;
此时的话我们就可以看到 p 3 只有两种可能 1 或者 2 (n - 1)个。
当 n > 3 时: p 2 = 3 的话,那么 p 1 有三种情况 1 , 2 和 4 。
如果 p 1 = 1 , 那么 p 3 = 2,4,5,… n (n - 2)个
如果 p 1 = 2 ,那么 p 3 = 1,4,5,… n (n - 2)个
如果 p 1 = 4 ,那么 p 3 = 2,5,6,… n (n - 3)个
此时的话我们就可以看到 p 3 的情况有 1,2,4,5,… n (n - 1)个。
综上所述就是 p 3 可能取值的个数是 (n - 1)个。
综上:选择C选项
一棵有 n 个结点的二叉树,按层次从上到下、同一层从左到右顺序存储在一维数组 A[1…n] 中,则二叉树中第 i个结点(i从1开始用上述方法编号)的右孩子在数组 A 中的位置是( )
A. A[2i](2i <= n)
B. A[2i + 1](2i + 1 <= n)
C. A[i - 2]
D. 条件不充分,无法确定
答案解析:D
必须是完全二叉树才能确定,若是,选择B选项。如下图所示:
根据二叉树的性质5:
1.对于具有n个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有节点从0开始编号,则对于序号为i的结点有:
1.1 若i>0,i位置节点的双亲序号:(i-1)/2;i=0,i为根节点编号,无双亲节点
1.2 若2i+1<n,左孩子序号:2i+1,2i+1>=n否则无左孩子
1.3 若2i+2<n,右孩子序号:2i+2,2i+2>=n否则无右孩子
上述的性质的节点从0开始编号, 而题目当中是从1开始编号, 所有右孩子的序号为 2i+1
已知-算术表达式的中缀表达式为 a-(b+c/d)*e , 其后缀形式为( )
A. -a+b*c/d
B. -a+b*cd/e
C. -+*abc/de
D. abcd/+e*-
答案解析:D
1.先使用中缀表达式构建二叉树
1.1 第一个 “-”则将表达式分为左右子树, 左子树为“a”, 右子树为“(b+c/d)e”
1.2 在1.1中的右子树“(b+c/d)e”, 通过“”将再次分为左右子树, 左子树为“(b+c/d)”, 右子树为“e”
1.3 在1.2中的左子树“(b+c/d)”, 通过“+”将再次分为左右子树, 左子树为“b”, 右子树为“c/d”
1.4 在1.3中的右子树“c/d”, 通过“/”将再次分为左右子树, 左子树为“c”, 右子树为“d”
所以构建出来的二叉树如下图所示, 后缀表达式也就不难求解, 先左, 再右, 再根, 即“abcd/+e-”
综上:选择D选项
设二叉树的先序遍历序列和后序遍历序列正好相反,则该二叉树满足的条件是( )
A. 空或只有一个结点
B. 高度等于其结点数
C. 任一结点无左孩子
D. 任一结点无右孩子
答案解析:B
先序遍历:根左右;后序遍历:左右根
要满足题意,则只有,根左<----->左根,根右<--------->右根
所以高度一定等于节点数
综上: 选择B选项
具有 1000 个节点的二叉树的最小深度为( )(第一层深度为1)
A. 11
B. 12
C. 9
D. 10
答案解析: D
1.当二叉树为完全二叉树时, 深度最小。
2.根据二叉树的性质“若规定根节点的层数为1,具有n个结点的满二叉树的深度,h=log2(n+1), 计算log2(1001)约等于9.97
3.另一种计算方式: 当第一层深度为1时, 深度为n的满完全二叉树节点为2^n - 1。
所以: 2^n - 1 >= 1000; 则n >= 10;
综上: 选择D选项
【解题思路】:
此题主要考察单链表操作,对链表进行遍历提取节点的值,在把该值化为十进制数即可
int getDecimalValue(struct ListNode* head)
{
int number = 0;
while(head)
{
number = (number << 1) + head->val;//左移一位就是乘以2
head = head->next;
}
return number;
}
此题主要考察单链表的反转操作,核心思路主要是借助临时头结点,找到需要翻转链表的前驱位置,然后将要翻转链表的节点摘下进行子链表的头部插入即可,题目不难,主要就是要注意一些边界条件的处理,以及借助临时头结点后,能够使代码处理更简单。
struct ListNode* reverseBetween(struct ListNode* head, int m, int n ) { // write code here if(head->next == NULL && m == n) { return head; } //借助临时头结点,可以统一所有的情况进行处理,尤其是翻转的链表从第一个节点开始 struct ListNode* newHead = (struct ListNode*)malloc(sizeof(struct ListNode)); newHead->next = head; struct ListNode* prev = newHead; for(int i = 1; i < m; i++) { prev = prev->next; } head = prev->next;//head指向翻转子链表的首部 //取head的下一个来头插 for(int i = m; i < n; i++) { struct ListNode* cur = head->next; head->next = cur->next; cur->next = prev->next; prev->next = cur; } head = newHead->next; free(newHead); newHead = NULL; return head; }
此题主要借助链表考察前缀和的求解,要删去总和值为零的连续链表节点,只需维护每一个节点之前的所有和,此时如果该节点与前面节点的和(即前缀和)相加结果为0,则该节点就可以抵消掉前面的节点,消除的时候就是把next指针指向和的下一个节点,然后在重复该过程,直到整个链表求解结束
struct ListNode* removeZeroSumSublists(struct ListNode* head) { struct ListNode* prev = (struct ListNode*)malloc(sizeof(struct ListNode)); prev->next = head; struct ListNode* p = prev; while(p) { int sum = 0; struct ListNode* q = p->next; //从p位置找到q位置中间和为0的所有节点 while(q) { sum += q->val; if(sum == 0) { struct ListNode* del = p->next; p->next = q->next; q = q->next; //删掉中间节点 while(del != q) { struct ListNode *tmp = del; del = del->next; free(tmp); } } else { q = q->next; } } p = p->next; } head = prev->next; free(prev); prev = NULL; return head; }
【解题思路】:
此题变相考察二叉树的遍历,对二叉树进行先序遍历,用哈希数组判断当前值是否出现过(出现过就是1,未出现就是0),每出现一个没有在哈希数组中统计过的元素哈希数组就新增一个值,最后统计哈希数组有多少不为0的值即可。
int hash[1001]; void PrevOrder(struct TreeNode* root) { if(root == NULL) { return; } hash[root->val]++; PrevOrder(root->left); PrevOrder(root->right); } int numColor(struct TreeNode* root) { memset(hash, 0, sizeof(hash));//全部初始化位0 PrevOrder(root); int num = 0; //统计次数 for(int i = 1; i < 1001; i++) { if(hash[i] != 0) { num++; } } return num; }
此题主要考察二叉树的深度遍历, pathVal: 计算各路径和; sum: 统计各路径和;由于结点值为0,1;表示二进制数,利用二进制计算方法由最高位至最低位: pathVal(pathVal<<1)+root->val ;先序遍历树结点,用 pathVal计算至当前节点的值,当该节点为叶节点则达到路径末尾;此时统计 *sum+=pathVal
void dfs(struct TreeNode* root, int pathVal, int* sum) { if(root == NULL) { return; } pathVal = (pathVal << 1) + root->val; if(root->left == NULL && root->right == NULL) { *sum += pathVal; } dfs(root->left, pathVal, sum); dfs(root->right, pathVal, sum); } int sumRootToLeaf(struct TreeNode* root) { int sum = 0; dfs(root, 0, &sum); return sum; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。