一开始看函数指针的时候我是很懵的,因为不知道它有什么用,之后慢慢就发现了自己的愚昧无知。
假设我们想实现一个数据结构,比如二叉搜索树,堆。又或者是一个快排,归并排序。
我们一般是直接在两个数要比较的时候直接采用运算符比较大小,但是这样的缺点是,如果我要大顶堆就要单独写大顶堆,小顶堆也要单独实现。
很明显这样的代码复用性很低,两串除了比较运算符不同其他全部相同的代码自己看着也难受,这个时候就是函数指针出马的时候了。比如下面我写的这个堆
#include<bits/stdc++.h>
using namespace std;
const int MAXN = ;
typedef bool (*PF)(int,int);///这句定义意思是:PF类型是指向bool (int, int)类型函数的函数指针
bool cmp1(int a, int b) {return a<b;}///
bool cmp2(int a, int b) {return a>b;}///
struct Heap{
int siz;
int num[MAXN];
bool (*cmp)(int,int);///参数传大于就是大顶堆
Heap(PF pf = cmp2):siz(),cmp(pf) {};///默认用大顶堆的比较函数大顶堆
void shift_up(int now) {
while(now>>) {
if(cmp(num[now], num[now>>])) {
swap(num[now], num[now>>]);
now>>=;
} else break;
}
}
void shift_down(int now) {
int point;
while(now<<<=siz) {
point = now<<;
if(now<<^ <= siz && cmp(num[now<<^], num[now<<]))
point ^= ;
if(cmp(num[point], num[now])) {
swap(num[point], num[now]);
now = point;
} else break;
}
}
bool Empty() { return siz; }
int Top() { return siz?num[]:-; }
void Pop() {
if(siz == ) return ;
num[] = num[siz--];
shift_down();
}
void Push(int val) {
if(siz+ == MAXN)
return;
num[++siz] = val;
shift_up(siz);
}
};
(如果写错了告诉我一下,我写完没严谨的测试一下, 因为重点是讲函数指针)
上面那个函数里面有一个函数指针;
这个指针在构造函数里初始化是cmp2,为了构建大顶堆。
但是我们要小顶堆也很容易,Heap hh(cmp1);这样定义出来的hh就是小顶堆,同理我们就可以实现自己的二叉搜索树等等。
比如下面的这个快排就是用传入的函数指针来排序,这样可以升序降序都没问题。、
#include<bits/stdc++.h>
using namespace std;
const int MAXN = ;
typedef bool (*PF)(int,int);///这句定义意思是:PF类型是指向bool (int, int)类型函数的函数指针
bool cmp1(int a, int b) {return a<b;}///
bool cmp2(int a, int b) {return a>b;}///
int single_sort(int l, int r, int num[], PF cmp=cmp1){
int key=num[l];
while(l<r){
while(l<r&&cmp(key,num[r]))
--r;
num[l]=num[r];
while(l<r&&cmp(num[l], key))
++l;
num[r]=num[l];
}
num[l]=key;
return l;
}
void qsort(int l, int r, int num[], PF cmp=cmp1){
if(l+>=r) return;
int k = single_sort(l, r, num, cmp);
qsort(l, k, num, cmp);
qsort(k+, r, num, cmp);
}
int main() {
int num[]={, , , , ,, , , , };
qsort(, , num, cmp2);
for(int i=; i<; ++i){
printf("%d ", num[i]);
}
}
快速排序
同理其他排序也可以做到这样