zoukankan      html  css  js  c++  java
  • 循环队列

    循环队列

    队列:先进先出,FIFO。

    牺牲一个单元,使队列为空和只有一个元素时不要产生歧义

     

    队首front,队尾rear,队列为a[front+1]~a[rear]

    开一个大小为n的数组,a:array[0..n-1] of longint ,当rear=n-1时,需要在队尾增加一个数据,此时没有存储空间,但此时使用的内存单元只是a[front+1]~a[rear],前面的a[1]~a[front]内存单元未被使用,却没有存储空间,导致假溢出。

     

    可以使用循环队列,当rear=n-1,增加一个数据,则rear变为0,即回到原点。相当于把数组看成一个圆,设置圆的开头和结尾(相邻),从开头到结尾存储数据,当到了结尾,又重新返回开头。

    Spfa常使用循环队列,从而节省队列的内存。

    注意:

    1.在队列里的点都不重复,所以队列的长度小于等于n(点的总个数)+1(牺牲的一个单元),

    2.不用判断队列大小单元不够,只要开的足够大即可

     

     

    ccf20170304类似spfa:

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <malloc.h>
      4 #include <stdbool.h>
      5 #define maxn 100000
      6 #define maxm 200000
      7 #define maxc 1000000
      8  
      9 long max(long a,long b)
     10 {
     11     if (a>b)
     12         return a;
     13     else
     14         return b;
     15 }
     16  
     17 int main()
     18 {
     19     struct node
     20     {
     21         long d,len;
     22         struct node *next;
     23     };
     24     long n,m,head,tail,d,value,i,a,b,c;
     25     long *dis=(long *) malloc (sizeof(long)*(maxn+1));
     26     //循环队列
     27     long *line=(long *) malloc (sizeof(long)*(maxn+1));
     28     bool *vis=(bool *) malloc (sizeof(bool)*(maxn+1));
     29     //本身已经是struct node *point,创建数组再加"*"
     30     struct node **point=(struct node **) malloc (sizeof(struct node *)*(maxn+1));
     31     struct node *t;
     32     scanf("%ld%ld",&n,&m);
     33  
     34     for (i=1;i<=n;i++)
     35     {
     36         point[i]=NULL;
     37         //1 ≤ c ≤ 1000000
     38         //max<=c
     39         dis[i]=maxc;
     40         vis[i]=true;
     41     }
     42     for (i=1;i<=m;i++)
     43     {
     44         scanf("%ld%ld%ld",&a,&b,&c);
     45         //build a
     46         t=(struct node *) malloc (sizeof(struct node));
     47         t->d=b;
     48         t->len=c;
     49         if (point[a]!=NULL)
     50             t->next=point[a];
     51         else
     52             t->next=NULL;
     53         point[a]=t;
     54         //build b
     55         t=(struct node *) malloc (sizeof(struct node));
     56         t->d=a;
     57         t->len=c;
     58         if (point[b]!=NULL)
     59             t->next=point[b];
     60         else
     61             t->next=NULL;
     62         point[b]=t;
     63     }
     64     dis[1]=0;
     65     vis[1]=false;
     66     line[1]=1;
     67     //head=front-1 牺牲一个位置 front为队列头位置
     68     head=0;
     69     tail=1;
     70     //这里的循环队列不用判断空或者溢出
     71     //因为如果那样的话,已经不能用了。
     72     //不存在空的情况。而数组要开的足够大,使队列不溢出。
     73     while (head!=tail)
     74     {
     75         //head++;
     76         //队列为0~n
     77         head++;
     78         if (head==n+1)
     79             head=0;
     80         d=line[head];
     81         t=point[d];
     82         while (t)
     83         {
     84             if (dis[d]<t->len)
     85                 value=t->len;
     86             else
     87                 value=dis[d];
     88             if (value<dis[t->d])
     89             {
     90                 dis[t->d]=value;
     91                 //如果该点未被放在队列里,则入队;否则不入队
     92                 //即在队列里的点都不重复
     93                 //则队列(tail-head)最多有n+1个数(n个点+空位置(head))
     94                 if (vis[t->d])
     95                 {
     96                     //tail++;
     97                     tail++;
     98                     if (tail==n+1)
     99                         tail=0;
    100                     line[tail]=t->d;
    101                     vis[t->d]=false;
    102                 }
    103             }
    104             t=t->next;
    105         }
    106         vis[d]=true;
    107     }
    108     printf("%ld
    ",dis[n]);
    109     return 0;
    110 }
      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <malloc.h>
      4 #include <stdbool.h>
      5 #define maxn 100000
      6 #define maxm 200000
      7 #define maxc 1000000
      8  
      9 long max(long a,long b)
     10 {
     11     if (a>b)
     12         return a;
     13     else
     14         return b;
     15 }
     16  
     17 int main()
     18 {
     19     struct node
     20     {
     21         long d,len;
     22         struct node *next;
     23     };
     24     long n,m,head,tail,d,value,i,a,b,c;
     25     long *dis=(long *) malloc (sizeof(long)*(maxn+1));
     26     //循环队列
     27     long *line=(long *) malloc (sizeof(long)*(maxn+1));
     28     bool *vis=(bool *) malloc (sizeof(bool)*(maxn+1));
     29     //本身已经是struct node *point,创建数组再加"*"
     30     struct node **point=(struct node **) malloc (sizeof(struct node *)*(maxn+1));
     31     struct node *t;
     32     scanf("%ld%ld",&n,&m);
     33  
     34     for (i=1;i<=n;i++)
     35     {
     36         point[i]=NULL;
     37         //1 ≤ c ≤ 1000000
     38         //max<=c
     39         dis[i]=maxc;
     40         vis[i]=true;
     41     }
     42     for (i=1;i<=m;i++)
     43     {
     44         scanf("%ld%ld%ld",&a,&b,&c);
     45         //build a
     46         t=(struct node *) malloc (sizeof(struct node));
     47         t->d=b;
     48         t->len=c;
     49         if (point[a]!=NULL)
     50             t->next=point[a];
     51         else
     52             t->next=NULL;
     53         point[a]=t;
     54         //build b
     55         t=(struct node *) malloc (sizeof(struct node));
     56         t->d=a;
     57         t->len=c;
     58         if (point[b]!=NULL)
     59             t->next=point[b];
     60         else
     61             t->next=NULL;
     62         point[b]=t;
     63     }
     64     dis[1]=0;
     65     vis[1]=false;
     66     line[1]=1;
     67     //head=front-1 牺牲一个位置 front为队列头位置
     68     head=0;
     69     tail=1;
     70     //这里的循环队列不用判断空或者溢出
     71     //因为如果那样的话,已经不能用了。
     72     //不存在空的情况。而数组要开的足够大,使队列不溢出。
     73     while (head!=tail)
     74     {
     75         //head++;
     76         //队列为0~n
     77         head++;
     78         if (head==n+1)
     79             head=0;
     80         d=line[head];
     81         t=point[d];
     82         while (t)
     83         {
     84             if (dis[d]<t->len)
     85                 value=t->len;
     86             else
     87                 value=dis[d];
     88             if (value<dis[t->d])
     89             {
     90                 dis[t->d]=value;
     91                 //如果该点未被放在队列里,则入队;否则不入队
     92                 //即在队列里的点都不重复
     93                 //则队列(tail-head)最多有n+1个数(n个点+空位置(head))
     94                 if (vis[t->d])
     95                 {
     96                     //tail++;
     97                     tail++;
     98                     if (tail==n+1)
     99                         tail=0;
    100                     line[tail]=t->d;
    101                     vis[t->d]=false;
    102                 }
    103             }
    104             t=t->next;
    105         }
    106         vis[d]=true;
    107     }
    108     printf("%ld
    ",dis[n]);
    109     return 0;
    110 }

     

  • 相关阅读:
    jQuery入门级part.2
    jQuery入门级part.1
    总结十二天
    延时器和定时器
    总结第十一天
    总结第十天
    总结第九天
    android特殊字符
    android 查看 当前activity
    京东运营 不错的帖子
  • 原文地址:https://www.cnblogs.com/cmyg/p/6816448.html
Copyright © 2011-2022 走看看