算法板子(持续更新中)

文章目录

      • 区间问题
        • 线段树
      • 二叉树
        • 二叉树链表实现
      • 搜索
        • 深度优先遍历
        • 广度优先遍历

区间问题

线段树

#include
using namespace std;
const int N=1000;

int arr[N],tree[N],lazy[N];
void build(int start,int end,int cp){
    //如果左右重合 说明到了叶子节点
    //叶子节点的值即为原数组的值
    if(start==end){
        tree[cp]=arr[start];
        return;
    }

    int lchild=cp<<1;
    int rchild=(cp<<1) +1;
    int mid=(start+end)/2;
     
    build(start,mid,lchild);//建立左子树
    build(mid+1,end,rchild);//建立右子树

    tree[cp]=tree[lchild]+tree[rchild];//维护区间和
}
//区间求和
//求区间[l,r]的和
int getSum(int l,int r,int start,int end,int cp){

    int mid=(start+end)/2;
    int lchild=cp<<1;
    int rchild=(cp<<1)+1;
    //如果有懒标记 下放
    if(lazy[cp]){
    tree[lchild]+=(mid-start+1)*lazy[cp];
    tree[rchild]+=(end-mid)*lazy[cp];
    lazy[lchild]+=lazy[cp];
    lazy[rchild]+=lazy[cp];
    lazy[cp]=0;
    }

    //无重合区域 剪枝
    if(r<start||l>end) return 0;
    //如果查询区间包含当前区间
    else if(l<=start&&end<=r) {
  
        return tree[cp];
    }
    else{
 
    int sum=0;
    //如果查询区域和当前区间的左半部分有重合,查询左子树
    if(l<=mid) 
    sum+=getSum(l,r,start,mid,lchild);
    //如果查询区间和当前区间的右半部分有重合,查询右子树
    if(r>=mid)
    sum+=getSum(l,r,mid+1,end,rchild);
    return sum;
    }

}
//区间修改 
//将区间【l,r】 每个数都加上val
void update(int l,int r,int val,int start,int end,int cp){
    
    if(l>end||r<start) return;

    else if(l<=start&&end<=r){
    
        tree[cp]+=(end-start+1)*val;
        //如果非叶子节点 打上懒标记
        if(start!=end)   lazy[cp]+=val;
    }
    else{
        int mid=(start+end)/2;
        int lchild=cp<<1;
        int rchild=(cp<<1)+1;
        if(l<=mid) update(l,r,val,start,mid,lchild);
        if(r>=mid) update(l,r,val,mid+1,end,rchild);

        tree[cp]=tree[lchild]+tree[rchild];
    }
}

二叉树

二叉树链表实现

#include
using namespace std;

struct Tree{
    char val;
    Tree* left;
    Tree* right;
    Tree(char c=0):val(c),left(0),right(0){}
}root;

Tree* build(char c){
    if(c=='*') return 0;
    return new Tree(c);
}
Tree* search(char c,Tree* start= &root){
    if(start->val==c) return start;
    Tree* ans=0;
    if(start->left) ans=search(c,start->left);
    if(ans) return ans;
    if(start->right) ans=search(c,start->right);

    return ans;

}
Tree* pre(Tree* start){

    cout<<start->val;
    if(start->left) pre(start->left);
    if(start->right) pre(start->right);
}

搜索

深度优先遍历

int dfs(vector<vector<int>> &grid, int cur_i, int cur_j)
{
    if (cur_i < 0 || cur_j < 0 || cur_i == grid.size() || cur_j == grid[0].size() || grid[cur_i][cur_j] != 1)
        return 0;
    grid[cur_i][cur_j] = 0;
    int di[4] = {0, 0, 1, -1};
    int dj[4] = {1, -1, 0, 0};
    int ans = 1;
    for (int index = 0; index != 4; ++index)
    {
        int next_i = cur_i + di[index], next_j = cur_j + dj[index];
        ans += dfs(grid, next_i, next_j);
    }
    return ans;
 }
}

广度优先遍历

int bfs(vector<vector<int>> &grid, int cur_i, int cur_j)
{
    
    grid[cur_i][cur_j] = 0;
    queue<pair<int, int>> q;
    q.push(make_pair(cur_i, cur_j));
    int ans = 1;
    while (!q.empty())
    {
        pair<int, int> x = q.front();
        q.pop();
        int di[4] = {0, 0, 1, -1};
        int dj[4] = {1, -1, 0, 0};

        for (int index = 0; index != 4; ++index)
        {
            int next_i = x.first + di[index], next_j = x.second + dj[index];
            if (next_i < 0 || next_i == grid.size() || next_j < 0 || next_j == grid[0].size || !grid[next_i][next_j])
                continue;

            grid[next_i][next_j] = 0;
            q.push(make_pair(next_i, next_j));

            ans += 1;
        }
    }

    return ans;
 }

你可能感兴趣的:(算法)