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. }  
public class QuickF {

	public static void main(String[] args) {
		int N = 10;
		int id [] = new int[N];
		for(int i = 0; i < N; i++){
			id[i] = i;
		}
		int [] [] a =  new int [][]{
				{3,4},{4,9},{8,0},{2,3},{0,2},{5,6},
				{2,9},{5,9},{7,3},{4,8},{5,6},{6,1}
		};
		System.out.println(Arrays.toString(id));
		for(int [] s : a){
			int p = s[0], q = s[1];
			int t = id[p];
			if(t == id[q]){
				continue;
			}
			for(int i = 0; i < N; i++){
				if(id[i] == t){
					id[i] = id[q];
					System.out.println(" " + p + " " + q);
					System.out.println(Arrays.toString(id));
				}
			}
		}
		
	}
}

在用快速查找算法时,对序列{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. }  
public class QuickFU {

	public static void main(String[] args) {
		int N = 10;
		int id [] = new int[N];
		for(int i = 0; i < N; i++){
			id[i] = i;
		}
		int [] [] a =  new int [][]{
				{3,4},{4,9},{8,0},{2,3},{5,6},{2,9},
				{5,9},{7,3},{4,8},{5,6},{0,2},{6,1},{5,8}
		};
		System.out.println(Arrays.toString(id));
		for(int [] s : a){
			int i, j, p = s[0], q = s[1];
			 for(i = p; i != id[i]; i = id[i]);
			 for(j = q; j != id[j]; j = id[j]);
			 if(i == j){
				 continue;
			 }
			 id [i] = j;
			 System.out.println(" " + p + " " + q);
			 System.out.println(Arrays.toString(id));
		}
	}
}

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

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

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. }  
public class QuickFW {

	public static void main(String[] args) {
		int N = 10;
		int id [] = new int[N];
		int sz [] = new int[N];
		for(int i = 0; i < N; i++){
			id[i] = i;
			sz[i] = 1;
		}
		int [] [] a =  new int [][]{
				{3,4},{4,9},{8,0},{2,3},{5,6},{2,9},
				{5,9},{7,3},{4,8},{5,6},{0,2},{6,1}
		};
		System.out.println(Arrays.toString(id));
		for(int [] s : a){
			int i, j, p = s[0], q = s[1];
			 for(i = p; i != id[i]; i = id[i]);
			 for(j = q; j != id[j]; j = id[j]);
			 if(i == j){
				 continue;
			 }
			 if(sz[i] < sz[j]){
				 id[i] = j; 
				 sz[j] += sz[i];
			 }else{
				 id[j] = i;
				 sz[i] += sz[j];
			 }
			 System.out.println(" " + p + " " + q);
			 System.out.println(Arrays.toString(id));
			 System.out.println(Arrays.toString(sz));
		}
	}
}

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

路径压缩,在合并操作中,经过每条路径就加一条连线,把一路上遇到的对应的每个顶点的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. }  
public class QuickFH {

	public static void main(String[] args) {
		int N = 10;
		int id [] = new int[N];
		int sz [] = new int[N];
		for(int i = 0; i < N; i++){
			id[i] = i;
			sz[i] = 1;
		}
		int [] [] a =  new int [][]{
				{3,4},{4,9},{8,0},{2,3},{5,6},{2,9},
				{5,9},{7,3},{4,8},{5,6},{0,2},{6,1}
		};
		System.out.println(Arrays.toString(id));
		for(int [] s : a){
			int i, j, p = s[0], q = s[1];
			 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){
				 continue;
			 }
			 if(sz[i] < sz[j]){
				 id[i] = j; 
				 sz[j] += sz[i];
			 }else{
				 id[j] = i;
				 sz[i] += sz[j];
			 }
			 System.out.println(" " + p + " " + q);
			 System.out.println(Arrays.toString(id));
			 System.out.println(Arrays.toString(sz));
		}
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值