调用一成员函数时, 使用动态联编的情况是?
正确答案: B
通过对象调用一虚函数
通过指针或引用调用一虚函数
通过对象调用静态函数
通过指针或应用调用一静态函数
动态联编就是程序在运行的时候知道该调用哪个函数,而不是编译阶段
所以这个机制应该是由虚函数支持的
即运行时的多态,基类的某个成员函数声明为虚函数,派生类继承,而且同样重写该函数
那么当声明一个派生类的指针或者引用时,它所调用的函数是由该指针指向的对象确定的
这就是动态联编
抽象数据类型与计算机内部表示和实现无关()
正确答案: A
对
错
抽象数据类型的定义取决于它的一组逻辑特性,而与其在计算机内部如何表示和实现无关。
即不论其内部结构如何变化,只要它的数学特性不变,都不影响其外部的使用。
指针变量p进行自加运算(即 执行p++;)后,地址偏移值为1,则其 数据类型为 char。说法是否正确?
正确答案: B
正确
错误
class A
{
};
对于一个什么都没有的类,字节也为1。
递归函数中的形参是()
正确答案: A
自动变量
外部变量
静态变量
可根据需要自定义存储类型
首先要理解的是递归是借助栈来实现的,自动变量是存储在栈里面的,随着递归的进行,自动创建和销毁。
外部变量和静态变量存放在静态存储区。外部变量和静态变量是不能作为递归函数的参数的。。
最后,自动变量可以大体上等价于局部变量。但也不完全相同,是C++11的新特性,很好很强大。
下面哪个指针表达式可以用来引用数组元素a[i][j][k][l]
正确答案: B
(((a+i)+j)+k)+l)
((((a+i)+j)+k)+l)
(((a+i)+j)+k+l)
((a+i)+j+k+l)
a:整个四维数组的地址
*(a+i) = a[i]
*(a+i)+j = a[i] +j
*((a+i)+j) = a[i][j]
*(*((a+i)+j)+k = a[i][j]+k
*(*( *((a+i)+j)+k ) = a[i][j][k]
*(*( *((a+i)+j)+k )+l = a[i][j][k]+l
*(*( *( *((a+i)+j)+k )+l ) = a[i][j][k][l]
以下程序的输出结果是()。
void main()
{
printf("s1=│%15s│s2=│%-5s│","chinabeijing","chi");
}
正确答案: D
s1=│chinabeijing□□□│s2=│chi│
s1=│chinabeijing□□□│s2=│chi□□│
s1=│□□□chinabeijing│s2=│□□chi│
s1=│□□□chinabeijing│s2=│chi□□│
%15s表示输出占15个空格的位置,并且右对齐,左边多余的位置补空格,因
为“chinabeijing”包含12个字符,所以输出时,左边要补上3个空格,%-5s表示输出占5
个空格的位置,并且左对齐,右边多余的位置补空格,因为”chi”包含3个字符,所以输出
时,右边要补上2个空格。
下面的程序的输出是什么?
#include
int main(void)
{
int n;
char y[10] = "ntse";
char *x = y;
n = strlen(x);
*x = x[n];
x++;
printf("x=%s\n",x);
printf("y=%s\n",y);
return 0;
}
正确答案: B
x=atse,y=
x=tse,y=
x=atse,y=e
x=tse,y=e
8.
已有定义int x;float y;且执行scanf(“%3d%f”,&x,&y);语句时,假设输入数据为
12345□678↙,则x、y的值分别为()。
正确答案: D
12345 678.000000
123 678.000000
123 45.678000
123 45.000000
因为%3d,所以输入中的前3位数123将赋给x,输入中后面的45将赋给y,
因为45后键入了空格使得后面的输入无效,又因y是浮点数,所以y的值应为45.000000。
故正确答案是D。
设完全无向图中有n个顶点,则该完全无向图中有多少条边
正确答案: A
n(n-1)/2
n(n-1)
n(n+1)/2
(n-1)/2
无向图 n(n-1)/2 条
有向图 n(n-1) 条
以下哪个排序的平均速度最快?
正确答案: B
希尔
快速
冒泡
插入
在各种排序方法中,快速排序法和堆排序法的平均速度是最快的,因为它们的时间复杂度都是O (nlog2n),其他的排序算法的时间复杂度大都是O(n2@)。
以下关于抽象类的说法正确的有
正确答案: A B C
抽象类只能用作其他类的基类
不能使用抽象类定义对象
抽象类不能用作参数类型、函数返回类型或显式转换的类型
抽象类不能有构造函数和析构函数
抽象类有一下几个特点:
(1)抽象类只能用作其他类的基类,不能建立抽象类对象。
(2)抽象类不能用作参数类型、函数返回类型或显式转换的类型。
(3)可以定义指向抽象类的指针和引用,此指针可以指向它的派生类,进而实现多态性。
一个抽象类注意一下几点:
1.抽象类只能作为其他类的基类,他不能直接被实例化,而且对抽象类不能使用new操作符。
抽象类如果含有变量或值,则他们一定是null类型,要么包含了对非抽象类的实例的引用。
2.抽象类允许包含抽象成员,但这不是必须的(可以允许一个抽象类中没有没有任何抽象成员);
抽象类中可以有非抽象方法.
3.抽象类不能同时又是final的,如果试图将一个final类作为其他类的基类,
Java将特别提示“the class can either abstract or final ,not both".
理所当然,final类不能同时事抽象类。因为抽象类总希望被继承。
4.如果一个非抽象类从抽象类中派生,则其必须通过覆盖来实现所有的继承而来的抽象成员。
5.抽象类可以被抽象类所继承,结果依然是抽象类 。
6.抽象类允许被声明。
下面说法错误的是()
正确答案: A B
在组合时,为了保证成员对象被正确清除,在组合类的析构函数中需要显式调用其成员对象的析构函数
在类的继承层次中,可以自动进行向上和向下类型转换.而且都是安全的
构造函数可以重载,析构函数不能重载
C++的派生类如果要覆盖一个继承到的成员函数,在基类中需要将该函数声明为virtual
A选项:在组合类的析构函数中并不需要显式调用其成员对象的析构函数,因为当执行组合类的析构函数时,其数据成员也会被销毁,对于类成员对象来说,成员对象销毁时,程序会自动调用其析构函数;不过对于组合类中new的指向类成员的指针,组合类需要自己去delete该指针;
B选项:显然是错的,在类继承层次中,基类在上,派生类在下,所以可以自动进行向上类型转换,即可以使基类指针和引用指向派生类对象,而不可以使派生类指针和引用指向基类对象;
C选项:对的,构造函数可以根据参数的不同实现函数重载,而因为析构函数没有参数,对于一个类来说也是唯一的,所以是不能重载的;
D选项:即派生类想要重写继承来的成员函数,需要用到virtual函数,来实现动态多态。
在下⾯面关于并发性的叙述众正确的是:
正确答案: C
并发性是指若干事件在同一时刻发生
并发性是指若干事件在不同时刻发生
并发性是指若干事件在同一时间间隔发生
并发性是指若干事件在不同时间间隔发生
并行性和并发性是既相似又有区别的两个概念。并行性是指两个或多个事件在同一时刻发生。而并发性是指两个或多个事件在同一时间间隔发生。在多道程序环境下,并发性是指在一段时间内宏观上有多个程序在同时运行,但在单处理机系统中,每一时刻却仅能有一道程序执行,故微观上这些程序只能是分时地交替执行。
采用简单选择排序,比较次数与移动次数分别为()
正确答案: C
O(n),O(logn)
O(logn),O(nn)
O(nn),O(n)
O(nlogn),O(n)
对n个记录进行简单选择牌组,所需进行的比较次数为
移动记录的次数,最小值为0,最大值为3(n-1),
所以简单选择排序的最好和平均时间复杂度为O(n*n)
判断下列说法是否正确:在用堆排序算法排序时,如果要进行增序排序,则需要建立“大顶堆”。( )
正确答案: A
正确
错误
堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆。
将无序序列构建成一个堆,根据升序需求选择大顶堆;
将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;
重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素
反复执行调整+交换步骤,直到整个序列有序。
类成员函数的重载、覆盖和隐藏区别描述正确的有?
正确答案: C D
覆盖是指在同一个类中名字相同,参数不同
重载是指派生类函数覆盖基类函数,函数相同,参数相同,基类函数必须有virtual关键字
派生类函数与基类函数相同,但是参数不同,会"隐藏"父类函数
函数名字相同,参数相同,基类无virtual关键字的派生类的函数会"隐藏"父类函数
a.成员函数被重载的特征:
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
b.覆盖是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual 关键字。
c.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)
下列排序算法中,()在某趟排序结束后不一定能选出一个元素放到其最终位置上。
正确答案: C
选择排序
冒泡排序
希尔排序
堆排序
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。
所以每一趟选择的元素都会放在他的最终位置
冒泡排序, 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。
走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
比如按照升序排序则每一趟会将前面未排序部分的最大的往后交换到已排序的最前面,为其最终位置
堆排序如果要求升序则建立大根堆,降序则建立小根堆,堆顶元素为最大或者最小的元素
将这个元素与最后一个位置的元素交换,再将剩余元素还原成大小跟堆
每一趟都会选出一个未排序中的最大或者最小放大他的最终位置
希尔排序由于是按照增量排序,步长不同可能元素不一定到他最终位置
若执行fopen函数时发生错误,则函数的返回值是()。
正确答案: B
地址值
0
1
EOF
执行fopen函数时,如果文件打开成功,则返回该文件结构体的指针,如果打开失败(例如,读打开时文件不存在,写打开时文件不能创建),则返回NULL(即0)。
对长度为n的线性表作快速排序,在最坏情况下,比较次数为
正确答案: D
n
n-1
n(n-1)
n(n-1)/2
快速排序 、冒泡排序 、直接插入排序 、堆排序,除了堆排序算法的比较次数是O(nlog2n),其他的都是n(n-1)/2
如下哪一段代码不能给地址0xaae0275c赋值为1?()
正确答案: B
volatile int *p=(int *)0xaae0275c;*p=1
(volatile int *)0xaae0275c[0]=1
volatile int *p=(int *)0xaae0275c;p[0]=1
*(volatile int *)0xaae0275c=1
主要考察赋值到指定的内存地址
选项A,C, 通过一个指针向其指向的内存地址写入数据。
选项D,这行代码其实和上面的两行代码没有本质的区别。先将地址0xaae0275c强制转换,告诉编译器这个地址上将存储一个int类型的数据;然后通过钥匙“*”向这块内存写入一个数据。
选项B,将一个右值赋给一个左值,显然行不通。类似指针,int *p; p=1不合理
另外这里涉及到volatile关键字,顺便介绍一下 :
(1)用来同步,因为同一个东西可能在不同的存储介质中有多个副本,有些情况下会使得这些副本中的值不同,这是不允许的,所以干脆用volatile,让它只 有一个,没有其他的副本,这样就不会发生不同步的问题。
(2)防止编译器优化去掉某些语句,像我在arm中见到个寄存器非常奇怪,当中断来的时候,相对应的位置1,而清0又不能向这位写0,向这位写1才是1才 是清中断(清0),
// 假设0x560012300 为寄存器地址
#define INTPAND *(volatile unsigned int *)0x560012300
INTPAND = INTPAND; // 清中断
像编译器如果看到有INTPAND = INTPAND;这种看似无用的操作,如果没有volatile说明,编译器就很有可能会去掉INTPAND = INTPAND;实际上有用的东 西,却被编译器当没用的东西优化掉了。
(3)当地址是io端口的时候,读写这个地址是不能对它进行缓存的,这是相对于某些嵌入式中有***才有这个。比如写这个io端口的时候,如果没有这个 volatile,很可能由于编译器的优化,会先把值先写到一个缓冲区,到一定时候 再写到io端口,这样就不能使数据及时的写到io端口,有了volatile说明以后, 就不会再经过***,write buffer这种,而是直接写到io端口,从而避免了读写 io端口的延时。
个数约为 50k 的数列需要从小到大排序, 数列特征是基本逆序 (多数数字从大到小,个别乱序) ,以下哪种排序算法在事先不了解数列特征的情况下性能大概率最优(不考虑空间限制)___.
正确答案: E
冒泡排序
改进冒泡排序
选择排序
快速排序
堆排序
插入排序
个数约为50K,基本可以秒杀一般的`冒泡`,`改进冒泡`,`选择`,`插入`等基本的排序。加上数列的特征是基本逆序,而快速排序的worst case就是基本逆序或者基本有序的情况。综上所述,堆排序应该是大概率最优的
有关希尔排序算法叙述正确的是( )
正确答案: A B
最后一次的步长增量一定为1
分割后子序列内部的排序算法是直接插入排序
分割后子序列内部的排序算法是直接选择排序
希尔排序是稳定排序算法
Shell排序的执行时间依赖于增量序列。
好的增量序列的共同特征:
① 最后一个增量必须为1;
② 应该尽量避免序列中的值(尤其是相邻的值)互为倍数的情况。
2.Shell排序的时间性能优于直接插入排序
希尔排序的时间性能优于直接插入排序的原因:
①当文件初态基本有序时直接插入排序所需的比较和移动次数均较少。
②当n值较小时,n和的差别也较小,即直接插入排序的最好时间复杂度和最坏时间复杂度差别不大。
③在希尔排序开始时增量较大,分组较多,每组的记录数目少,故各组内直接插入较快
后来增量di逐渐缩小,分组数逐渐减少,而各组的记录数目逐渐增多,但由于已经按di-1作为距离排过序
使文件较接近于有序状态,所以新的一趟排序过程也较快。
因此,希尔排序在效率上较直接插入排序有较大的改进。
假设你只有100MB的内存,需要对1GB的数据进行排序,最合适的算法是?
正确答案: A
归并排序
快速排序
希尔排序
计数排序
总数据量大于内存存储范围,数据无法一次装入内存进行排序,后三种排序都需要内存中有完整的数据才能实现。 可以用归并排序不断交换外部数据与内部数据的方式实现
若有说明语句,int a,b;,用户的输入为111222333,结果a的值为111,b的值为
333,那么以下输入正确的语句是()。
正确答案: B
scanf(“%*3d%3c%3d”,&a,&b);
scanf(“%3d%*3c%3d",&a,&b);
scanf(“%3d%3d%*3d",&a,&b);
scanf(“%3d%*2d%3d",&a,&b);
当格式控制字符串中含有抑制符’*’时,表示本输入项对应的数据读入后,不赋给相应的变量(该变量由下一个格式指示符输入)。所以A的结果是a的值不确定(因为%3c与a的类型不匹配),b的值为333;C的结果将使a的值为111,b的值为222;D的结果将使a的值为111,b的值为233;B的结果将使a的值为111,b的值为333,中间输入的222不赋给任何变量(%*3c的作用);所以正确答案是B。
数组Q[n]用来表示一个循环队列,f为当前队列头元素的前一位置,r为队尾元素的位置,假定队列中元素的个数小于n,计算队列中元素的公式为()。
正确答案: D
r-f
(n+f-r)% n
n+r-f
(n+r-f)% n
26.
对包含n个元素的散列表进行检索,平均检索长度()
正确答案: D
为O(log2n)
为O(n)
为O(nlog2n)
不直接依赖于n
散列表(Hash table,也叫哈希表),是根据关键码值而直接进行访问的数据结构。
也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。
这个映射函数叫做散列函数,存放记录的数组叫做散列表。
查找过程中,关键码的比较次数,取决于产生冲突的多少,产生的冲突少,查找效率就高
产生的冲突多,查找效率就低。
因此,影响产生冲突多少的因素,也就是影响查找效率的因素。影响产生冲突多少有以下三个因素:
散列函数是否均匀;
处理冲突的方法;
散列表的装填因子(即填入表中的元素个数 / 散列表的长度)。由于表长是定值,装填因子与"填入表中的元素个数"成正比,所以,装填因子越大,填入表中的元素较多,产生冲突的可能性就越大;装填因子越小,填入表中的元素较少,产生冲突的可能性就越小。
希尔排序法属于哪一种类型的排序法
正确答案: A
插入类排序法
交换类排序法
选择类排序法
建堆排序法
希尔排序法(缩小增量法) 属于插入类排序
是将整个无序列分割成若干小的子序列分别进行 插入排序 的方法
下列容器中,哪些容器按 key 查找的复杂度为 O(log(n)) ()
正确答案: B C
std::unordered_set
std::multimap
std::map
std::deque
STL库中,map和multimap底层都是红黑树实现的,两者的不同在于multimap允许重复的可以,而map中不行。
红黑树的查找复杂度为O(log(n))
unodered_map/_set底层是哈希表实现的,查找复杂度为O(1)
若一个广义表的表头为空表,则此广义表亦为空表()
正确答案: B
对
错
广义表的表头为空,并不代表该广义表为空表。
例如:
广义表()和(())不同。前者是长度为0的空表,对其不能做求表头和表尾的运算;
而后者是长度为l的非空表(只不过该表中惟一的一个元素是空表),对其可进行分解
得到的表头和表尾均是空表()
线性表的顺序存储结构是一种() 的存储结构,线性表的链式存储结构是一种顺序存取 的存储结构。
正确答案: A
随机存取
顺序存取
索引存取
散列存取
顺序存储结构中,数据元素存放在一组地址连续的存储单元中,每个数据元素地址可通过公式LOC(ai)=LOC(a1)+(i-1)L计算得到,从而实现了随机存取。对于链式存储结构,要对某结点进行存取,都得从链的头指针指向的结点开始,这是一种顺序存取的存储结构。
不进行初始化即可自动获得初值0的变量包括()。
正确答案: D
任何用static修饰的变量
.任何在函数外定义的变量
局部变量和用static修饰的全局变量
全局变量和用static修饰的局部变量
全局(静态)存储区:存放全局变量和静态变量,包括DATA段和BSS段。
初始化的全局变量和静态变量存放在DATA段
未初始化的全局变量和未初始化的静态变量存放在BSS段。
在程序执行之前,BSS段会自动清零,所以,未初始化的全局变量与静态变量在程序执行之前已经成0了。
设散列表中有 m 个存储单元,散列函数 H(key)= key % p ,则 p 最好选择( )。
正确答案: B
小于等于m的最大奇数
小于等于m的最大素数
小于等于m的最大偶数
小于等于m的最大合数
【1】 奇数、偶数、合数都可能分解成两个数相乘的形式(除了1x本身);而素数只能分解成1x本身。
【2】 若key是随机分布的,则不管p取小于等于m的最大奇数、素数、偶数还是合数,H(key)将较均匀的映射到0~m-1的存储单元;
若key的分布具有某种规律,若m取小于等于m的最大素数,依然能较好的映射。
【3】 严蔚敏《数据结构》:一般情况下,可以选p为质数或不包含小于20的质因数的合数。
瀑布模型的存在问题是( )
正确答案: B
用户容易参与开发
缺乏灵活性
用户与开发者易沟通
适用可变需求
瀑布模型的优缺点
1、瀑布模型有以下优点:
1)为项目提供了按阶段划分的检查点。
2)当前一阶段完成后,您只需要去关注后续阶段。
3)可在迭代模型中应用瀑布模型。
迭代模型中应用瀑布模型
增量迭代应用于瀑布模型。迭代1解决最大的问题。每次迭代产生一个可运行的版本,同时增加更多的功能。每次迭代必须经过质量和集成测试。
2、瀑布模型有以下缺点:
1)在项目各个阶段之间极少有反馈。
2)只有在项目生命周期的后期才能看到结果。
3)通过过多的强制完成日期和里程碑来跟踪各个项目阶段。
若用数组S[0…n]作为两个栈S1和S2的存储结构,对任何一个栈只有当S全满时才不能做入栈操作。为这两个栈分配空间的最佳方案是
正确答案: A
S1的栈底位置为0,S2的栈底位置为n
S1的栈底位置为0,S2的栈底位置为n/2
S1的栈底位置为1,S2的栈底位置为n/2
两个栈的栈底一个在数组第一个元素,朝着数组正方向增长
另一个在数组最后一个元素,朝着数组索引减小的方向增长。
当两个栈的栈顶相等是,表明数组满了,不能继续入栈
循环队列SQ的存储空间是数组d[m],队头、队尾指针分别是front和rear,则执行出队后其头指针front值是()
正确答案: D
front=front+1
front=(front+1)%(m-1)
front=(front-1)%m
front=(front+1)%m
循环队列
进队:队尾指针(rear+1)%m
出队:对头指针(front+1)%m
m为数组容量
题目来源于王道论坛
在内部排序过程中,对尚未确定最终位置的所有元素进行一遍处理称为一趟排序。下列排序方法中,每一趟排序结束都至少能够确定一个元素最终位置的方法是()。
Ⅰ.简单选择排序 Ⅱ.希尔排序 Ⅲ.快速排序
Ⅳ.堆排序 Ⅴ.二路归并排序
正确答案: A
仅Ⅰ、Ⅲ、Ⅳ
仅Ⅰ、Ⅲ、Ⅴ
仅Ⅱ、Ⅲ、Ⅳ
仅Ⅲ、Ⅳ、Ⅴ
对于Ⅰ,简单选择排序每次选择未排序列中的最小元素放入其最终位置。对于Ⅱ,希尔排序每次是对划分的子表进行排序,得到局部有序的结果,所以不能保证每一趟排序结束都能确定一个元素的最终位置。对于Ⅲ,快速排序每一趟排序结束后都将枢轴元素放到最终位置。对于Ⅳ,堆排序属于选择排序,每次都将大根堆的根结点与表尾结点交换,确定其最终位置。对于Ⅴ,二路归并排序每趟对子表进行两两归并从而得到若干个局部有序的结果,但无法确定最终位置。
下面有关函数模板和类模板的说法正确的有?
正确答案: A B
函数模板的实例化是由编译程序在处理函数调用时自动完成的
类模板的实例化必须由程序员在程序中显式地指定
函数模板针对仅参数类型不同的函数
类模板针对仅数据成员和成员函数类型不同的类
C:函数模版还可以将 函数返回值类型 作为模版参数。
D:类模板还可以针对 继承的基类类型 作为模板参数。
下面描述中,正确的是
正确答案: B D
虚函数是没有实现的函数
纯虚函数的实现是在派生类中
抽象类是没有纯虚函数的类
抽象类指针可以指向不同的派生类
用关键字virtual修饰的成员函数叫做虚函数,虚函数是为了实现多态而存在的,必须有函数体
纯虚函数的声明,是在虚函数声明的结尾加=0,没有函数体。在派生类中没有重新定义虚函数之前是不能调用的
如果一个类中至少含有一个纯虚函数,此时称之为抽象类。所以抽象类一定有纯虚函数
基类类型的指针可以指向任何基类对象或派生类对象
以下不能在list中添加新元素的方法是()
正确答案: B
append()
add()
extend()
insert
1. 列表可包含任何数据类型的元素,单个列表中的元素无须全为同一类型。
2. append() 方法向列表的尾部添加一个新的元素。只接受一个参数。
3. extend()方法只接受一个列表作为参数,并将该参数的每个元素都添加到原有的列表中。
4. insert() 将一个元素插入到列表中,但其参数有两个(如insert(1,”g”)),第一个参数是索引点,即插入的位置,第二个参数是插入的元素。
折半查找与二元查找树的时间性能在最坏的情况下是相同的()
正确答案: B
对
错
折半查找的查找长度至多为㏒2 n +1,二元查找树最坏时需查找n次(数列有序,树只有左孩子或只有右孩子,退化为线性表)
下面哪些是使用分治法的特征( )
正确答案: A B D
该问题可以分解为若干个规模较小的相同问题
子问题的解可以合并为该问题的解
子问题必须是一样的
子问题之间不包含公共的子问题
理解为"分而治之"这一成语的意思来做
AB肯定对的
如果子问题都是一样的话都可以统一解决了还分什么问题,C错
D,这小块问题是这个,那一小块问题是那个,如果含公共项的话都可以统一了,就和C的说法差不多了
float 类型(即 IEEE754 单精度浮点数格式)能表示的最大整数是( )。
正确答案: D
2126-2103
2127-2104
2127-2103
2128-2104
链接:
我这里说说IEEE754的一些特殊情况,就单精度而言。
32位, 1位符号位+8位指数位+23位小数位
当指数位全部为0,并且小数位全部为0的时候,表示0;通过符号位可以得知是+0,还是-0;
当指数位全部为1,并且小数位全部为0的时候,表示无穷大,计算机里面一般标记为inf;
通过符号位可以得知是inf,还是-inf;
当指数位全部为1,并且小数位不全为0的时候,表示这并不是一个有效数,一般即为NaN。
至于本题中的最大数,它的编码形式是这样的 0 11111110 11111111111111111111111
多态类中的虚函数表建立在()
正确答案: A
编译阶段
运行阶段
构造函数被调用时进行初始化的
类声明时
是在编译时创建的的虚函数表,编译器对每个包含虚函数的类创建一个虚函数表(vtable),在vtable中
放置这个类的虚函数地址。编译器另外还为每个特定类的对象提供了一个虚表指针(即vptr)
这个指针指向了对象所属类的虚表。
在程序运行时,根据对象的类型去初始化vptr,从而让vptr正确的指向所属类的虚表,从而在调用虚函数时,就能够找到正确的函数
下面的说法那个正确
#define NUMA 10000000
#define NUMB 1000
int a[NUMA], b[NUMB];
void pa()
{
int i, j;
for(i = 0; i < NUMB; ++i)
for(j = 0; j < NUMA; ++j)
++a[j];
}
void pb()
{
int i, j;
for(i = 0; i < NUMA; ++i)
for(j = 0; j < NUMB; ++j)
++b[j];
}
正确答案: C
pa 和 pb 运行的一样快
pa 比 pb 快
pb 比 pa 快
无法判断
小循环放外面,大循环放里面是没错的。 但是这道题目是例外,相当于一个大数组赋值少数次和小数组赋值多次!这样肯定小数组的比较快。如果把题目中的++a[],和++b[]换成一个同一个数,那么结果刚好相反。亲测,是这样!
使用fseek函数可以实现的操作是( )
正确答案: A
改变文件指针的当前位置
文件的顺序读写
文件的随机读写
以上都不对
int fseek( FILE *stream, long offset, int origin );
第一个参数stream为文件指针;
第二个参数offset为偏移量,整数表示正向偏移,负数表示负向偏移;
第三个参数origin设定从文件的哪里开始偏移,可能取值为:
SEEK_CUR当前位置、 SEEK_END文件结尾 或 SEEK_SET文件开头
双循环链表中,任意一结点的后继指针均指向其逻辑后继。
正确答案: B
T
F
尾节点的后继指向头结点,而头结点不是尾节点的逻辑后继
一个稀疏矩阵Amn 采用三元组形式表示,若把三元组中有关行下标与列下标的值互换,并把m和n的值互换,则就完成了Amn 的转置运算()
正确答案: B
对
错
三元组转置: (1)将数组的行列值相互交换 (2)将每个三元组的i和j相互交换 (3)重排三元组的之间的次序便可实现矩阵的转置
下面哪个Set类是排序的?
正确答案: B
LinkedHashSet
TreeSet
HashSet
AbstractSet
LinkedHashSet
继承于HashSet、又基于 LinkedHashMap 来实现
TreeSet
使用二叉树的原理对新 add()的对象按照指定的顺序排序(升序、降序),每增加一个对象都会进行排序,将对象插入的二叉树指定的位置。
HashSet
存储元素的顺序并不是按照存入时的顺序(和 List 显然不同) 而是按照哈希值来存的所以取数据也是按照哈希值取得
具有 n 个结点的二叉排序树有多种,其中树高最小的二叉排序树是最佳的,这样的说法正确吗?
正确答案: A
正确
不正确
二叉排序树的主要用途是链式存储结构的二分查找,查找的最坏次数是树的高度
因此高度最小的二叉排序树是最佳的。
假定CSomething是一个类,执行下面这些语句之后,内存里创建了____个CSomething对象。
CSomething a();
CSomething b(2);
CSomething c[3];
CSomething &ra = b;
CSomething d=b;
CSomething *pA = c;
CSomething *p = new CSomething(4);
正确答案: E
10
9
8
7
6
5
CSomething a();
// 没有创建对象,这里不是使用默认构造函数,而是定义了一个函数,在C++ Primer393页中有说明。
CSomething b(2);//使用一个参数的构造函数,创建了一个对象。
CSomething c[3];//使用无参构造函数,创建了3个对象。
CSomething &ra=b;//ra引用b,没有创建新对象。
CSomething d=b;//使用拷贝构造函数,创建了一个新的对象d。
CSomething *pA = c;//创建指针,指向对象c,没有构造新对象。
CSomething *p = new CSomething(4);//新建一个对象。
关于 Array 数组对象的说法不正确的是()
正确答案: B
push()向数组的末尾添加一个或更多元素,并返回新的长度
pop()删除并返回数组的第一个元素
unshift()向数组的开头添加一个或更多元素,并返回新的长度
join()把数组的所有元素放入一个字符串
push方法是向数组末尾添加一个或者多个元素,并返回新的长度
二、pop方法删除数组的最后一个元素,把数组的长度减1,并且返回它被删除元素的值
如果数组变为空,则该方法不改变数组,返回undefine值
三、unshift()方法是向数组的开头添加一个或多个元素,并且返回新的长度
四、shift()方法和unshift()方法恰恰相反。该方法用于把数组的第一个元素从其中删除,并返回被删除的值。如果数组是空的,shift()方法将不进行任何操作,返回undefined的值。
五,join()方法用于把数组中的所有元素放入一个字符串。元素是通过指定的分隔符进行分隔的。
在一颗度为4的树T中,若有20个度为4的结点,10个度为3的结点,1个度为2的结点,10个度为1的结点,则树T的叶结点个数是_______。
正确答案: B
41
82
113
122
任何一棵树中,结点个数比分支个数多一
分支个数等于20*4+10*3+1*2+10*1=122
所以这棵树一共有123个结点
度不为零的结点数目为20+10+1+10=41
所以叶子结点也就是度为零的结点个数为123-41=82
带权的连通无向图的最小(代价)生成树(支撑树)是唯一的。( )
正确答案: B
正确
错误
最小生成树在一些情况下可能会有多个。
例如,当图的每一条边的权值都相同时,该图的所有生成树都是最小生成树。
最短加权路径是一样的,但是最小生成树可能不一样
设一棵m叉树中度数为0的结点数为N0 ,度数为1的结点数为Nl ,……,度数为m的结点数为Nm,则N0=()。
正确答案: B
Nl+N2+……+Nm
l+N2+2N3+3N4+……+(m-1)Nm
N2+2N3+3N4+……+(m-1)Nm
2Nl+3N2+……+(m+1)Nm
m叉树总的指针数为N1 + 2N2 + ...+mNm
总的节点数为N 0 +N1 + N2 + ...+Nm ,需要的指针数为N 0 +N1 + N2 + ...+Nm -1
以上两式相等得出N 0 =1+ N2 + 2N3...+(m-1)Nm
下述说法中______是正确的。
正确答案: B
EPROM是可改写的,因而也是随机存储器的一种
EPROM是可改写的,但它不能用作为随机存储器用
EPROM只能改写一次,故不能作为随机存储器用
EPROM是可改写的,但它能用作为随机存储器用
EPROM是可擦除可编程的只读存储器.可以反复改写,但每次改写之前都需要擦除干净后,再在特殊环境下进行改写,而随机存储器要求可以随时读写,而且速度要求很快,所以不能当做随机存储器用,选B
在一台主流配置的PC机上,调用f(35)所需的时间大概是_______。
int f(int x) {
int s=0;
while(x-- >0) s+=f(x);
return max(s,1);
}
正确答案: C
几毫秒
几秒
几分钟
几小时
答案:c
O(f(n)) = O(f(n - 1)) + O(f(n - 2)) + ... + O(f(0))
= 2O(f(n - 2)) + 2(O(f(n - 3)) + ... + 2O(f(0))
= 235O(f(0))
现在的计算机大致每秒运算一亿次。
所以大约花去235/100000000m大致为344秒也就是几分钟。
动态RAM的特点是( )
正确答案: C
工作中需要动态地改变存储单元内容
工作中需要动态地改变访存地址
每隔一定时间需要刷新
每次读出后需要刷新
静态RAM(SRAM)速度非常快,只要电源存在内容就不会自动消失。其基本存储电路为6个MOS管组成1位,因此集成度相对较低,功耗也较大。一般高速缓冲存储器用它组成。
动态RAM(DRAM)的内容在10-3或l0-6秒之后自动消失,因此必须周期性的在内容消失之前进行刷新。由于它的基本存储电路由一个晶体管及一个电容组成,因此它的集成度高,成本较低,另外耗电也少,但它需要一个额外的刷新电路。DRAM运行速度较慢,SRAM比DRAM要快2~5倍,一般,PC机的标准存储器都采用DRAM组成。
关于双链表的搜索给定元素操作的说法正确的是?
正确答案: B
从两个方向搜索双链表,比从一个方向搜索双链表的速度慢
从两个方向搜索双链表,比从一个方向搜索双链表的方差要小
从两个方向搜索双链表,比从一个方向搜索双链表速度要快
以上说法都不正确
如果链表数据是无序的,则单向搜索与双向搜索平均速度相同
如果链表是有序的,而要搜索的数据距离最小值(最大值)较近,这种情况下双向搜索平均速度更快。
因此双向搜索更稳定,方差更小
方差没说是速度还是步长的 无序有序也不说 。方差主要用来判断数据波动是否大的。越小越平均,分布越均匀,和标准差差不多
某二叉树共有12个结点,其中叶子结点只有1个。则该二叉树的深度为(根结点在第1层)
正确答案: D
3
6
8
12
【解析】二叉树中,度为0的结点数等于度为2的结点数加1,即n2 = n0 -1,叶子结点即度为0,n0 = 1,则n2 = 0,总结点数为 12 = n0 + n1 + n2 = 1+ n1 +0,则度为1的结点数n1 = 11,故深度为12
如果不是往一侧走的话,至少会有两个叶子结点,所以只能是往一侧延伸的(即每个节点只有一个子节点,最下面一个节点为唯一的叶子结点),那么多少个节点就会多少层
若外部存储上有3110400个记录,做6路平衡归并排序,计算机内存工作区能容纳400个记录,则排序好所有记录,需要作几趟归并排序( )
正确答案: C
6
3
5
4
次数最少 每次让计算机内存填满400
3110400个记录要填 3110400/400 = 7776次
n路归并m 次 的次数为 n^m
6^m = 7776
m=5
如果在一个排序算法的执行过程中,没有一对元素被比较过两次或以上,则称该排序算法为节俭排序算法,以下算法中是节俭排序算法的有________。
正确答案: A D
插入排序
选择排序
堆排序
归并排序
解析。A。插入排序的思想是对第i+1位置上的数,将其插入前i个有序数组中。
插入以后形成新的有序数组,根据排序数组不会在比较的原则,该元素不可能再次比较了。
B。选择排序的思想是对当前第i个位置上的数,那么在后续数组中,选最小的与i对换。
说明肯定比较过第二小和第三的数。那么在i+1位置上,上次第二小和第三小的数还需要比较一次选出最小的与i+1交换。那么至少比较了两次。
C。堆排序。堆排序分两步。初始建堆和堆重建。当最大元素与最末尾元素交换后。
面临堆重建的问题。那么堆顶元素下层过程中,必然与第二小的元素比较一次。
再一次堆重建,假设第二小元素被替换的时候,他们会在比较一次。
D。归并排序思路是对两个已经排好序的数组,同时向后移动。
那么每个元素只会与其他数组中的元素比较一次。然后合并在一起。根据同组元素不会比较的原则的,以后两个元素不可能在比较到。
将有关二叉树的概念推广到三叉树,则一棵有244个结点的完全三叉树的高度为()
正确答案: C
4
5
6
7
Log3(244)向下取整+1
两分法插入排序所需比较次数与待排序记录的初始排列状态相关()
正确答案: B
对
错
不管你初始数据的状态是什么,插入过程中它前面一部分一定是刚刚已经全局排好序的,而比较过程正是在前面这排好序的部分中进行。也就是说,不管你初始数据是已经有序、基本有序、无序,比较操作都是只在前面已经排好序部分中进行
一个文件名字为rr.Z,可以用来解压缩的命令是?
正确答案: D
tar
gzip
compress
uncompress
tar是操作.tar的命令
gzip是压缩.gz压缩包的命令
compress:压缩.Z文件
uncompress:解压缩.Z文件
对n个数字进行排序,期中两两不同的数字的个数为k,n远远大于k,而n的取值区间长度超过了内存的大小,时间复杂度最小可以是?
正确答案: C
O(nlogk)
O(nk)
O(n)
O(nlogn)
两两不同的数字的个数为k,因为不知道确定的数字范围,桶排序不适合,又因为 n远远大于k, 本题使用hash表来统计,首先获得k个数及其每个数出现的次数,然后对k个数进行排序,排序的 复杂度可忽律不计,实际上就是遍历一遍n个数字,所以本位复杂度为O(n)。
先通过hash来获得这k个数,以及每个数对应的个数,然后对k个数进行排序。复杂度为O(N)
设int f(int);和int g(int);是函数f和g的原形,以下将f作为语句调用的是()
正确答案: B
g(f(3))
f(g(3))
g(f(3)+2)
p= f(g(3)+1)
调用即是函数名(参数);
AC形式一样,对g的调用,
d已经是另外一个函数p,也就是对p的调用
对 n 个记录的文件进行快速排序,所需要的辅助存储空间大致为
正确答案: C
O(1)
O(n)
O(1og2n)
O(n2)
辅助存储空间 = 时间复杂度
额外存储空间 = 空间复杂度
若采用双符号位补码运算,运算结果的符号为 10,则()
正确答案: A
产生了负溢出(下溢)
运算结果正确,为负数
产生了正溢出
运算结果正确
常用的溢出检测机制主要有进位判决法和双符号位判决法。
双符号位判决法采用两位表示符号,即00表示正号、11表示负号,则溢出时两个符号位就不一致了,从而可以判定发生了溢出。
假设X、Y分别两个加数符号位,Z为运算结果符号位。
当X=Y=00(两数同为正),而Z=01(结果为负)时,正溢出;
当X=Y=11(两数同为负),而Z=10(结果为正)时,负溢出.
表达式"X=A+B*(C-D)/E"的后缀表示形式可以是()
正确答案: C
XAB+CDE/-=
XA+BC-DE/=
XABCD-E/+=
XABCDE+/=
思路如下:
X=A+B*(C-D)/E
1)扫描X为数字,进行输出 X
2)扫描=为操作符,进栈,栈中元素为:=
3)扫描A为数字,进行输出A,输出的元素为X,A 栈中元素为:=
4)扫描+为操作符,由于+>=(栈顶)进栈,栈中元素为:+,=
5)扫描B为数字,进行输出B,输出的元素为X,A,B 栈中元素为:=
6) 扫描*为操作符,由于 *>+(栈顶) 进栈,栈中元素为:*,+,=
7)扫描(为操作符,进栈,栈中元素为:(, *,+,=
8)扫描C为数字,进行输出C,输出的元素为X,A,B,C 栈中元素为:(, *,+,=
9) 扫描-为操作符,进栈,栈中元素为:-,(, *,+,=
10)扫描D为数字,进行输出D,输出的元素为X,A,B,C,D 栈中元素为:-(, *,+,=
11)扫描)为操作符,进行弹出操作,直到遇见(为止,输出元素为:- ,总的 输出元素为X,A,B,C,D,- ,栈中元素为: *,+,=
12) 扫描/为操作符,此时栈顶元素为*,由于*,/优先级相同,依次弹出直到遇见比/优先级低的为止,然后/进栈 输出元素为:*, 总的输出为: 输出的元素为X,A,B,C,-,* 栈中元素为:/ ,+,=
13) 扫描E为数字,进行输出E,输出的元素E,总的输出元素为 X,A,B,C,D,-,*,E 栈中元素为: / ,+,=
14)到此扫描结束,依次弹出栈中剩余的元素,输出的的元素为 / ,+,=, 总的输出元素为 X,A,B,C,D,-,*,E, / ,+,=
所谓取广义表的表尾就是返回广义表中最后一个元素()
正确答案: B
对
错
广义表的表头是广义表的第一个元素,可以是一个特定的类型,也可以是一个广义表
广义表的表尾是广义表中将除了第一个元素之外的所有元素看做一个广义表
关于堆数据结构,下面描述中正确的有()
正确答案: A B C E
可以用堆实现优先队列
使用堆可以实现排序算法,复杂度为N * log N
从M个元素中查找最小的N个元素时,使用大顶堆的效率比使用小顶堆更高
在大顶堆中,第N层中的所有元素比第N+1层中的所有元素都要大
堆数据结构可以用数组方式存储,存储的是一棵完全二叉树
关于C选项:利用堆结构解决top K(这里是min K)问题有两种实现方式,以本题的min K为例:
小顶堆思路:构建一个容量为n的堆,建堆时间为n,此后每次都弹出堆顶元素(最小元素)再调整,一共弹 K 次,每次调整时间为log(n),所以时间复杂度是 n+K*log(n);
大顶堆思路:只维护一个容量为 K 的堆,所以建堆的复杂度为 K,此后遍历数组剩下的所有元素(n-K个),每个元素都要和堆顶的元素进行比较,如果比堆顶大,则忽略(说明该元素不是最小K个值,概率比较难算,这里简单当作(n-K)/n),复杂度是1,如果比堆顶小(概率简单视作K/n),则将堆顶替换为该元素并调整堆结构(称之为堆更新),每次更新(堆调整)的复杂度为 log(K),所以最坏时间代价为:K + (n-K) * log(K);
结合概率平均每个元素要比较的次数为:log(K)*K/n + 1*(n-K)/n,所以总时间复杂度是:K + (n-K) * [log(K)*K/n + 1*(n-K)/n];
下面我们来分析一下二者的代价,假设数据总量固定为10w,要求min K问题,将K作为变量,画出二者的函数图像(如下),可见,对于不同的 K 值,方法二(大顶堆)普遍比方法一好(但是一定要注意把概率考虑进去,否则得出的结果是大顶堆的最坏情况)。
int main(){fork()||fork();}共创建几个进程:_____
正确答案: C
1
2
3
4
5
6
fork()给子进程返回一个零值,而给父进程返回一个非零值;
在main这个主进程中,首先执行 fork() || fork(), 左边的fork()返回一个非零值,根据||的短路原则,前面的表达式为真时,后面的表达式不执行,故包含main的这个主进程创建了一个子进程,
由于子进程会复制父进程,而且子进程会根据其返回值继续执行,就是说,在子进程中, fork() ||fork()这条语句左边表达式的返回值是0, 所以||右边的表达式要执行,这时在子进程中又创建了一个进程,
即main进程->子进程->子进程,一共创建了3个进程。
以下算法中哪些算法的空间复杂度为O(1)( )
正确答案: A D
简单选择排序
快速排序
基数排序
堆排序
基数排序:k进制的话需要k个桶
快速排序:基于递归,考虑栈空间,空间复杂度从最坏O(N)到最好O(logN)
下列排序法中,每经过一次元素的交换会产生新的逆序的是( )
正确答案: A
快速排序
冒泡排序
简单插入排序
简单选择排序
产生新的逆序对,并不是说逆序对的数目发生改变。稳定的排序算法,每交换一次,逆序对的数目必然发生改变。
冒泡每交换一次,会减少一个逆序对,并不会产生新的逆序对。
简单插入排序,若插入到已排序序列的最后,则不会产生新的逆序对。
简单选择排序,每次将一个元素归位。无论由小到大归位,还是由大到小归位,都不会产生新的逆序对。
而快排,是跳跃式交换,必然会产生新的逆序对。
struct Date
{
char a;
int b;
int64_t c;
char d;
};
Date data[2][10];
在64位系统上,如果Data的地址是x,那么data[1][5].c的地址是()
正确答案: C
X+195
X+365
X+368
X+215
故此结构体总字节数为:24字节
data[1][5],意思是前面有15个元素。则第15个元素的起始地址为: 24 * 15 = 360, 即 X + 360
则data[1][5].c的地址为: 360 + 1 + 3 + 4 = 368,即 X + 368
下面关于 “EOF” 的叙述,正确的是()
正确答案: B
EOF的值等于0
EOF是在库函数文件中定义的符号常量
文本文件和二进制文件都可以用EOF作为文件结束标志
对于文本文件,fgetc函数读入最后一个字符时,返回值是EOF
C 标准函数库中表示文件结束符( end of file )。在 while 循环中以 EOF 作为文件结束标志,这种以 EOF 作为文件结束标志的文件,必须是文本文件。在文本文件中,数据都是以字符的 ASCII 代码值的形式存放。我们知道, ASCII 代码值的范围是 0~255 ,不可能出现 -1 ,因此可以用 EOF 作为文件结束标志。
在图采用邻接表存储时,求最小生成树的Prim算法的时间复杂度为()
正确答案: B
O(n)
O(n+e)
O(n2)
O(n3)
记住了 Prim算法的时间复杂度
邻接表存储时,是 O(n+e)
图的时候 是O(n^2)
计算斐波那契数列第n项的函数定义如下:
int fib(int n){
if(n==0)
return 1;
else if(n==1)
return 2;
else
return fib(n-1)+fib(n-2);
}
若执行函数调用表达式fib(10),函数fib被调用的次数是:
正确答案: D
117
137
157
177
若C(n) 表示计算次数,则
C(0) = 1;
C(1) = 1;
C(n) = C(n-1) + C(n-2) + 1; n>=2;
故:
C(0) = 1;
C(1) = 1;
C(2) = 1 + 1 + 1 = 3;
C(3) = 3 + 1 + 1 = 5;
C(4) = 5 + 3 + 1 = 9;
C(5) = 9 + 5 + 1 = 15;
……
若数据元素序列 11 , 12 , 13 , 7 , 8 , 9 , 23 , 4 , 5 是采用下列排序方法之一得到的第二趟排序后的结果,则该排序算法只能是() 。
正确答案: B
冒泡排序
插入排序
选择排序
二路归并排序
解答本题需要对各种排序算法的特点极为清楚。对于冒泡排序和选择排序,每一趟都能确定一个元素的最终位置,而题目中,前 2 个元素和后 2 个元素均不是最小或最大的 2 个元素并按序排列。选项 D 中的 2 路归并排序,第一趟排序结束都可以得到若干个有序子序列,而此时的序列中并没有两两元素有序排列。插入排序在每趟排序后能确定前面的若干元素是有序的,而此时第二趟排序后,序列的前三个元素是有序的,符合其特征。
下列哪些算法在排序过程中需要一个记录的辅助空间( )
正确答案: A B C
直接选择排序
直接插入排序
冒泡排序
归并排序
直接选择排序:前面逐渐有序,每次从后面的无序数列中找最大或最小继续添加到前面有序数列中,两两交换需要一个辅助空间
直接插入排序:类似打斗地主,每次抓一张牌,从后往前比较,把新抓的牌放到合适大小的位置,两两交换需要一个辅助空间
冒泡排序:每次把当前无序数列中最大或最小的数交换到此无序数量的最后,两两交换需要一个辅助空间
归并排序:分治法把当前待排数组分成多个子序列,先使每个子序列有序,再使子序列段间有序,需要 O(n) 的辅助空间
一个栈的入栈序列为1,2,3,…,n ,其出栈序列是 p 1 ,p 2 ,p 3 ,…p n 。若p 2 = 3,则 p 3 可能取值的个数是()
正确答案: C
n-3
n-2
n-1
无法确定
第二个出栈的是3,根据栈先进后出的规律,可知第一个可能是1也有可能是2。假设第一个出栈的是1,则留在栈里边的是2,等3出栈后2接着出栈。对于第一个出栈的是2情况也可以推出,3后面可能是1,其他的数字可以进栈接着出栈得到。因此,唯一能排除的数字就是3,其他数字都有可能!故为n-1
在下列排序算法中,哪一个算法的时间复杂度与初始序列无关( )
正确答案: D
直接插入排序
冒泡排序
快速排序
直接选择排序
1.直接插入排序
需要和前面都有序序列对比插入的位置,如果本身有序,则每次对比一个即可。
最坏情况,则需要一直对比到第一个元素
最好时间复杂度O(n),最坏时间复杂度O(n^2)
2.冒泡排序
假设递增冒泡,需要每次把无序部分最大的移动到无序部分的最右边,如果本身就是递增,则无序移动,遍历一遍就完成了。
最好时间复杂度为O(n),最坏时间复杂度为O(n^2);
3.快速排序
大家都知道,最差为O(n^2),平均为O(nlogn)
4.直接选择排序
每次需要遍历一遍选择无序部分最大的,无论是否有序,都要遍历才能找到,所以其时间复杂度与初始序列无关。
下列运算符重载函数中,属于友元函数的是( )
正确答案: B C D
Base operator+(Base);
Base operator–(Base);
Base operator&&(Base, Base);
Base operator++(Base,int);
A选项中,operator+有两个参数,重载函数中只声明了一个参数,属于类的成员函数
B选项中,operator--前置运算符没有参数,后置运算符参数应为int型,因此它重载的是前置--友元函数
C选项中,operator&&有两个参数,属于类的友元函数
D选项中,重载的是operator++后置运算符,两个参数,为友元函数
若调用fputc函数输出字符成功,则其返回值是()。
正确答案: D
EOF
1
0
输出的字符
fputc函数输出字符成功时,其返回值就是输出的字符。故选择答案是D.
在c语言程序中,当调用函数时,正确的是( )?
正确答案: C
全局变量开始占用存储单元
形参不需要分配存储单元
内部变量开始占用存储单元
外部变量开始占用存储单元
D项 extern是外部变量,这个变量在程序外部定义,在调用函数前后是始终存在的。
A项 全局变量在函数调用前后始终是占用内存的。
B项 形参本来是不占用存储单元的 但是 只有当函数调用时,发生实参向形参的数据传递时,系统才分配给形参存储单元,调用完之后就释放。
Linux文件权限一共10位长度,分成四段,第三段表示的内容是_() __ 。
正确答案: C
文件类型
文件所有者的权限
文件所有者所在组的权限
其他用户的权限
1,代表文件类型,一般有三类,- 代表普通的二进制文件,l 代表符号链接文件(软链接),d 代表目录文件
2-4,代表文件所有者的权限表示情况,分别对应 可读(r) 可写(w) 可执行(w),- 代表没有该项权限
5-7,代表文件所有这所属组的权限表示情况。分别对应 可读(r) 可写(w) 可执行(w),- 代表没有该项权限
8-10,代表除文件所有者和所属组的其他人所拥有的权限表示情况。分别对应 可读(r) 可写(w) 可执行(w),- 代表没有该项权限
如;umask 的值为022
创建一个文件的默认权限应该就是777-022=755
由于 执行权限(x) 比较危险,Linux默认不会赋予此权限,所以实际创建文件的默认权限是 755-111=644
如果此时创建的是一个软链接文件,则权限位为 lrx-r--r-;如果此时创建的是一个普通文件,则权限位为 -rx-r--r--;如果此时创建的是一个目录文件,则权限位为 drx-r--r--
下列哪些容器可以使用数组,但不能使用链表来实现?
正确答案: D
队列
栈
优先级队列
Map或者Dict
优先队列一般利用堆来实现,堆用数组来做的话,确实可以快很多,体现在用数组可以很快定位到父子节点,而链表的话,就没有那么方便了,但是这并不意味着链表不能做,可以,只是时间复杂度会比较高而已.
说一下字典吧,字典一般要求最好能在O(1)的时间就定位到要查询的值,如果采用链表的话,是不可能有这个好的时间复杂度的,字典一般用hash表来实现,在不碰撞的情况下,能够达到这么好的复杂度,用红黑树实现的map,查找的复杂度在log(N)左右. 用链表的话,硬要说的话,可以实现字典,但是效率不够,它在查找,插入等各种操作上都没有优势.
以下哪个方法是类A的合法继承方法:
class A
{
protected int method1(int a, int b)
{
return 0;
}
}
正确答案: A
public int method1(int a, int b) {return 0; }
private int method1(int a, int b) { return 0; }
public short method1(int a, int b) { return 0; }
static protected int method1(int a, int b) { return 0; }
B:重写时方法的访问权限只能相等或更大,而抛出的异常只能相等或更小;
C:方法重写时,返回值类型需要相同;
D:非static方法,重写时子类中也要是非static的。而static方法重写时,子类中也要是static的。
下面有关c++内存分配堆栈说法错误的是?
正确答案: D
对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制
对于栈来讲,生长方向是向下的,也就是向着内存地址减小的方向;对于堆来讲,它的生长方向是向上的,是向着内存地址增加的方向增长。
对于堆来讲,频繁的 new/delete 势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题
一般来讲在 32 位系统下,堆内存可以达到4G的空间,但是对于栈来讲,一般都是有一定的空间大小的。
一般0~3G是用户空间,3G~4G是内核空间, 所以堆内存不应该达到4G
对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;对于栈来讲,它的生长方向是向下的,是向着内存地址减小的方向增长。
有20个自然数1-20.每次取两个数字,取出不放回,其中一个数字是另一个数字2倍多。则最多取出来()个数字。
正确答案: A
18
16
14
12