算法学习——2.连通性问题(二)

1.2.3 加权快速合并算法

快速合并算法仍然有他的局限性,因为查找根节点的次数并不是固定的,如果出现极端情况那么任然会出现计算较多的次数。假定输入对按照1-2, 2-3, 3-4, 4-5......的次序出现,然么N-1个数对形成的树为一条直线。其中N指向N-1,N-1指向N-2以此类推。要查找N最下面的节点,则需要N-1次遍历。那么查找M个对象的查找操作次数必定大于MN/2。

优化:使用另一组数组保存节点的计数,则会使效率获得巨大提升,称之为加权快速合并算法。

#include <stdio.h>

#define N (10)

int main()
{
     int i, p, q, j;
     int id[N];
     int sz[N];//表示前N的对象,所保存的节点

     //初始化对象集合中元素的初始值
     for (i = 0; i < N; i++)
     {
         id[i] = i;
         sz[i] = 1;
     }

     //循环读入整数对
     while (scanf("%d-%d", &p, &q) == 2)
     {
         //读取p根节点
         for (i = p; i != id[i]; i = id[i])
         {
         }

         for (j = q; j != id[j]; j = id[j]);

         if (i == j)
         {
             //p和q的根节点相同
             continue;
         }

         if (sz[i] < sz[j])
         {
             id[i] = j;
             sz[j] += sz[i];
         }
         else
         {
             id[j] = i;
             sz[i] += sz[j];
         }
         //因为p-q是新对,所以输出这个对
         printf("New pair: %d-%d\n", p, q);

     }

     return 0;
 }

加权合并中的sz[N]保存的连接节点的数量,通过使用这个新的数据结构完成原先的算法的优化。

1.2.4 压缩路径加权合并法 —— 等分路径压缩

#include <stdio.h>

#define N (10)

int main()
{
     int i, p, q, j;
     int id[N];
     int sz[N];//表示前N的对象,所保存的节点

     //初始化对象集合中元素的初始值
     for (i = 0; i < N; i++)
     {
         id[i] = i;
         sz[i] = 1;
     }

     //循环读入整数对
     while (scanf("%d-%d", &p, &q) == 2)
     {
         //读取p根节点
         for (i = p; i != id[i]; i = id[i])
         {
             id[i] = id[id[i]];
         }

         for (j = q; j != id[j]; j = id[j])
         {
             id[j] = id[id[j]];
         }

         if (i == j)
         {
             //p和q的根节点相同
             continue;
         }

         if (sz[i] < sz[j])
         {
             id[i] = j;
             sz[j] += sz[i];
         }
         else
         {
             id[j] = i;
             sz[i] += sz[j];
         }
         //因为p-q是新对,所以输出这个对
         printf("New pair: %d-%d\n", p, q);

     }

     return 0;
 }

再次优化,使得每棵树都是尽量扁平的。

看似是和快速查找法类似的数据变化过程,但是由于是找根节点的方式判断是否有链接,所以效率变高。

通俗理解:就是利用查找根节点这一相对简单的判断方式,但是通过扁平化的树分支来代替原先的较长的分支。提高执行效率。

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值