数据结构(二)

(1)单调队列:典型问题----滑动窗口

#include
#include
using namespace std;
const int N=1000010;
int n,k;
int a[N],q[N],hh=0,tt=-1;//tt=-1表示目前还没有元素。
//个人理解,对于冗杂数据,由于是单调队列,靠近对首的值越小,对于一个对尾,如果插入的a[i]《=它,
//由于a[i]生存周期比它久,所以这个冗杂元素一定不会被用到。
int main()
{
    cin>>n>>k;
    for(int i=0;iq[hh]) hh++;
        while(hh<=tt&&a[i]<=a[q[tt]])tt--;
        q[++tt]=i;
     if(i+1>=k)printf("%d ",a[q[hh]]);
    }
    printf("\n");
    hh=0,tt=-1;
    for(int i=0;iq[hh]) hh++;
        while(hh<=tt&&a[i]>=a[q[tt]]) tt--;
        q[++tt]=i;
      if(i+1>=k)printf("%d ",a[q[hh]]);
    }
    
    
  return 0;
}

用数组来模拟单调队列,需要设置一个头指针和尾指针,且尾指针初始没有指向任何值设为0,当插入第一个数时,头尾对齐,对于本题,有一个核心的思路:生存周期,也就是后进队列的数生存周期一定比之前的生存周期久,也就是说,不管队列因为比较排出去多少个数,都不会有影响,只要保证队列的单调性,同时由于移动的长度每次是一所以每次调整对头只需要前移一格就行了。

(2)模拟堆

#include
#include
#include
using namespace std;
//ph储存第k个插入数的下标,hp储存下标对应的插入数;
int n,m;
const int N =100010;
int h[N],size1,hp[N],ph[N];
void heap_swap(int a,int b)//a,b指对应的下标
{
swap(ph[hp[a]],ph[hp[b]]);
swap(hp[a],hp[b]);
swap (h[a],h[b]);

    
}

void down(int u)
{
    int t=u;
    if(2*u<=size1&&h[u*2]h[u])
  {
      heap_swap(u/2,u);
      u/=2;
  }
}

int main()
{
    int n,m=0;
    scanf("%d",&n);
    while(n--)
    {
        char op[10];
        int k,x;
        scanf("%s",op);
        if(!strcmp(op,"I"))
        {
            scanf("%d",&x);
            size1++;
            m++;
            h[size1]=x;
            hp[size1]=m; //对应节点是第几个插入的数
            ph[m]=size1; //第几个插入的数是堆中的第几个节点。
            up(size1); //这里漏了
        
        }
        
        else if(!strcmp(op,"PM"))
        printf("%d\n",h[1]);
        else if(!strcmp(op,"DM"))
        {
         heap_swap(1,size1);
         size1--;
         down(1);
     
            
        }
    else if(!strcmp(op,"D"))
    {
        scanf("%d",&k);
        k=ph[k];
        heap_swap(size1,k);
        size1--;
        down(k),up(k);
     
    }
        else
        {
            scanf("%d %d",&k,&x );
            k=ph[k];
            h[k]=x;
            down(k),up(k);
        
        }
        
    }
    
    return 0;
}

这里面的hp[],ph[]函数,hp储存对应子节点储存的是第几个插入的数,ph储存的是第几个插入的数是堆中的哪个节点。

你可能感兴趣的:(数据结构,数据结构,c语言,c++)