一,冒泡排序的基本思路,时间复杂度是多少?
冒泡排序, 重复走访要排序的序列,依次比较两个元素,根据排序顺序,判断其顺序是否错误,错误则把他们交换。遍历整个序列,直到没有再需要交换的为止。
时间复杂度: 最好O(n),最坏O(n2)
算法稳定性: 稳定
二,什么是算法的复杂度?
时间复杂度 指执行算法所需要的计算工作量。
空间复杂度 指算法在计算执行时,所需要的空间度量。
三,C++和Java有什么区别?
1,Java中对内存的分配是动态的。采用面向对象机制,通过运算符new对每个对象分配内存。
2,Java不在所有类之外定义全局变量。而是通过公共静态变量完成此功能。
3,Java不使用Goto语句。
4,Java不支持头文件。在C.C++中都用头文件来定义类的原型,全局变量,库函数等。
5,Java 不支持宏定义,而是使用final来定义常量,而C++则用宏定义来定义常量。
6,Java 对每种数据类型在不同操作系统都分配固定长度。 如java int类型32位,而C、 C++对不同平台,数据类型长度不同。
7,类型转换不同。 C,C++可通过指针进行任意类型转换,常常带来不安全性,而java,运行时系统对对象的处理要经过相容性检测。
8,结构和联合的处理。在C,C++中,结构和联合体的所有成员均为公有,这带来了安全性问题。而在java中不包含结构和联合这两种结构,所以内容都封装在类内部。
9,Java不再使用指针。指针是C、C++中最灵活,也容易产生错误的数据类型。
四,对指针有什么优点体会。
提高程序编译效率和执行速度。
通过指针可使主函数和被调用函数之间的共享变量或数据结构吗,实现双向通信。
可以实现动态的存储分配。
便于标识各种数据结构,编写高质量的程序。
五,数组和链表的区别
数组是将元素在内存中顺序存放,每个元素占用的内存相同,可以通过下标迅速访问数组中的元素。数组必须事先确定长度,不能适量的数据动态增减。
链表在内存中是随机存储,其是通过元素中的指针联系到一起。链表动态的进行存储分配,可以适应数据动态的增减,且可以方便的插入,删除数据项。
六,数组,链表的优缺点。
数组优点:存储效率高,存取速度快,支持随机存取 缺点:灵活度不高,不能动态增减
链表有点: 自由度大,动态添加,删除元素方便 缺点:较比数组使用空间多
七,进程和线程的区别?
一个程序至少有一个进程,一个进程至少有一个线程。
进程在执行过程中有独立的存储单元,而多个线程共享内存,从而极大提高了程序的运行效率。
每个独立的线程有一个程序运行入口,顺序执行序列和程序的出口。 但是线程不能独立执行,必须依赖于进程中。
八,C++:memset ,memcpy 和strcpy 的根本区别?
答:
#include "memory.h"
#include "string.h"
memset用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为' '或'';例:char a[100];memset(a, '', sizeof(a)); memset( array, init_char , len);
memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度;例:char a[100],b[50]; memcpy(b, a, sizeof(b));注意如用sizeof(a),会造成b的内存地址溢出。把a拷贝向b。
strcpy就只能拷贝字符串了,它遇到'\0'(第一个)就结束拷贝;例:chara[100],b[50];strcpy(a,b);如用strcpy(b,a),要注意a中的字符串长度(第一个'\0'之前)是否超过50位,如超过,则会造成b的内存地址溢出。
strcpy
原型:extern char *strcpy(char *dest,char *src);
{
ASSERT((dest!=NULL)&&(src!=NULL));
Char *address = dest;
While((*dest++=*src++)!=’\0’)
Continue;
Return dest;
}
用法:#include <string.h>
功能:把src所指由NULL结束的字符串复制到dest所指的数组中。
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
返回指向dest的指针。
memcpy
原型:extern void *memcpy(void *dest, void *src, unsigned int count);
{
ASSERT((dest!=NULL)&&(src!=NULL));
ASSERT((dest>src+count)||(src>dest+count));//防止内存重叠,也可以用restrict修饰指针
Byte* bdest= (Byte*)dest;
Byte* bsrc =(Byte*) src;
While(count-->0)
*bdest++ = **bsrc++;
Return dest;
}
用法:#include <memory.h>
功能:由src所指内存区域复制count个字节到dest所指内存区域。
说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针。
memset
原型:extern void *memset(void *buffer, char c, int count);
用法:#include <memory.h>
功能:把buffer所指内存区域的前count个字节设置成字符c。
说明:返回指向buffer的指针。
九, 请讲一讲析构函数和虚函数的用法和作用?
析构函数也是特殊的类成员函数,它没有返回类型,没有参数,不能随意调用,也没有重载。只是在类对象生命期结束的时候,由系统自动调用释放在构造函数中分配的资源。这种在运行时,能依据其类型确认调用那个函数的能力称为多态性,或称迟后联编,动态联编。另: 析构函数一般在对象撤消前做收尾工作,比如回收内存等工作,
虚拟函数的功能是使子类可以用同名的函数对父类函数进行覆盖,并且在调用时自动调用子类覆盖函数,如果是纯虚函数,则纯粹是为了在子类覆盖时有个统一的命名而已。
注意:子类重新定义父类的虚函数的做法叫覆盖(override),而不是overload(重载)。重载指的是存在多个同名函数,这些函数的参数表不同..重载是在编译期间就决定了的,是静态的,因此,重载与多态无关.与面向对象编程无关.
含有纯虚函数的类称为抽象类,不能实例化对象,主要用作接口类。
十,二分查找算法
int Binary_Search(int* a, int n, int key)
{
int low,high,mid;
low = 0; // 最低下标,首位
high = n-1; // 最高下标,末位
while(low <= high)
{
mid = (low+high) / 2; //折半
// 插值 mid = low + (high - low)*(key-a[low])/(a[high]-a[low])
if(key < a[mid]) //比查找值小
high = mid - 1; // 最高下标调整到中位下标的下一位
else if(key > a[mid]) //比查找值大,调整到中位下标大一位
low = mid +1;
else
return mid; //相等,返回中间位置
}
return -1;
}
插值查找:是根据要查找的关键字key与查找表中最大最小记录的关键字比较后的查找方法,其核心就在于插值计算公式。 (key - a[low])/(a[high] - a[low])