算法
非递归式快排模板:
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]);
}
}
}