学习目标:
·掌握并查集的逻辑结构和物理结构
·掌握并查集的并、查操作的代码描述
·掌握并查集的并操作的优化
·掌握并查集的查操作的优化
学习内容:
- 搭建 Java 开发环境
- 掌握 Java 基本语法
- 掌握条件语句
- 掌握循环语句
- 并操作优化后为什么find操作时间复杂度为O(log n)?∵这种优化方式相当于去朝着完全二叉树的方向去并集合所代表的子树,完全二叉树的树高为⌊log n⌋+ 1 或「log (n+1 )] (注释:log n ⇔以2为底n的对数)
学习时间:
- 3h
学习产出:
//
// 并查集.cpp
// 408_ADT_二叉树
//Created by 郭宸羽 on 13/10/2022.
//
#include <stdlib.h>
#include <stdio.h>
//#include <math.h>
//#define MAX_NUMBER 20
//fail reason:make the set's element struct more complex, don't understand(set element parallel arry's index)
//typedef struct union_find_Set
//{
// int data;
// int paraent;
//}union_find_Set;
//
//void InitialSet(int num_in_set,union_find_Set set[])
//{
// for(int i = 0; i < num_in_set; i++)
// {
// set[i].paraent = -1;
// }
//}
//
//void AssigElement(union_find_Set set[])
//{
// ❌数组元素就是父结点,并查集本质是把集合元素通过arry'sindex⇔线性结构⇔树形结构组织关系(set element parallel arry's index)
// int i = 0;
// int count_node = 0;
// scanf("%c",&element);
// while(element != ' ')
// {
// set[i].data = element;
// ++i;
// ++count_node;
// }
// set[0].data = -count_node;
//}
//
//bool find(char element,union_find_Set set)
//{
// while(set.data)
//}
//
//int main()
//{
// union_find_Set set[MAX_NUMBER];
// InitialSet(10, set);
// AssigElement(set);
//
//}
//edition 2
#define SIZE 15
void InitialUFSet(int* p_union_find_sets)
{
for(int i = 0;i < SIZE; i++){
*(p_union_find_sets + i) = -1;
}
}
bool Find(int union_find_sets[],int element_index)
{
while(union_find_sets[element_index] >= 0)
{
element_index = union_find_sets[element_index];
}
return element_index;
}
//1.主要目的是学会并的思想
void Union(int all_sets[],int set1_root,int set2_root)//int set_root is arry's index
{
if(set2_root == set1_root){
printf(" the are same set\n");
return;
}
else{
all_sets[set1_root] = all_sets[set2_root];
}
}
// 1.1if get the element index is not the set's index and you want to union these two element's set the you should:Union( all_sets,Find(union_find_sets[],element_index_1),Find(union_find_sets[],element_index_2) ) 分而制之思想的体现。
//2.通过对union操作的优化来避免union后的集合find操作的复杂
//2.1优化思路:1st 用根结点的绝对值表示树中结点的数目 2st 通过比较树中结点数目的大小来让小树连到大树的
//2.2可以通过union操作来把离散的元素构建成集合
//2.3代码:
void UnionSmallToBig(int all_sets[],int set1_root,int set2_root)
{
if(abs(all_sets[set1_root]) > abs(all_sets[set2_root])){
all_sets[set1_root] += all_sets[set2_root]; //⚠️先累加结点总数
set1_root = all_sets[set2_root];//a += 20; ⇔ a = a + 20
}
else{
all_sets[set2_root] += all_sets[set1_root];//⚠️先累加结点总数
set2_root = all_sets[set1_root];
}
}
//2.4优化原因:非优化构造法中当没有进行判断时有可能会发生大树并到小树中(大树的根结点连接小树)这样会使树的高度+1,
//2.5优化性质:进行优化了的判断构造法构造的树,就可以在判断的情况下确保每次执行小树并到大树,这样树高不超过⌊log n⌋ + 1,同时确保了find操作的时间复杂度在O(log n)数量级上。
//2.6 综2.4&2.5 所述,union优化以后union操作的时间复杂度不发生变化依旧是O(1) find操作的时间复杂度从O(n)变为O(log n)
int main()
{
int union_find_sets[SIZE];
InitialUFSet(union_find_sets);
}
总结 re:王道并查集