算法
非递归式快排模板:
void quick_sort(int q[], int l, int r)void quick_sort(vector<int> q, int l, int r){ if (l >= r) return; stack<int> stk; stk.push(l), stk.push(r); // 将 left 和 right两个元素指针压进栈里; while (stk.size()) { int rr = stk.top(); stk.pop(); // poll() 操作; int ll = stk.top(); stk.pop(); //取出并推出左右指针; if (ll < rr) { int i = ll - 1, j = rr + 1, x = q[ll + rr >> 1]; // 将中间元素取做; while (i < j) { do ++i; while (q[i] < x); //对元素的移动会优先执行; do --j; while (q[j] > x); // 略过符合增序的两端元素; if (i < j) swap(q[i], q[j]); // 交换不符合两端切分的元素; } stk.push(ll), stk.push(j); // 依次压入左,中左,中右,右; stk.push(j + 1), stk.push(rr); } // 下一次循环会优从右半边到左半边,因为取值的时候会先取右边,所以压栈的时候要先从左边压到右边; }}
使用C++ 的 STL 库排序:
void quick_sort(int q[], int n){ sort(q, q+n);}
归并算法模板:
using namespace std;void merge (vector<int> &nums, int l1, int r1, int l2, int r2 ) { int i = l1, j = l2; vector<int> tmp(nums. size() ); int index=0; while(i<=r1 && j<=r2){ if(nums[i]<=nums[j]){ tmp[index++] = nums[i++];}else{ tmp[index++] = nums[j++]; }}while(i <= r1) tmp[index++]=nums[i++];while(j <= r2) tmp[index++]=nums[j++];for(inti=0; i<index; i++){ nums[l1+i]=tmp[i]; }}void mergeSort(vector<int> &nums, int left, int right){ if(left < right){ int mid = (left+right)/2; mergeSort(nums, left, mid); mergeSort(nums, mid+1, right); merge(nums, left, mid, mid+1, right); }}
堆排序
using namespace std;void adjust(vector<int> &nums, int i, int n){// i为待调整的节点,n为nums数组元素的个数,从上往下调整int j = 2*i + 1;// 左子节点while(j<n){ if(j+1 < n && nums[j+1] > nums[j]) j++;// 比较左右孩子谁更大 if(nums[j] < nums[i]) break;// 都比父节点小就停止 else{ swap(nums[i],nums[j]); i = j;// 继续往下调整 j= 2*i + 1; } }}void HeapSort(vector<int> &nums){ int n= nums.size(); for(int i=n/2-1; i>=0; i--){// 从第一个非叶子节点开始(从下往上看第一个) adjust(nums ,i,n); } for(int i=n-1; i>=1; i--){ swap(nums[0], nums[i]);// 交换堆顶和最末一个元素 adjust(nums,0,i);// 将最末一个元素去除,再进行调整 }}
素数筛
/* |埃式筛法| |快速筛选素数|*/int prime[maxn]; bool is_prime[maxn];int sieve(int n){ int p = 0; for(int i = 0; i <= n; ++i) is_prime[i] = true; is_prime[0] = is_prime[1] = false; for (int i = 2; i <= n; ++i){ // 注意数组大小是n if(is_prime[i]){ prime[p++] = i; for(int j = i + i; j <= n; j += i) // 轻剪枝,j必定是i的倍数 is_prime[j] = false; } } return p; // 返回素数个数}
快速幂
/*
|快速幂|
*/
typedef long long LL; // 视数据大小的情况而定
LL powerMod(LL x, LL n, LL m)
{
LL res = 1;
while (n > 0){
if (n & 1) // 判断是否为奇数,若是则true
res = (res * x) % m;
x = (x * x) % m;
n >>= 1; // 相当于n /= 2;
}
return res;
}
全排列
/*
|求1到n的全排列, 有条件|
|16/11/05ztx, thanks to wangqiqi|
*/
void Pern(int list[], int k, int n) { // k表示前k个数不动仅移动后面n-k位数
if (k == n - 1) {
for (int i = 0; i < n; i++) {
printf("%d", list[i]);
}
printf("\n");
}else {
for (int i = k; i < n; i++) { // 输出的是满足移动条件所有全排列
swap(list[k], list[i]);
Pern(list, k + 1, n);
swap(list[k], list[i]);
}
}
}