主要是从同学这打听到的,于是自己也写了一下。第一道就是叫手写一个堆排序,第二道是写幂,第三道链表反转。
堆排序
堆排序其实就是叫建堆嘛,最大堆和最小堆,之前也写过,具体见 堆和堆排序。这次写的时候写成了模板,想着要好点。
#include <iostream>
#include <algorithm>
using namespace std;
// 两个比较仿函数,STL有自带的,也可用自带的 greater 和 less
template<typename type>
struct mgreater{
bool operator()(const type& a, const type& b){return a>b;}
};
template<typename type>
struct msmaller{
bool operator()(const type& a, const type& b){return a<b;}
};
template<typename type, typename COMP>
class heap{
private:
type *heaptop; // 用数组存储,来构建堆
int len; // 存储堆大小
COMP comp;
public:
heap(int length){
heaptop = new type[length]; // 预分配堆大小
len = 0;
}
~heap(){ delete [] heaptop;} // 释放堆
void insertNode(type nums){ // 新节点插入
if(0==len) { // 堆为空,即直接插入,无需上调
heaptop[len++] = nums;
return;
}
int cur = len++; // 插入新节点,放入末尾,并进行上调
heaptop[cur] = nums;
while(cur>0){
if(comp(heaptop[cur], heaptop[(cur-1)/2])) break;
// 当前节点和父节点比较,父节点满足和子节点的comp,则交换
swap(heaptop[cur], heaptop[(cur-1)/2]);
cur = (cur-1)/2;
}
}
type gettop(){ // 仅返回堆顶点,不执行删除
if(len<=0) return -1;
return heaptop[0];
}
int getLen(){ return len;} //返回堆大小
type removeNode(){ //删除堆顶点,并返回堆顶元素
if(len<=0) return static_cast<type>(-1);
swap(heaptop[0], heaptop[--len]); // 将堆顶元素和末尾元素交换,堆大小-1,实现假删除
int cur = 0;
int child = (cur+1)*2; // 右孩子位置
while(child<len){
/**
** 这里需要跟插入时比对好,选择一个和父节点进行交换,因为此时的父节点是从末尾交换而来,
** 所以一定是可以下沉的
**/
if(comp(heaptop[child], heaptop[child-1])){
swap(heaptop[child-1], heaptop[cur]);
cur = child - 1;
} else {
swap(heaptop[child], heaptop[cur]);
cur = child;
}
child = (cur+1)*2;
}
// 跳出循环,可能只有一个左孩子节点,做最后的分析
if(child-1<len && comp(heaptop[cur], heaptop[child-1]))
swap(heaptop[cur], heaptop[child-1]);
return heaptop[len];
}
};
int main()
{
int a[10] = {3,2,3,4,1,6,7,19,10,8};
// priority_queue<int, vector<int>, greater<int>> mm;
heap<int, mgreater<int>> hh(10);
for(int i=0;i<10;i++){
hh.insertNode(a[i]);
}
cout <<"size: " <<hh.getLen() <<endl;
while(hh.getLen()>0){
cout <<hh.removeNode() <<" ";
}
cout <<endl;
return 0;
}
求幂
求幂那就再经典不过了,快速幂,思想就是利用幂的特性,实现底数的快速翻倍,从而达到幂的指数增长。直接上代码了
#include <iostream>
using namespace std;
// 快速幂的思想就是利用 将底数翻倍的思想来达到 幂的指数增长
int quickm(int m, int n)
{
if(1==m || 0==n) return 1;
else if(1==n) return m;
long long res = 1; // 结果用long long 存储
while(n){
if(n&1) res*=m;
m*=m;
n>>=1;
}
return res;
}
int main()
{
cout <<"2, 8: " <<quickm(2,8) <<endl;
cout <<"10, 3: " <<quickm(10,3) <<endl;
cout <<"1, 99: " <<quickm(1,99) <<endl;
cout <<"2, 20: " <<quickm(2,20) <<endl;
return 0;
}
单链表反转
链表反转也是比较常问的题目,一般的方法就是双指针的方法,还有一个呢就是想法比较质朴的,额外数组存储,另起一个链表。我自己使用双指针来写的,直接上代码:
#include <iostream>
using namespace std;
struct node{
int value;
node* next;
node(int val){
value = val;
next = NULL;
}
};
void printLink(node *head)
{ //链表打印
node *tem = head;
while(tem!=NULL){
cout <<tem->value <<" ";
tem = tem->next;
}
cout <<endl;
}
node* reverseLink(node *head)
{
if(head==NULL || head->next==NULL) return head;
// 就是一个记录head 节点的前驱,一个记录后驱,加上head本身,三个节点
node *p1 = NULL, *p2 = head->next;
while(p2!=NULL){
head->next = p1;
p1 = head;
head = p2;
p2 = p2->next;
}
head->next = p1;
return head;
}
int main()
{
int a[10] = {1, 2,3,4,5,6,7,8,9,10};
node *head = new node(1);
node *tem = head;
for(int i=1;i<10;i++){
tem->next = new node(a[i]);
tem = tem->next;
}
printLink(head);
head = reverseLink(head);
printLink(head);
return 0;
}
虽然都不太难,但是在面试的情况下,叫我现场手写还是达不到很快就能写出来的地步。确实还是要加强练习啊,像有同学面试的时候三分钟手写快排,已经惊呆了。

这篇博客分享了2020年腾讯实习生招聘面试中遇到的三道算法题,包括堆排序的实现、快速幂求幂操作以及单链表的反转方法。通过代码展示了解题思路,强调面试中快速解决问题的重要性,提示需要加强算法练习。
1913

被折叠的 条评论
为什么被折叠?



