不相交集ADT--链表实现
每一个集合用用一个链表来表示。链表的第一个对象作为它所在集合的代表。链表中每个对象都包含一个集合成员,一个指向下一个对象的指针,以及指向代表的指针。每个链表含head和tail指针,head指向链表的代表,tail指向链表中最后的对象。
如下图所示:
Union的简单实现:将x所在的链表拼接到y所在链表的表尾。对于原先x所在链表中的每一个对象都要更新其指向代表的指针。
如下图所示:
根据以上思想,代码如下:
#include<iostream> using namespace std; #define NumSets 8 typedef struct Node *Position;
typedef struct Node *Head;
typedef Head DisjSet[NumSets + 1]; //对于头节点,head_node指向第一个元素,tail指向最后一个元素,Key为该集合的大小
//对于普通节点,head_node指向第一个元素,tail指向后面的一个元素,相当于Next,Key为关键字
struct Node
{
Position head_node;
Position tail;
int Key;
}; Head Make_One_Node (int x)
{
Head Head_one = (Head)malloc(sizeof(Node)); //先申请一个头结点
Head_one->Key = 1; //个数为1 Position p = (Position)malloc(sizeof(Node)); //这个节点才是存储数据的节点 p->Key = x;
p->head_node = p; //普通节点的hand_node域指向第一个元素,此时就是它本身
p->tail = NULL; Head_one->head_node = p; //头节点的hand_node域指向第一个元素
Head_one->tail = p; //头节点的tail域指向最后一个元素 return Head_one;
}
void Set_Union (Head head1, Head head2)
{
Head tempHead;
if (head1->Key < head2->Key )
{
tempHead = head1;
head1 = head2;
head2 = tempHead;
} //把短的接在长的后面 //下面两句话的位置不能交换,否则会陷入死循环
head1->tail->tail = head2->head_node; //head1最后一个元素的tail域指向head2的第一个元素
head1->tail = head2->tail ; //head1的tail域指向head2的最后一个元素,也就是head2->tail Position p = head2->head_node ;
while(p)
{
p->head_node = head1->head_node ;//head2的所有元素都指向head1的第一个元素
p = p->tail;
}
head1->Key += head2->Key ; //释放head2的所有元素
head2->Key = 0;
head2->head_node = NULL;
head2->tail = NULL; } Head Set_Find (DisjSet S,int x) //返回该节点的头结点
{
for (int i = 1; i <= NumSets; ++i)
{
Position p = S[i]->head_node ;
while(p)
{
if(x == p->Key )
return p->head_node;
else
p = p->tail;
} }
} void printf_list(DisjSet S)
{
for (int i = 1; i <= NumSets; ++i)
{
if(S[i]->Key == 0)
{
cout << "第 "<< i << " 个集合没有元素。" <<endl;
}
else
{
cout << "第 "<< i << " 个集合一个共有 " << S[i]->Key << " 个元素,分别是:";
Position p = S[i]->head_node ;
while(p)
{
cout << p->Key << "\t";
p = p->tail;
}
cout << endl;
} } } int main ()
{
DisjSet S;
for (int i = 1; i <= NumSets; ++i)
{
S[i] = Make_One_Node (i);
}
Set_Union (S[1], S[2]);
Set_Union (S[3], S[4]);
Set_Union (S[3], S[1]);
printf_list(S); cout << Set_Find (S,5)->Key << endl; return 0;
}
看着比数组实现要复杂一点啊。
夜深了,,,
今天5月20号啊,520啊,还是周末啊,还在写代码,代码才是真爱。
不相交集ADT--链表实现的更多相关文章
- 不相交集ADT 你是和谁是一类人?
//不相交集ADT (抽象数据类型) //一般用于集合运算 //用树,这种结构组成,有多个树(=森林) //属于同一颗数的元素,表示处于同一个集合中 //主要支持2个操作. //1. Find操作,找 ...
- 栈ADT的链表实现
/* 栈ADT链表实现的类型声明 */ struct Node; typedef struct Ndoe *PtrToNode; typedef PtrToNode Stack; struct Nod ...
- 【WIP_S3】链表
创建: 2017/12/26 完成: 2018/01/14 [TODO] S4, S5, S14来处理动态数组 CAF8A81B790F [github 地址]传送门 链表的定义 ...
- Android开发project师,前行路上的14项技能
导读: 你是否曾渴望回到宋朝? 或者什么朝,反正就是男耕女织的古代. 哦,那时的首都在汴梁(开封),房价想必没有如今这么高,工作?无非就是给你把锄头,去,种地去.夕阳西下了,麦子垛后,你和翠姑搂抱在一 ...
- 数据结构与算法分析:C语言描述(原书第2版 简体中文版!!!) PDF+源代码+习题答案
转自:http://www.linuxidc.com/Linux/2014-04/99735.htm 数据结构与算法分析:C语言描述(原书第2版中文版!!!) PDF+源代码+习题答案 数据结构与算法 ...
- 最小生成树——Kruskal(克鲁斯卡尔)算法
[0]README 0.1) 本文总结于 数据结构与算法分析, 源代码均为原创, 旨在 理解 Kruskal(克鲁斯卡尔)算法 的idea 并用 源代码加以实现: 0.2)最小生成树的基础知识,参见 ...
- 不相交集(The Disjoint Set ADT)
0)引论 不相交集是解决等价问题的一种有效的数据结构,之所以称之为有效是因为,这个数据结构简单(几行代码,一个简单数组就可以搞定),快速(每个操作基本上可以在常数平均时间内搞定). 首先我们要明白什么 ...
- 【ADT】链表的基本C语言实现
什么是抽象数据类型?首先,这一概念是软件开发人员在力求编写的代码健壮.易维护且可以复用的过程中产生的.英文是AbstractData Type.有人将其比作"抽象"的墙壁,&quo ...
- 单链表ADT
本博客第一篇学术性博客,所以还是写点什么东西: 首先这篇博客以及以后的博客中的代码尽量百分之90是自己写过的: 可能有部分图片和代码是我认为别人更好的故摘抄下来, 本人三观正确,所以一定会表明来源: ...
- 分离链表法散列ADT
分离链表法解决冲突的散列表ADT实现 数据结构定义如下: struct ListNode; typedef struct ListNode *Position; struct HashTbl; typ ...
随机推荐
- 【Python】极简单的方式序列化sqlalchemy结果集为JSON
继承 json.JSONEncoder 实现一个针对sqlalchemy返回类型的处理方式. sqlalchemy的返回类型有大都有两种,一种是Model对象,一种是Query集合(只查询部分字段). ...
- 【插件】LinqToExcel常用对象
1.ExcelQueryFactory对象(1)获取工作表名集合IEnumerable<string> GetWorksheetNames() //获取工作薄中的工作表名foreach ( ...
- 解析php addslashes()与addclashes()函数的区别和比较
一. addslashes() 函数 addslashes(string) 函数在指定的预定义字符前添加反斜杠.这些预定义字符是:•单引号 (')•双引号 (")•反斜杠 (\)•NULL ...
- BZOJ5071 小A的数字
设f[i]为选择i对i-1和i+1所带来的贡献.则有f[i-1]+f[i+1]+a[i]-2f[i]=b[i],特殊地,f[2]+a[1]=b[1],f[n-1]+a[n]-2f[n]=b[n].可以 ...
- 洛谷 P3376 【模板】网络最大流
题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...
- TortoiseSVN的基本使用方法
TotoiseSVN的基本使用方法 来源 https://blog.csdn.net/hecongzhen/article/details/37879801 在 项目管理实践教程一.工欲善其事,必先利 ...
- 【刷题】BZOJ 1180 [CROATIAN2009]OTOCI
Description 给出n个结点以及每个点初始时对应的权值wi.起始时点与点之间没有连边.有3类操作: 1.bridge A B:询问结点A与结点B是否连通. 如果是则输出"no&quo ...
- c++字符串排序
在主函数中输入10个等长的字符串,用另一函数对它们排序.然后在主函数输出这10个已排好序的字符串. 用两种方法完成. 方法一:用二维数组做函数参数: 方法二:用指向一维数组的指针做函数参数. 方法一: ...
- Eclipse开发Java代码,如何添加智能提示
选择:Window->Preferences->JAVA->Editor->Context Assist 在Auto activation triggers for Java处 ...
- BZOJ3724 [HNOI2012]集合选数 【状压dp】
题目链接 BZOJ3724 题解 构造矩阵的思路真的没想到 选\(x\)就不能选\(2x\)和\(3x\),会发现实际可以转化为矩阵相邻两项 \[\begin{matrix}1 & 3 &am ...