【实用】游戏开发岗位常见笔试题知识点汇总

1:原文来自 CSDN博主 【趁着头发多我想做游戏】htt防和谐ps://blog.csdn.n防和谐et/weixin_37658157/article/details/88087867 转载请注明出处

文章目录

  • 1.哈希表
  • 2.快速排序
  • 3.二叉树
  • 4.排序算法的时间复杂度和空间复杂度
  • 5.二分查找法的最大寻找次数
  • 6.条件概率
  • 7.C++指针
  • 8.哈夫曼树
  • 9.组合数问题
  • 10.内存读写
  • 11.找唯一数字
  • 12.图的邻接矩阵
  • 13.各种排序算法的实现
  • 14.二分查找法代码实现

1.哈希表

知识点:
http://www.cnblogs.com/gavanwanggw/p/7307596.html

求链地址法的平均长度 ASL(包含查找成功和不成功) : https://blog.csdn.net/ecnuThomas/article/details/69666559

总结:

  1. 线性探测是判断key处的value是否为空,若非空,则继续判断key+1处的value是否为空,直至溢出;
  2. 链地址法是判断key处的value是否为空,若非空,则把value插入到该key处的单链表尾部(该散列表的每个地址都是一个单链表表头)
  3. 查找成功的ASL是:每个key在单链表的index之和除以key的个数
  4. 查找不成功的ASL是:每个单链表的长度之和除以整个链表的总长度;

2.快速排序

知识点:https://www.cnblogs.com/skywang12345/p/3596746.html

左右指针法(基准是每一趟结束时才移动的):设第一个元素为基准,首先从右往左扫描一个比基准小的,再从第二个元素开始从左往右扫描一个比基准大的,交换他们,重复这个过程直到碰头,最后把基准把碰头位置交换,此时基准已经在正确的位置,然后递归这个位置的左半部分和右半部分。

挖坑法(基准每一趟一开始就移动):设第一个元素为基准,首先从右往左扫描一个比基准小的,这个元素的位置定义为“坑”,把这个元素填充到基准位置,再从第二个元素开始从左往右扫描一个比基准大的,把这个元素填充到上一个“坑”位置,重复这个过程直到碰头,这个碰头位置也是一个“坑”,最后把基准的值填充到坑中,此时基准已经在正确的位置,然后递归这个位置的左半部分和右半部分。

注意挖坑法和左右指针法的第一趟排序结果不一定一样!因此没有符合的选项就要换另外一种方法来检验

挖坑法注意:若选择最左边的元素为枢纽,则要先走right指针,原因是:如5 3 4 6 7 8 10 11 12 选5为枢纽,若left先走,则要交换5和6,显然不符合

下面给出左右指针法的代码:

	public static void QuickSort(int[] arr,int left,int right)
	{
		if(left>right)
			return;
		int temp = Partition(arr,left,right);//基准
		QuickSort(arr, left, temp-1);
		QuickSort(arr, temp+1, right);
	}
	
	//左右指针法
	public static int Partition(int[] arr,int left,int right)
	{
		//默认基准index是最左边的那个
		int i = left,j = right,index = left;
		while(i<j)
		{
			while(i<j && arr[j]>=arr[index])
				j--;
			while(i<j && arr[i]<=arr[index])
				i++;
			if(i<j)
			{
				Swap(arr, i, j);
			}
		}
		Swap(arr, j, index);
		return j;
	}

3.二叉树

知识点:https://blog.csdn.net/qq_33243189/article/details/80222629

四种基本的遍历思想为:

前序遍历:根结点 —> 左子树 —> 右子树

中序遍历:左子树 —> 根结点 —> 右子树

后序遍历:左子树 —> 右子树 —> 根结点

层次遍历的步骤是:(相当于广度搜索,上面的都是深度搜索)

1.对于不为空的结点,先把该结点加入到队列中

2.从队头拿出结点,如果该结点的左右结点不为空,就分别把左右结点加入到队列中

3.重复 步骤 2 直到队列为空

感悟:这个前中后序指的是访问根节点的先后

4.排序算法的时间复杂度和空间复杂度

知识点:https://www.cnblogs.com/zhaoshuai1215/p/3448154.html
算法思路(以从小到大排序为例):
1. 冒泡排序: 每个元素和其他元素比较,一旦比自己大,就交换,第一趟的最后一个元素一定是最大的,因此第二趟比较时不需要再比较最后的元素

2. 直接插入排序: 每个元素和左边所有的元素(从右往左)比较,一旦比自己大,就交换,直至找到比自己小的位置;

3. 希尔排序: 最小增量排序,增量公式:n = n / 3 + 1,按增量划分成(Length / 3+1)个分组,每个分组执行直接插入排序,直至增量减少到1;

4. 快速排序:

  • 左右指针法(基准是每一趟结束时才移动的):设第一个元素为基准,首先从右往左扫描一个比基准小的,再从第二个元素开始从左往右扫描一个比基准大的,交换他们,重复这个过程直到碰头,最后把基准把碰头位置交换,此时基准已经在正确的位置,然后递归这个位置的左半部分和右半部分。

  • 挖坑法(基准每一趟一开始就移动):设第一个元素为基准,首先从右往左扫描一个比基准小的,这个元素的位置定义为“坑”,把这个元素填充到基准位置,再从第二个元素开始从左往右扫描一个比基准大的,把这个元素填充到上一个“坑”位置,重复这个过程直到碰头,这个碰头位置也是一个“坑”,最后把基准的值填充到坑中,此时基准已经在正确的位置,然后递归这个位置的左半部分和右半部分。

5.二分查找法的最大寻找次数

设n是数据长度,k是寻找次数
每次二分 直到最后一次才找到 就会有 2^k = n / 2 得到 k = log2(n)+1

6.条件概率

真题:
一个家庭有两个小孩,其中一个是女孩、另一个也是女孩的概率是 1/3

解析:
设事件A为两个孩子中有女孩,事件B为第二个孩子为女孩。

P(A)=1-1/4=3/4(即求至少有一个女孩的情况概率)
P(AB)=1/2*1/2=1/4(两个都是女孩的概率)
P(B|A)=P(AB)/P(A)=1/4 / 3/4 =1/3(条件概率)

另一种解法:两个小孩可能是 男男,男女,女男,女女
已知其中一个是女孩,也就是后三种情况中的一种,男女,女男,女女
只有最后一种情况另一个也是女孩。因此另一个也是女孩的概率是1/3

7.C++指针

真题:
若有以下定义和赋值语句,则与&s[i][j]等价的是 *(p+i)+j

int s[2][3] = {0}, (*p)[3], i, j;
p = s;
i = j = 1;

解析:
int (*p)[3] 表示一个指针,指向一个含有三个元素的数组;
p=s,表示p指向了数组s的第一行,
p+1 表示现在指针指向了数组s的第二行;
*(p+1)表示数组s第二行第一个元素的地址;
*(p+1)+1 表示数组s第二行第二个元素的地址;

8.哈夫曼树

例题:若以{4,5,6,7,8}作为叶子结点的权值构造哈夫曼树,则其带权路径长度是()。

构造方法是每次取最小的两个数, 合并成一个数, 然后循环这种做法, 直到只剩一个点为止。构造的树是

30
17
13
8
9
6
7
4
5

所以带权路径长度是 (4+5)* 3 + (6+7+8) * 2 = 102

9.组合数问题

以下问题的通用答案:S=C(2n,n)-C(2n,n-1)

1.括号化问题。
矩阵链乘: P=a1×a2×a3×……×an,依据乘法结合律,不改变其顺序,只用括号表示成对的乘积,试问有几种括号化的方案?(h(n)种)


2.出栈次序问题。
一个栈(无穷大)的进栈序列为1,2,3,..n,有多少个不同的出栈序列?

类似:有2n个人排成一行进入剧场。入场费5元。其中只有n个人有一张5元钞票,另外n人只有10元钞票,剧院无其它钞票,问有多少中方法使得只要有10元的人买票,售票处就有5元的钞票找零?(将持5元者到达视作将5元入栈,持10元者到达视作使栈中某5元出栈)


3.将多边行划分为三角形问题。
将一个凸多边形区域分成三角形区域的方法数?
		类似:一位大城市的律师在她住所以北n个街区和以东n个街区处工作。每天她走2n个街区去上班。如果她从不穿越(但可以碰到)从家到办公室的对角线,那么有多少条可能的道路?
类似:在圆上选择2n个点,将这些点成对连接起来使得所得到的n条线段不相交的方法数?


4.给顶节点组成二叉树的问题。
给定N个节点,能构成多少种不同的二叉树?

10.内存读写

真题:
i的初始值为0,i++在两个线程里面分别执行100次,能得到最大值是 200 ,最小值是 2

解析:
i++只需要执行一条指令,并不能保证多个线程i++操作同一个i,可以得到正确的结果。
因为还有寄存器的因素,多个cpu对应多个寄存器。每次要先把i从内存复制到寄存器,
然后++,然后再把i复制到内存中,这需要至少3步。

最小值是 2 情况分析:
【实用】游戏开发岗位常见笔试题知识点汇总_第1张图片

11.找唯一数字

根据异或运算特点:
1.异或满足交换律。
2.相同两个数异或为0。
3.0异或一个数为那个数本身。
如 1^ 2 ^ 1 = 1 ^ 1 ^ 2 = 0 ^ 2 = 2

public static int singleNumber(int[] A) {
    int num = 0;
    for(int i=0;i<A.length;i++){
        num^=A[i];
    }
    return num;
}

12.图的邻接矩阵

知识点:https://blog.csdn.net/qq_35295155/article/details/78639997

13.各种排序算法的实现

 public static void BubbleSort(int[] arr)
	{
		for(int i=0;i<arr.length;i++)//控制比较趟数
		{
			for(int j=0;j<arr.length-1-i;j++)//控制每一趟两两比较次数,每一趟排序完最后一个元素都是已经排好的,下一趟不需要再比较
			{
				if(arr[j]>arr[j+1])
				{
					Swap(arr, j, j+1);
				}
			}
		}
	}
	
	public static void InsertSort(int[] arr)
	{
		for (int i = 1; i < arr.length; i++) 
		{
			for (int j = i; j > 0; j--) 
			{
				if(arr[j]<arr[j-1])
				{
					Swap(arr, j, j-1);
				}
				else 
				{
					break;//由于每一趟结束,左部分是一个有序数组,一旦碰到比自己小的元素,则证明其他更小,所以可以跳出循环
				}
			}
		}
	}
	
	
	public static void ShellSort(int[] arr)
	{
		//增量
		int n = arr.length;
		while(n>1)//增量不断减少,直至为1
		{
			n = n/3+1;
			for (int i = 0; i < n; i++) {//一共分为了n/3+1个分组,如长度为5,则增量为2,共2组,可自行试验
				//每个分组分别进行直接插入排序
				for(int j = i+n; j < arr.length;j+=n)//从分组的第二个元素开始比较该元素左边的所有元素
				{
					for(int k = j;(k-n)>=0 && k > 0;k-=n)//注意比较的两个数的下标都要大于等于0
					{
						if(arr[k]<arr[k-n])						
						{
							Swap(arr, k, k-n);
						}
						else 
						{
							break;
						}
					}			
				}
			}
		}
	}
	
	
	public static void SelectSort(int[] arr)
	{
		for (int i = 0; i < arr.length; i++) {
			int minIndex = i;
			for (int j = i+1; j < arr.length; j++) {
				if(arr[minIndex] > arr[j])
				{
					minIndex = j;
				}
			}
			Swap(arr, minIndex, i);
		}
	}
	
	
	public static void QuickSort(int[] arr,int left,int right)
	{
		if(left>right)
			return;
		int temp = Partition(arr,left,right);//基准
		QuickSort(arr, left, temp-1);
		QuickSort(arr, temp+1, right);
	}
	
	//左右指针法
	public static int Partition(int[] arr,int left,int right)
	{
		//默认基准index是最左边的那个
		int i = left,j = right,index = left;
		while(i<j)
		{
			while(i<j && arr[j]>=arr[index])
				j--;
			while(i<j && arr[i]<=arr[index])
				i++;
			if(i<j)
			{
				Swap(arr, i, j);
			}
		}
		Swap(arr, j, index);
		return j;
	}

14.二分查找法代码实现

int BinSearch(SeqList *R,int n,KeyType K)
{
    //在有序表R[0..n-1]中进行二分查找,成功时返回结点的位置,失败时返回-1
    int low=0,high=n-1,mid;     //置当前查找区间上、下界的初值
    while(low<=high)
    {
        if(R[low].key==K)
            return low;
        if(R[high].key==k)
            return high;          //当前查找区间R[low..high]非空
        mid=low+(high-low)/2;
            /*使用(low+high)/2会有整数溢出的问题
            (问题会出现在当low+high的结果大于表达式结果类型所能表示的最大值时,
                这样,产生溢出后再/2是不会产生正确结果的,而low+((high-low)/2)
                不存在这个问题*/
        if(R[mid].key==K)
          return mid;             //查找成功返回
        if(R[mid].key<K)
          low=mid+1;              //继续在R[mid+1..high]中查找
        else
          high=mid-1;             //继续在R[low..mid-1]中查找
    }
    return -1;//当low>high时表示所查找区间内没有结果,查找失败
}

原文来自 CSDN博主 【趁着头发多我想做游戏】htt防和谐ps://blog.csdn.n防和谐et/weixin_37658157/article/details/88087867 转载请注明出处

你可能感兴趣的:(学习笔记,笔试)