数据结构-5.3集合及运算

集合的表示

  • 集合运算:交、并、补、差,判定一个元素是否属于某一集合
  • 并查集:集合并、查某元素属于什么集合
  • 并查集问题中集合存储如何实现?
  1. 链式存储:树结构表示集合,树的每个结点代表一个集合元素            

     2.顺序存储:用数组表示

集合运算

  • 查找某个元素所在的集合(用根节点表示
#define MaxSize 100
typedef int ElementType;
typedef struct {
	ElementType Data;
	int Parent;
} SetType;

int Find( SetType S[], ElementType X){
	/* 在数组S中查找值为X的元素所属的集合*/
	/*MaxSize是全局变量,为S的最大长度*/
	int i;
	for (i = 0; i < MaxSize && S[i].data != X; ++i);
	if (i >= MaxSize) return -1;
	for ( ; S[i].Parent >= 0;i = S[i].Parent);
	return i;
} 
  • 集合的并运算
  1. 分别找到x1和x2两个元素所在的集合的根节点
  2. 判断是否同根:同根则不做改变;不同根则将其中一个根节点的父节点指针设置成另一个根节点的数组下标
void Union( SetType S[], ElementType X1, ElementType X2){
	int Root1, Root2;
	Root1 = find( S[], X1 );
	Root2 = find( S[], X2 );
	if( Root1 != Root2 ) S[Root2].Parent = Root1;
}

可以利用Parent的信息表达集合中元素的个数(负数绝对值)

随着集合的不断并入,可能会使树越来愈高,从而降低Find的效率,因此尽量将较小的集合并入较大的集合

int ImprovedUnion( SetType S[], ElementType X1, ElementType X2 ){
	int Root1, Root2;
	int max, min;
	Root1 = find( S[], X1 );
	Root2 = find( S[], X2 );
	if( Root1 != Root2 ){
		min = Root1 > Root2 ? Root2 : Root1;
		mmax = Root1 > Root2 ? Root1 : Root2;
		S[min].Parent = max;
	}
}

 

 

#define MAXN 1000                  /* 集合最大元素个数 */
typedef int ElementType;           /* 默认元素可以用非负整数表示 */
typedef int SetName;               /* 默认用根结点的下标作为集合名称 */
typedef ElementType SetType[MAXN]; /* 假设集合元素下标从0开始 */

void Union( SetType S, SetName Root1, SetName Root2 )
{ /* 这里默认Root1和Root2是不同集合的根结点 */
    /* 保证小集合并入大集合 */
    if ( S[Root2] < S[Root1] ) { /* 如果集合2比较大 */
        S[Root2] += S[Root1];     /* 集合1并入集合2  */
        S[Root1] = Root2;
    }
    else {                         /* 如果集合1比较大 */
        S[Root1] += S[Root2];     /* 集合2并入集合1  */
        S[Root2] = Root1;
    }
}

SetName Find( SetType S, ElementType X )
{ /* 默认集合元素全部初始化为-1 */
    if ( S[X] < 0 ) /* 找到集合的根 */
        return X;
    else
        return S[X] = Find( S, S[X] ); /* 路径压缩 */
}

 

目 录 一、课程设计目的 •••••••••••••••••••••••••••••••••••••••••••••••• 2 1.1、实现集合 •••••••••••••••••••••••••••••••••••••••••••••••• 2 二、课程设计内容 •••••••••••••••••••••••••••••••••••••••••••••••• 2 2.1、实现集合 •••••••••••••••••••••••••••••••••••••••••••••••• 2 三、数据结构分析 •••••••••••••••••••••••••••••••••••••••••••••••• 2 3.1、实现集合 •••••••••••••••••••••••••••••••••••••••••••••••• 2 3.1.1 集合的相等运算 •••••••••••••••••••••••••••••••••••••••• 2 3.1.2 集合的并运算 ••••••••••••••••••••••••••••••••••••••••• 3 3.1.3 集合的包含、差运算 •••••••••••••••••••••••••••••••••••• 3 四、算法分析 ••••••••••••••••••••••••••••••••••••••••••••••••••••• 3 4.1、实现集合 •••••••••••••••••••••••••••••••••••••••••••••••• 4 4.1.1 集合的相等运算 •••••••••••••••••••••••••••••••••••••••• 4 4.1.2 集合的并运算 ••••••••••••••••••••••••••••••••••••••••• 4 4.1.3 集合的包含、差运算 •••••••••••••••••••••••••••••••••••• 5 五、代码分析 ••••••••••••••••••••••••••••••••••••••••••••••••••••• 5 5.1、实现集合 •••••••••••••••••••••••••••••••••••••••••••••••• 5 5.1.1 集合的相等运算 •••••••••••••••••••••••••••••••••••••••• 5 5.1.2 集合的并运算 ••••••••••••••••••••••••••••••••••••••••• 6 5.1.3 集合的包含、差运算 •••••••••••••••••••••••••••••••••••• 7 六、问题分析 ••••••••••••••••••••••••••••••••••••••••••••••••••••• 9 6.1、实现集合 •••••••••••••••••••••••••••••••••••••••••••••••• 9 七、运行结果 ••••••••••••••••••••••••••••••••••••••••••••••••••••• 10 7.1、实现集合 •••••••••••••••••••••••••••••••••••••••••••••••• 10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值