• 队列与广度优先搜索概述+一本通1362


    在C++中有很多数据结构,包括栈(stack)、队列(queue)、容器(vector)、数对(pair)等。这篇博客的重点是队列。

    1.队列的定义:一种线性数据结构,可以插入和弹出数据。每个队列除了有数据,还有两个指针,“头指针”指向队列的第一个元素(以下简称队首),“尾指针”指向队列的最后一个元素(以下简称队尾)。插入数据时在队列的队尾后插入,并使尾指针后移一位。弹出时是弹出队首的元素,并使头指针后移一位。也就是说,先插入的元素会先被弹出,这一特性叫做“先进先出”(FIFO,“First in first out”)。

    以下是一个队列的例子,其中Enqueue函数是插入操作,Dequeue函数是弹出操作。

    (来自百度)

    2.队列的基本操作:

    (1)头文件:<queue>

    (2)声明一个队列:queue<typename T>  q;  (typename是指队列中存放的数据类型,最常见的如int、char)

    (3)插入操作:void push(T a);(这里是指a的类型由上述typename决定,下同)

    (4)弹出操作:void pop(); 

    (5)获得队首元素:T front();

    (6)获得队尾元素:T back();

    (7)获得队列里的元素数量:size_type size();

    (8)检验队列是否为空:bool empty();

    3.广度优先搜索(bfs)是指从当前节点访问所有与它相邻的节点(称为第一层),全部访问完以后,再访问与第一层相连的所有节点(第二层)......以此类推,直到所有节点都搜索完为止。

    上面的树,广度优先搜索会得到以下的搜索次序:1 2 3 4 5 6 7 8 。而深度优先搜索则是:1 2 6 7 3 4 8 5。

    队列是一端插入,另一端弹出的线性数据结构,这给广度优先搜索的实现带来了极大便利。先把根节点插入队列,再插入与它相连的节点,依次访问,访问节点的同时把与它相连的节点插入队列,访问后弹出该节点。若队列为空,则证明搜索结束。

    4.例题(ybt1362:家庭问题(family))

    【题目描述】有n个人,编号为1,2,……n,另外还知道存在K个关系。一个关系的表达为二元组(α,β)形式,表示α,β为同一家庭的成员。当n,k和k个关系给出之后,求出其中共有多少个家庭、最大的家庭中有多少人?例如:n=6,k=3,三个关系为(1,2),(1,3),(4,5)此时,6个人组成三个家庭,即:{1,2,3}为一个家庭,{4,5}为一个家庭,{6}单独为一个家庭,第一个家庭的人数为最多。

    【输入】第一行为n,k二个整数(1≤n≤100)(用空格分隔);接下来的k行,每行二个整数(用空格分隔)表示关系。

    【输出】二个整数(分别表示家庭个数和最大家庭人数)。

    【输入样例】

    6 3

    1 2

    1 3

    4 5

    【输出样例】

    3 3

    代码如下:(以下代码用到了pair,它表示一个数组,包含于iostream里,第一个数用first表示,第二个用second表示)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<queue>
     5 using namespace std;
     6 int n,k;
     7 pair<int,int> rela[1000];//记录一对关系 
     8 int inWhichFamily[105];//记录每个人在编号为几的家庭中,0表示这个人独自成为一个家庭 
     9 queue<int> family[105];//模拟家庭 
    10 
    11 int main()
    12 {
    13     cin>>n>>k;
    14     int p=1;//目前的家庭编号 
    15     for(int i=1;i<=k;i++)
    16     {
    17         cin>>rela[i].first>>rela[i].second;
    18         if((!inWhichFamily[rela[i].first])&&(!inWhichFamily[rela[i].second])&&rela[i].first!=rela[i].second)//这对关系不属于任何一个家庭,是一个新家庭。(注意排除关系的两个人相同的情况) 
    19         {
    20             family[p].push(rela[i].first);//新家庭的两个人 
    21             family[p].push(rela[i].second);
    22             inWhichFamily[rela[i].first]=p;//这两个人属于第p个家庭 
    23             inWhichFamily[rela[i].second]=p;
    24             p++;//家庭数量增加 
    25         }
    26         else if((!inWhichFamily[rela[i].first])&&(inWhichFamily[rela[i].second]))//有个人已经有所属家庭 
    27         {
    28             family[inWhichFamily[rela[i].second]/*那个人所属家庭的编号*/].push(rela[i].first);//将另一个人加入这个家庭中 
    29             inWhichFamily[rela[i].first]=inWhichFamily[rela[i].second];//这个人获得了家庭编号 
    30         }
    31         else if((inWhichFamily[rela[i].first])&&(!inWhichFamily[rela[i].second]))//与上面的同理 
    32         {
    33             family[inWhichFamily[rela[i].first]].push(rela[i].second);
    34             inWhichFamily[rela[i].second]=inWhichFamily[rela[i].first];        
    35         }
    36     }
    37     int _max=1;
    38     for(int i=1;i<=n;i++)
    39     {
    40     //    cout<<family[i].size();
    41         if(!inWhichFamily[i]) p++;//再考虑独自成家的人 
    42         if(family[i].size() > (unsigned)_max)//得到最大的家庭大小 
    43         {
    44             _max=family[i].size();
    45         } 
    46     }
    47     cout<<p-1<<" "<<_max<<endl;//前面应该是多加了一个1 
    48 }

    好像和广度优先搜索没什么关系......算了不管了,开溜

  • 相关阅读:
    Win10以管理员身份运行Loadrunner11时候提示“管理员已阻止你运行此应用”
    logrotate日志切割
    Scala的型变
    Caused by: com.esotericsoftware.kryo.KryoException: Buffer overflow. Available: 0, required: 134217728
    ERROR BatchJobMain: Task not serializable
    Spark创建HiveContext报错tez的问题
    Spark初始换HiveContext空指针异常
    windows10专业版 操作系统无法监听远程端口
    windows环境如何上传项目到gitee
    canal-kakfa-flink实现mysql数据的实时同步(一)
  • 原文地址:https://www.cnblogs.com/jiangyuechen/p/12547468.html
Copyright © 2020-2023  润新知