快排与并查集

快排与并查集

1.     快排

快排最重要的就是理解为甚吗会这样用:cmp函数中的返回值是表示将传入函数cmp的实参按照返回表达式的形式排列,是一种间接排列,以return的比较对象作为标准进行的排列。

所以对于结构体的排列,先判断比较条件是不是相等,相等的话换另一种排列的评判标准,否则按照第一种的方式进行排列。

sort函数的用法

头文件加上:

#include <algorithm>

using namespace std;

然后

运用时:sort(a,a+n,cmp);

这里第一个参数是排列区间的首地址,第二个参数是排列区间的尾地址,第三个参数是一个自定义函数,可以写也可以不写,不写时sort函数默认排列是以升序的方式进行排列。如果想要间数组元素进行降序排列,就要自己自己写一个比较函数cmp

bool cmp(int a,int b)

{

return a<b;//升序排列

//return b>a;//降序排列

}

   这个函数的返回值是bool型,只返回1或0.

   假设自己定义了一个结构体node

struct node

{

    int a;

    int b;

    double c;

}arr[100];

   有一个node类型的数组node arr[100],想对它进行排序:先按a值升序排列,如果a值相同,再按b值降序排列,如果b还相同,就按c降序排列。就可以写这样一个比较函数:

以下是代码片段:

boolcmp(node x,node y)//一元素

{

     return x.a<y.a;

}

intcmp(node x,node y) //二元素

        if(x.a != y.a) //升序排列

             return x.a < y.a;  //优先排的部分  

        return x.b < y.b;  //被动排的部分

}

bool cmp(nodex,node y)//三元素

{

     if(x.a!=y.a) return x.a>y.a;

     if(x.b!=y.b) return x.b>y.b;

     if(x.c!=y.c) return x.c>y.c;

}

排序时写sort(arr,arr+100,cmp);

2.     并查集

并查集分为两部分,一部分为并,一部分为查。

并:

首先,将数组的每个下标i的根节点a【i】为它本身。

每次输入两个相关连的元素,判断他们的最终根节点是不是一样,如果一样说明他们在同一棵树,如果不同就让一个树的根变成另一棵树的枝干,这样就可以把两个相关联的元素有规律的放在同一颗树上,不会出现环形的情况。

那么如何让去找到某个元素的最终根节点呢?

查:

每一次输入一个数据,如果它本身是最终根节点,则返回最终根结点,否则,返回它的根的最终根节点。

Int find(int a)

{

        Returnset[a]==a?a:find(set[a]);

}

可是由于有些树比较长,呈现链状,每次查找比较麻烦,所以运用压缩路径的方法。

Int find(int  a)

{

        Returnset[a]==a?set[a]=a:find(set[a]);

}

这样每次查找的时候都会让这个元素的跟等于它根的最终根节点。

一个作为参考的代码:

Hdu  1232

#include<stdio.h>

int set[1010]={0};

int find(int a)

{

    returnset[a]==a?a:set[a]=find(set[a]);

}

int main()

{

    intn,m,i,s,a,b,x,y;

   while(scanf("%d",&n),n)

    {

        scanf("%d",&m);

       for(i=0;i<=n;i++)

       set[i]=i;

       while(m--)

        {

           scanf("%d%d",&a,&b);

           x=find(a);

           y=find(b);

           if(x!=y)

           set[x]=y;

        }

        s=0;

       for(i=1;i<=n;i++)

        {

          if(set[i]==i)

           s++;

        }

       printf("%d\n",s-1);

    }

    return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值