• java算法事例:连通性


    java算法事例:连通性

    假设现在一个整数对序列,每个整数代表某种类型的对象,用p-q对表示“p连接到q”,又假设连接具有传递性,即p连接到q,q连接到r,则p连接到r。

    例一:解决连通性问题的快速查找算法

    Java代码 复制代码
    1. public class QuickF {   
    2.   
    3.     public static void main(String[] args) {   
    4.         int N = 10;   
    5.         int id [] = new int[N];   
    6.         for(int i = 0; i < N; i++){   
    7.             id[i] = i;   
    8.         }   
    9.         int [] [] a =  new int [][]{   
    10.                 {3,4},{4,9},{8,0},{2,3},{0,2},{5,6},   
    11.                 {2,9},{5,9},{7,3},{4,8},{5,6},{6,1}   
    12.         };   
    13.         System.out.println(Arrays.toString(id));   
    14.         for(int [] s : a){   
    15.             int p = s[0], q = s[1];   
    16.             int t = id[p];   
    17.             if(t == id[q]){   
    18.                 continue;   
    19.             }   
    20.             for(int i = 0; i < N; i++){   
    21.                 if(id[i] == t){   
    22.                     id[i] = id[q];   
    23.                     System.out.println(" " + p + " " + q);   
    24.                     System.out.println(Arrays.toString(id));   
    25.                 }   
    26.             }   
    27.         }   
    28.            
    29.     }   
    30. }  

    在用快速查找算法时,对序列{p,q}每一对进行处理后,id数组中的值为合并操作。把所有与id[p]值相同的元素值变为id[q]值。

    例二:快速合并(并不快速的查找)

    Java代码 复制代码
    1. public class QuickFU {   
    2.   
    3.     public static void main(String[] args) {   
    4.         int N = 10;   
    5.         int id [] = new int[N];   
    6.         for(int i = 0; i < N; i++){   
    7.             id[i] = i;   
    8.         }   
    9.         int [] [] a =  new int [][]{   
    10.                 {3,4},{4,9},{8,0},{2,3},{5,6},{2,9},   
    11.                 {5,9},{7,3},{4,8},{5,6},{0,2},{6,1},{5,8}   
    12.         };   
    13.         System.out.println(Arrays.toString(id));   
    14.         for(int [] s : a){   
    15.             int i, j, p = s[0], q = s[1];   
    16.              for(i = p; i != id[i]; i = id[i]);   
    17.              for(j = q; j != id[j]; j = id[j]);   
    18.              if(i == j){   
    19.                  continue;   
    20.              }   
    21.              id [i] = j;   
    22.              System.out.println(" " + p + " " + q);   
    23.              System.out.println(Arrays.toString(id));   
    24.         }   
    25.     }   
    26. }  

    在快速查找算法中,只需经过一个连接就可以找到节点;而在快速合并中中,可能需要多个节点才能找到。

    例三:快速合并的加权版本

    Java代码 复制代码
    1. public class QuickFW {   
    2.   
    3.     public static void main(String[] args) {   
    4.         int N = 10;   
    5.         int id [] = new int[N];   
    6.         int sz [] = new int[N];   
    7.         for(int i = 0; i < N; i++){   
    8.             id[i] = i;   
    9.             sz[i] = 1;   
    10.         }   
    11.         int [] [] a =  new int [][]{   
    12.                 {3,4},{4,9},{8,0},{2,3},{5,6},{2,9},   
    13.                 {5,9},{7,3},{4,8},{5,6},{0,2},{6,1}   
    14.         };   
    15.         System.out.println(Arrays.toString(id));   
    16.         for(int [] s : a){   
    17.             int i, j, p = s[0], q = s[1];   
    18.              for(i = p; i != id[i]; i = id[i]);   
    19.              for(j = q; j != id[j]; j = id[j]);   
    20.              if(i == j){   
    21.                  continue;   
    22.              }   
    23.              if(sz[i] < sz[j]){   
    24.                  id[i] = j;    
    25.                  sz[j] += sz[i];   
    26.              }else{   
    27.                  id[j] = i;   
    28.                  sz[i] += sz[j];   
    29.              }   
    30.              System.out.println(" " + p + " " + q);   
    31.              System.out.println(Arrays.toString(id));   
    32.              System.out.println(Arrays.toString(sz));   
    33.         }   
    34.     }   
    35. }  

    加权快速合并算法在典型情况下,可以在线性时间内解决实际问题。

    路径压缩,在合并操作中,经过每条路径就加一条连线,把一路上遇到的对应的每个顶点的id数组值都设为到树根上,逼近了快速查找算法的理想状态。

    例四:压缩方法:使在通向树根的路中的每条连线都指向路劲中的下一个节点,即折半路径压缩的加权快速合并

    Java代码 复制代码
    1. public class QuickFH {   
    2.   
    3.     public static void main(String[] args) {   
    4.         int N = 10;   
    5.         int id [] = new int[N];   
    6.         int sz [] = new int[N];   
    7.         for(int i = 0; i < N; i++){   
    8.             id[i] = i;   
    9.             sz[i] = 1;   
    10.         }   
    11.         int [] [] a =  new int [][]{   
    12.                 {3,4},{4,9},{8,0},{2,3},{5,6},{2,9},   
    13.                 {5,9},{7,3},{4,8},{5,6},{0,2},{6,1}   
    14.         };   
    15.         System.out.println(Arrays.toString(id));   
    16.         for(int [] s : a){   
    17.             int i, j, p = s[0], q = s[1];   
    18.              for(i = p; i != id[i]; i = id[i]){   
    19.                  id[i] = id[id[i]];   
    20.              }   
    21.              for(j = q; j != id[j]; j = id[j]){   
    22.                  id[j] = id[id[j]];   
    23.              }   
    24.              if(i == j){   
    25.                  continue;   
    26.              }   
    27.              if(sz[i] < sz[j]){   
    28.                  id[i] = j;    
    29.                  sz[j] += sz[i];   
    30.              }else{   
    31.                  id[j] = i;   
    32.                  sz[i] += sz[j];   
    33.              }   
    34.              System.out.println(" " + p + " " + q);   
    35.              System.out.println(Arrays.toString(id));   
    36.              System.out.println(Arrays.toString(sz));   
    37.         }   
    38.     }   
    39. }  

    得到的与例三一样的净结果,比全路径压缩算法更简单。

    通过一系列的算法:找到了解决实际问题的好算法,它比较容易实现,且运行实际保证在收集数据项所花费时间的常数因子范围内。在这些算法中需要仔细和复杂的分析,才能找到最优算法。

  • 相关阅读:
    bzoj1257 [CQOI2007]余数之和sum
    bzoj1053 [HAOI2007]反素数ant
    bzoj3680 吊打XXX
    CodeVS1344 线型网络
    bzoj1925 [Sdoi2010]地精部落
    2016年北大高代考研题解答
    巴塞尔问题(Basel problem)的多种解法
    积分计算题
    PDF添加水印的办法
    Matlab技巧1:在同一坐标系上绘制两个函数图像
  • 原文地址:https://www.cnblogs.com/wuyida/p/6301163.html
Copyright © 2020-2023  润新知