多益网络提前批笔试题

1、哈希散列值的计算平均查找长度

        哈希表的构造方法:

            (1)、数字分析法:事先知道关键字的集合,且每个关键字的位数比哈希表的地址码位数多时,可以从关键字中选出分布比较均匀的若干位,构成哈希地址。

            (2)、平方取中法:当无法确定关键字中哪几位分布比较均匀时,可以先求出关键字的平方值的中间几位作为哈希地址

            (3)、分段叠加法:按哈希表的地址位数将关键字分成位数相等的几部分(最后一部分较短),然后将这几部分相加,舍弃最高位后的结果就是该关键字的哈希地址。

            (4)、除留余数法:假设哈希表长为 m,p为小于等于 m 的 最大数数,则哈希 函数为 H(k) = k%p

            (5)、伪随机数为:采用一个伪随机函数作为哈希函数,即 H(key) = random(key)

         哈希表处理冲突的方法:

            (1)、开放定址法

            (2)、再哈希法

            (3)、链地址法   

            (4)、建立公共溢出区

          哈希表的性能分析:

                哈希法中影响关键字比较次数的因素有三个:哈希函数,处理冲突的方法,哈希表的装填因子。装填因子 a 的定义如下:         a  = 哈希表中元素的个数 / 哈希表的长度            a 可描述哈希表的装满程度。a 越小,发生冲突的可能性越小; a 越大 ,发生冲突的可能性越大。

           哈希表的查找过程示例:

                

                



2、小根堆的应用

      大根堆和小根堆排序,代码贴上:

        

/*************************************************************************
	> File Name: HeapSort.cpp
	> Author:    arrayli
	> Mail:      [email protected]
	> Created Time: 2018年03月27日 星期二 14时33分47秒
 ************************************************************************/

// 直接插入排序:
// 时间复杂度:         O(nlog2n)
// 最好:               O(nlog2n) 
// 最欢情况:           O(nlog2n)
// 空间复杂度:          O(1)
// 稳定性:             稳定

#include<stdio.h>


// 将堆顶元素与末尾元素进行交换
template<typename T>
void Swap( T* arr,int heapTop,int heapTail )
{
   T temp = arr[heapTop];
    arr[heapTop] = arr[heapTail];
    arr[heapTail] = temp;
}

// 调整大根堆

template<typename T>
void AdjustHeap(T *arr,int currentNode,int HeapLength)
{
   int leftChild = 0,rightChild = 0 ,largest = 0;
    
    leftChild = 2*currentNode + 1;
    rightChild = 2*currentNode + 2;

    // 判断 当前结点的左子节点是否大于当前结点,如果大于当前结点,则 largest = rightChild;
    if(leftChild< HeapLength && arr[leftChild] > arr[currentNode])
        largest = leftChild;
    // 否则 largest = currentNode;
    else
        largest = currentNode;

    // 然后判断当前结点的右子节点是否大于 largest
    if(rightChild < HeapLength && arr[rightChild] > arr[largest])
        largest = rightChild;
    
    if(largest != currentNode) 
    {
        // 交换最大结点和当前结点的值
        // 即将堆顶元素与末尾元素进行交换
        Swap(arr,currentNode,largest);        
       
        // 重新对堆进行调整
        AdjustHeap(arr,largest,HeapLength);
    }
}

// 构建大根堆

template<typename T>
void MaxHeapCreat(T *arr,int len)
{
   int i = 0;
    for( i = len/2;i>=0; i-- )
    {
        AdjustHeap(arr,i,len);
    }
}

// 大根堆排序
template<typename T>
void HeapSort(T *arr,int len)
{
   // 构建大根堆
    MaxHeapCreat(arr,len);

    for(int i = len-1;i>=0;i--)
    {
        // 交换堆顶和最后一个元素,即每次将剩余元素中的最大者放到最后面
        Swap(arr,0,i);
        // 又一次调用堆顶点成为大根堆,仅仅有被交换的分支才有可能不是大根堆
        AdjustHeap(arr,0,i);
    }
}

template<typename T>
void print(T *arr,int len)
{
    for(int i=0;i<len;i++)
    {
        printf("%d\t",arr[i]);
    }
    printf("\n");
}

int main(void)
{
    int arr[] = {9,8,7,6,5,4,3,2,1,0};
    int len = sizeof(arr)/sizeof(arr[0]);
    

    print(arr,len);
    HeapSort(arr,len);
    print(arr,len);

    int arr1[] = {3,9,5,1,6,2,8,4,0,7};
    int len1 = sizeof(arr1)/sizeof(arr1[0]);
    print(arr1,len1);
    HeapSort(arr1,len1);
    print(arr1,len1);
    
    int arr2[] = {48,62,35,77,55,14,35,98};
    int len2 = sizeof(arr2)/sizeof(arr2[0]);
    print(arr2,len2);
    HeapSort(arr2,len2);
    print(arr2,len2);
    return 0;
}


/*************************************************************************
	> File Name: HeapSort.cpp
	> Author:    arrayli
	> Mail:      [email protected]
	> Created Time: 2018年03月27日 星期二 14时33分47秒
 ************************************************************************/

// 直接插入排序:
// 时间复杂度:         O(nlog2n)
// 最好:               O(nlog2n) 
// 最欢情况:           O(nlog2n)
// 空间复杂度:          O(1)
// 稳定性:             稳定

#include<stdio.h>


// 将堆顶元素与末尾元素进行交换
template<typename T>
void Swap( T* arr,int heapTop,int heapTail )
{
   T temp = arr[heapTop];
    arr[heapTop] = arr[heapTail];
    arr[heapTail] = temp;
}

// 调整小根堆

template<typename T>
void AdjustHeap(T *arr,int currentNode,int HeapLength)
{
   int leftChild = 0,rightChild = 0 ,min = 0;
    
    leftChild = 2*currentNode + 1;
    rightChild = 2*currentNode + 2;

    // 判断 当前结点的左子节点是否大于当前结点,如果大于当前结点,则 largest = rightChild;
    if(leftChild< HeapLength && arr[leftChild] < arr[currentNode])
        min = leftChild;
    // 否则 largest = currentNode;
    else
        min = currentNode;

    // 然后判断当前结点的右子节点是否大于 largest
    if(rightChild < HeapLength && arr[rightChild] < arr[min])
        min = rightChild;
    
    if(min != currentNode) 
    {
        // 交换最大结点和当前结点的值
        // 即将堆顶元素与末尾元素进行交换
        Swap(arr,currentNode,min);        
       
        // 重新对堆进行调整
        AdjustHeap(arr,min,HeapLength);
    }
}

// 构建小根堆

template<typename T>
void MaxHeapCreat(T *arr,int len)
{
   int i = 0;
    for( i = len/2;i>=0; i-- )
    {
        AdjustHeap(arr,i,len);
    }
}

// 小根堆排序
template<typename T>
void HeapSort(T *arr,int len)
{
   // 构建小根堆
    MaxHeapCreat(arr,len);

    for(int i = len-1;i>=0;i--)
    {
        // 交换堆顶和最后一个元素,即每次将剩余元素中的最小者放到最后面
        Swap(arr,0,i);
        // 又一次调用堆顶点成为小根堆,仅仅有被交换的分支才有可能不是小根堆
        AdjustHeap(arr,0,i);
    }
}

template<typename T>
void print(T *arr,int len)
{
    for(int i=0;i<len;i++)
    {
        printf("%d\t",arr[i]);
    }
    printf("\n");
}

int main(void)
{
    int arr[] = {9,8,7,6,5,4,3,2,1,0};
    int len = sizeof(arr)/sizeof(arr[0]);
    

    print(arr,len);
    HeapSort(arr,len);
    print(arr,len);

    int arr1[] = {3,9,5,1,6,2,8,4,0,7};
    int len1 = sizeof(arr1)/sizeof(arr1[0]);
    print(arr1,len1);
    HeapSort(arr1,len1);
    print(arr1,len1);
    
    int arr2[] = {48,62,35,77,55,14,35,98};
    int len2 = sizeof(arr2)/sizeof(arr2[0]);
    print(arr2,len2);
    HeapSort(arr2,len2);
    print(arr2,len2);
    return 0;
}

3、后缀表达式

         前缀表达式、中缀表达式、后缀表达式都是四则运算的表达方式,用以四则运算表达式求值,即数学表达式的求值。

         前缀表达式:前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前。比如:- × + 3 4 5 6。前缀表达式求值:从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素 op 次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果

         中缀比表达式:中缀表达式就是常见的运算表达式,如(3+4)×5-6。

         后缀表达式:后缀表达式又称逆波兰表达式,与前缀表达式相似,只是运算符位于操作数之后。比如: 3 4 + 5 × 6 - 。
         具体使用方法,参考博客:https://www.cnblogs.com/Hslim/p/5008460.html

4、哈夫曼编码

     参考博客:https://blog.csdn.net/dongfei2033/article/details/80657360

                      https://translate.google.cn/

5、二叉树的结点计算问题及性质

        性质1 : 二叉树的第 i 层上至多有 2^(i-1) 个结点 (i>=1)

        性质2 :  深度为 k 的二叉树至多有 2^k -1 个结点( k>=1)

        性质3 :  对任意的一颗二叉树 T ,若叶子结点数为 n0,而其度数为 2 的结点数为 n2,则 n0 = n2+1

        性质4 :  具有 n 个结点的完全二叉树的深度 [log2n]+1

        性质 5:  如果有一颗有n个节点的完全二叉树的节点按层次序编号,对任一层的节点i(1<=i<=n)有

                        (1).如果i=1,则节点是二叉树的根,无双亲,如果i>1,则其双亲节点为[i/2],向下取整

                        (2).如果2i>n那么节点i没有左孩子,否则其左孩子为2i

                        (3).如果2i+1>n那么节点没有右孩子,否则右孩子为2i+1

6、关系型数据库的构成

       关系型数据是指以关系数学模型来表示的数据,关系数学模型中以二维表的形式来描述数据。关系型数据库是存储在计算机上的、可共享的、有组织的关系型数据的集合。 关系模型由关系数据结构,关系操作集合、关系完整性约束三部分组成。

7、文件逻辑记录和文件物理记录

    记录是文件存取操作的基本单位。逻辑记录:是按用户观点的基本存取单位。物理记录:是按外存设备观点的基本存取单位。通常逻辑记录和物理记录之间存在三种关系:(1)一个物理记录存放一个逻辑记录; (2)一个物理记录包含多个逻辑记录; (3)多个物理记录表示一个逻辑记录。

8、sql 的索引,主键,唯一索引,联合索引的区别,对数据库有什么影响

          (1)索引是一种特殊的文件,它们包含数据表里的所有记录的引用指针。索引的遵照原则:

                    (a). 最左侧原则:表的最左侧一列,往往数据不会发生改变,不影响其他列的数据

                    (b).命名短小原则:索引命名过长会使索引文件变大,损耗内存。

            (2). 普通索引(由关键字 KEY或 INDEX 定义得到的索引):加快数据的查询速度

            (3). 唯一索引(由关键字 UNIQUE 把它定义为唯一索引):保证数据的唯一性

            (4). 主键:一种特殊的唯一索引,一张表中只能定义一个主键索引,用来标识唯一一条数据,用 PRIMARY KEY 创建

            (5). 联合索引:索引可以覆盖多个数据列,如像 INDEX 索引就是联合索引

            索引可以极大的提高查询访问速度,但是会降低插入,删除,更新表的速度,应为在执行写的操作的时候还要操作索引文件。

9、TCP 传输的时候怎么保证传输的可靠性

            参考我的往期博客: 

                    https://blog.csdn.net/qq_35396127/article/details/80847189

10、在数组中找出三个数字使得它们的和为0,找出所有的这种不包含重复的组合。

set<vector<int>> find_triplets(vector<int> arr)
{
	sort(arr.begin(), arr.end());
	set<vector<int>>ret;
	vector<int>temp(3);
	int n = arr.size();
	for (int i = 0; i < n; ++i)
	{
		int j = i + 1;
		int k = n - 1;
		while (j < k)
		{
			int sum_two = arr[i] + arr[j];
			if (sum_two + arr[k] < 0)
				++j;
			else if (sum_two + arr[k] > 0)
				--k;
			else
			{
				temp[0] = arr[i];
				temp[1] = arr[j];
				temp[2] = arr[k];
				ret.insert(temp);
				++j;
				--k;
			}
		}
	}
	return ret;
}

猜你喜欢

转载自blog.csdn.net/qq_35396127/article/details/80820502