25 7.8上午 栈 队列 二叉搜索树

· · 算法·理论

栈:

#include<bits/stdc++.h>
#define int long long
/*
STL 中的 stack 容器提供了一众成员函数以供调用,其中较为常用的有:
元素访问
st.top() 返回栈顶
修改
st.push() 插入传入的参数到栈顶
st.pop() 弹出栈顶
容量
st.empty() 返回是否为空
st.size() 返回元素数量
此外,std::stack 还提供了一些运算符。较为常用的是使用赋值运算符 = 为 stack 赋值
*/
using namespace std;
stack<int>s;
const int N=1e5+50;
int st[N],top;
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    s.push(1);//入栈 
    st[++top]=1;//模拟入栈 
    int x=s.top();//栈顶 
    s.pop();//弹出 
    x=st[top--];//模拟出栈 

    return 0;
}

推荐题目:UVA12096(洛谷)

UVA12096(vjudge)

UVA12096代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
stack<int>s;
map<set<int>,int>IDset;
vector<set<int> >sets;
int ID(set<int> x){
    if(IDset[x]){
        return IDset[x];
    }
    sets.push_back(x);
    return IDset[x]=sets.size()-1;
}
set<int>set_union(set<int>x1,set<int>x2){
    set<int>::iterator x=x2.begin();
    while(x!=x2.end()){
        x1.insert(*x);
        ++x;
    }
    return x1;
}
set<int>set_inter(set<int>x1,set<int>x2){
    set<int>x;
    x.clear();
    for(auto i:x1){
        if(x2.find(i)!=x2.end()){
            x.insert(i);
        }
    }
//  set<int>::iterator i = x2.begin();
//  while(i != x2.end())
//  {
//      if(x2.find(*i) != x2.end()) 
//          x.insert(*i);
//      ++ i;
//  }
    return x;
}
void clear(){
    while(!s.empty()){
        s.pop();
    }
    IDset.clear();
    sets.clear();
}
void solve(){
    clear();
    int n;
    cin>>n;
    while(n--){
        string op;
        cin>>op;
        if(op[0]=='P'){
            s.push(ID(set<int>()));
        }
        else if(op[0]=='D'){
            s.push(s.top());
        }
        else{
            set<int>x1=sets[s.top()];
            s.pop();
            set<int>x2=sets[s.top()];
            s.pop();
            set<int>x;
            if(op[0]=='U'){
                x=set_union(x1,x2);
            }
            if(op[0]=='I'){
                x=set_inter(x1,x2);
            }
            if(op[0]=='A'){
                x=x2;
                x.insert(ID(x1));
            }
            s.push(ID(x));
        }
        cout<<sets[s.top()].size()<<"\n";
    }
    cout<<"***\n";
}
int T;
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>T;
    while(T--){
        solve();
    }

    return 0;
} 

队列:

#include<bits/stdc++.h>
#define int long long
/*
队列操作对应的代码如下:
插入元素:q[++qr] = x;
删除元素:ql++;
访问队首:q[ql]
访问队尾:q[qr]
清空队列:ql = 1; qr = 0;
STL 中的 queue 容器提供了一众成员函数以供调用。其中较为常用的有:
元素访问
q.front() 返回队首元素
q.back() 返回队尾元素
修改
q.push() 在队尾插入元素
q.pop() 弹出队首元素
容量
q.empty() 队列是否为空
q.size() 返回队列中元素的数量
此外,queue 还提供了一些运算符。较为常用的是使用赋值运算符 = 为 queue 赋值
*/
/*
循环队列
使用数组模拟队列会导致一个问题:随着时间的推移,整个队列会向数组的尾部移动,一旦到达数组的最末端,即使数组的前端还有空闲位置,再进行入队操作也会导致溢出(这种数组里实际有空闲位置而发生了上溢的现象被称为「假溢出」)。
解决假溢出的办法是采用循环的方式来组织存放队列元素的数组,即将数组下标为 0 的位置看做是最后一个位置的后继。(数组下标为 x 的元素,它的后继为 (x + 1) % SIZE)。这样就形成了循环队列。
*/
using namespace std;
queue<int>q;
int q2[N],st,ed;
const int N=1e5+50;
void test(){
    st=1;
    ed=0;
    q.push(1);
    q2[++ed]=1;
    int x=q.front();
    int y=q2[st];
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);

    test();

    return 0;
} 

推荐题目:UVA540(洛谷)

UVA540(vjudge)

UVA540代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,te[1000111],w;
string s;
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    while(1){
        w++;
        int fl=0;
        queue<int>q;
        queue<int>p[1010];
        cin>>n;
        if(n==0){
            return 0;
        }
        for(int i=1;i<=n;i++){
            int num;
            cin>>num;
            for(int j=1;j<=num;j++){
                int k;
                cin>>k;
                te[k]=i;
            }
        }
        while(1){
            cin>>s;
            int num;
            if(s[0]=='E'){
                cin>>num;
                if(p[te[num]].empty()){
                    q.push(te[num]);
                    p[te[num]].push(num);
                }
                else{
                    p[te[num]].push(num);
                }
            }
            if(s[0]=='D'){
                if(fl==0){
                    cout<<"Scenario #"<<w<<"\n";
                    fl=1;
                }
                while(p[q.front()].empty()){
                    q.pop();
                }
                cout<<p[q.front()].front()<<"\n";
                p[q.front()].pop();
            }
            if(s[0]=='S'){
                cout<<"\n";
                break;
            }
        }
    }

    return 0;
}

二叉搜索树:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+50;
int n,rt;
int a[N];
struct Node{
    int data,ls,rs;
}t[N];
/*
二叉搜索树是一种二叉树的树形数据结构,其定义如下:
空树是二叉搜索树。

若二叉搜索树的左子树不为空,则其左子树上所有点的附加权值均小于其根节点的值。

若二叉搜索树的右子树不为空,则其右子树上所有点的附加权值均大于其根节点的值。

二叉搜索树的左右子树均为二叉搜索树。
*/
/*
在以 root 为根节点的二叉搜索树中搜索一个值为 value 的节点。
分类讨论如下:
若 root 为空,返回 false。
若 root 的权值等于 value,返回 true。
若 root 的权值大于 value,在 root 的左子树中继续搜索。
若 root 的权值小于 value,在 root 的右子树中继续搜索。
*/
void build(int x,int l,int r){
    if(l==r){
        t[x].data=a[l];
        return;
    }
    int mid=(l+r)>>1;
    t[x].data=a[mid]; 
    if(l<mid){
        build(x*2,l,mid-1);
    }
    if(r>mid){
        build(x*2+1,mid+1,r);
    }
}
int find(int x,int y){
    if(t[x].data==0)return -1;
    if(t[x].data==y)return x;
    if(t[x].data>y)return find(x*2,y);
    if(t[x].data<y)return find(x*2+1,y);
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    rt=1;
    build(1,1,n);
    int m;
    cin>>m;
    while(m--){
        int x;
        cin>>x;
        cout<<find(rt,x)<<'\n';
    }

    return 0;
}

推荐题目:B4016

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+50;
vector<int>e[N];
int fa[N],deep[N];
int mx;
void dfs(int x){
    if(deep[x]>deep[mx])mx=x;
    for(auto i:e[x]){
        if(i!=fa[x]){
            fa[i]=x;
            deep[i]=deep[x]+1;
            dfs(i);
        }
    }
}
int n;
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n;
    for(int i=1;i<=n;i++){
        int x,y;
        cin>>x>>y;
        e[x].push_back(y);
        e[y].push_back(x);
    }
    dfs(1);
    memset(deep,0,sizeof(deep));
    memset(fa,0,sizeof(fa));
    dfs(mx);
    cout<<deep[mx];

    return 0;
} 

推荐题目:P1305

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
char s[10];
map<char,int>mp;
int n,sz;
struct node{
    char c;
    int ls,rs;
}t[30];
void print(int x){
    cout<<t[x].c;
    if(t[x].ls)print(t[x].ls);
    if(t[x].rs)print(t[x].rs);
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>s;
        if(!mp[s[0]]){
            mp[s[0]]=++sz;
            t[sz].c=s[0];
        }
        if(!mp[s[1]]&&s[1]!='*'){
            mp[s[1]]=++sz;
            t[sz].c=s[1];
        }
        if(!mp[s[2]]&&s[2]!='*'){
            mp[s[2]]=++sz;
            t[sz].c=s[2];
        }
        if(s[1]!='*')t[mp[s[0]]].ls=mp[s[1]];
        if(s[2]!='*')t[mp[s[0]]].rs=mp[s[2]];
    }
    print(1);

    return 0;
}