並集-查找算法


I.快速查找算法:
========================quick_find.c=================================
#include<stdio.h>
#define N 10
int main(){
 int id[N];
 int i, p, q, t, count, sum = 0;
 for(i = 0; i < N; i++) id[i] = i;
 while (scanf("%d %d", &p, &q) == 2){
  count = 0;
  if(id[p] == id[q]) continue;
  //下面的這個for循環很有意思,它具有記憶功能:記憶之前連通的數!
  for(t = id[p], i = 0; i < N; i++)
   if(id[i] == t){
     id[i] = id[q];  
    count++;
    sum ++;
   }
  printf("count = %d, sum = %d/n", count, sum);
  for(i = 0; i < N; i++) printf("%d ", id[i]);
  printf("/n");
 }
 
}

=====編譯運行=====
explore@ubuntu:~/Documents/datastruct/Algorithms in C/第一章  導論$ gcc quick_find.c
explore@ubuntu:~/Documents/datastruct/Algorithms in C/第一章  導論$ ./a.out
0 2
count = 1, sum = 1
2 1 2 3 4 5 6 7 8 9
1 4
count = 1, sum = 2
2 4 2 3 4 5 6 7 8 9
2 5
count = 2, sum = 4
5 4 5 3 4 5 6 7 8 9
3 6
count = 1, sum = 5
5 4 5 6 4 5 6 7 8 9
0 4
count = 3, sum = 8
4 4 4 6 4 4 6 7 8 9
6 0
count = 2, sum = 10
4 4 4 4 4 4 4 7 8 9
1 3

 

II.快速並集算法:
===================quick_union.c=======================================
#include<stdio.h>
#define N 10

/*
 *這個一個連通性問題的快速union的解決方案。
 */
int main(){
 int id[N];
 int i, j, p, q;
 int count_i, count_j, sum = 0;
 for(i = 0; i < N; i++) id[i] = i;
 while(scanf("%d %d", &p, &q) == 2){
  //下面是很有意思的兩個for循環!如果輸入的位置的值被改動過,此處的i可能出現多個值,例如,1 1 9 4 9 6 9 9 0 0 輸入 5 5,首先i=5發現5號位置被改動過->i=9發現9號位置也被改動->i=0發現0號位置也被改動,繼續給i賦值->i=1,好了發現1號位置沒有被改動,OK 最終i=1;

  //這個for循環的作用總結為:追蹤上一級的位置有沒有被改動!直到找到一個沒有被改動的位置的值附給變量。
  count_i = count_j = 0;
  for(i = p; i != id[i]; i = id[i]) {count_i++; sum++;}   
  for(j = q; j != id[j]; j = id[j]) {count_j++; sum++;}
  if(i == j) continue;
  id[i] = j;
  count_i++;
  sum++;
  printf("訪問數組id的次數:%d/n", count_i + count_j);
  printf("訪問數組id的總數:%d/n", sum);
  for(i = 0; i < N; i++) printf("%d ", id[i]);
  printf("/n/n"); 
 }
}

=======編譯運行===========
explore@ubuntu:~/Documents/datastruct/Algorithms in C/第一章  導論$ gcc quick_union.c
explore@ubuntu:~/Documents/datastruct/Algorithms in C/第一章  導論$ ./a.out
0 2
訪問數組id的次數:1
訪問數組id的總數:1
2 1 2 3 4 5 6 7 8 9

1 4
訪問數組id的次數:1
訪問數組id的總數:2
2 4 2 3 4 5 6 7 8 9

2 5
訪問數組id的次數:1
訪問數組id的總數:3
2 4 5 3 4 5 6 7 8 9

3 6
訪問數組id的次數:1
訪問數組id的總數:4
2 4 5 6 4 5 6 7 8 9

0 4
訪問數組id的次數:3
訪問數組id的總數:7
2 4 5 6 4 4 6 7 8 9

6 0
訪問數組id的次數:4
訪問數組id的總數:11
2 4 5 6 4 4 4 7 8 9

1 3

 

III.加權快速並集算法:
=========================weighted_quick_union.c=========================================
#include<stdio.h>
#define N 10

/*
 *這個一個連通性問題的快速加權union的解決方案。
 */
int main(){
 int id[N], sz[N];
 int i, j, p, q;
 int count_i, count_j, sum = 0;
 for(i = 0; i < N; i++){
   id[i] = i;
  sz[i] = 1;
 }
 while(scanf("%d %d", &p, &q) == 2){
  count_i = count_j  = 0;
  for(i = p; i != id[i]; i = id[i]){count_i++; sum++;}  
  for(j = q; j != id[j]; j = id[j]){count_j++; sum++;}
  if(i == j) continue;
  if(sz[i] < sz[j]){
   id[i] = j;
   count_i++;
   sum++;
   sz[j] += sz[i];
  } else {
   id[j] = i;
   count_j++;
   sum++;
   sz[i] += sz[j];
  }
  printf("訪問數組id的次數:%d/n", count_i+count_j);
  printf("訪問數組id的總次數:%d/n", sum);
  for(i = 0; i < N; i++) printf("%d ", id[i]);
  printf("/n/n"); 
 }
}
=========編譯運行============
explore@ubuntu:~/Documents/datastruct/Algorithms in C/第一章  導論$ gcc weighted_quick_union.c
explore@ubuntu:~/Documents/datastruct/Algorithms in C/第一章  導論$ ./a.out
0 2
訪問數組id的次數:1
訪問數組id的總次數:1
0 1 0 3 4 5 6 7 8 9

1 4
訪問數組id的次數:1
訪問數組id的總次數:2
0 1 0 3 1 5 6 7 8 9

2 5
訪問數組id的次數:2
訪問數組id的總次數:4
0 1 0 3 1 0 6 7 8 9

3 6
訪問數組id的次數:1
訪問數組id的總次數:5
0 1 0 3 1 0 3 7 8 9

0 4
訪問數組id的次數:2
訪問數組id的總次數:7
0 0 0 3 1 0 3 7 8 9

6 0
訪問數組id的次數:2
訪問數組id的總次數:9
0 0 0 0 1 0 3 7 8 9

1 3


IV.分路徑壓縮加權快速並集算法:
====================weighted_quick_union_pc_hal.c================================
#include<stdio.h>
#define N 10

/*
 *這個一個連通性問題的分路徑壓縮快速加權union的解決方案。
 */
int main(){
 int id[N], sz[N];
 int i, j, p, q;
 int count_i, count_j, sum = 0;
 for(i = 0; i < N; i++){
   id[i] = i;
  sz[i] = 1;
 }
 while(scanf("%d %d", &p, &q) == 2){
  count_i = count_j  = 0;
  for(i = p; i != id[i]; i = id[i]){
   id[i] = id[id[i]];
   count_i += 4;
   sum += 4;
  }  
  for(j = q; j != id[j]; j = id[j]){
   id[j] = id[id[j]];
   count_j += 4;
   sum += 4;
  }
  if(i == j) continue;
  if(sz[i] < sz[j]){
   id[i] = j;
   count_i++;
   sum++;
   sz[j] += sz[i];
  } else {
   id[j] = i;
   count_j++;
   sum++;
   sz[i] += sz[j];
  }
  printf("訪問數組id的次數:%d/n", count_i+count_j);
  printf("訪問數組id的總次數:%d/n", sum);
  for(i = 0; i < N; i++) printf("%d ", id[i]);
  printf("/n/n"); 
 }
}

==============編譯運行=====================
explore@ubuntu:~/Documents/datastruct/Algorithms in C/第一章  導論$ gcc weighted_quick_union_pc_hal.c
explore@ubuntu:~/Documents/datastruct/Algorithms in C/第一章  導論$ ./a.out
0 2
訪問數組id的次數:1
訪問數組id的總次數:1
0 1 0 3 4 5 6 7 8 9

1 4
訪問數組id的次數:1
訪問數組id的總次數:2
0 1 0 3 1 5 6 7 8 9

2 5
訪問數組id的次數:5
訪問數組id的總次數:7
0 1 0 3 1 0 6 7 8 9

3 6
訪問數組id的次數:1
訪問數組id的總次數:8
0 1 0 3 1 0 3 7 8 9

0 4
訪問數組id的次數:5
訪問數組id的總次數:13
0 0 0 3 1 0 3 7 8 9

6 0
訪問數組id的次數:5
訪問數組id的總次數:18
0 0 0 0 1 0 3 7 8 9

1 3

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com