数据结构 集合_集合(数学)抽象数据类型的C语言实现
链表是实现集合的一种理想的方式。将List以typedef的方式重命名为Set。这样做能保留链表简洁的特性,还能使集合具有了一些多态的特性。
使用这种方法的最大好处就是可以使用list_next来遍历一个集合,使用list_rem_next来移除一个成员,而不用根据成员所存储的数据来标识它。
我们先来查看一下集合抽象数据类型头文件的内容:
示例1:集合(抽象数据类型)头文件
#ifndef SET_H
#define SET_H #include <stdlib.h>
#include "list.h"
/*将集合定义成List结构*/
typedef List Set;
/*集合的初始化*/
void set_init(Set *set,int (match*)(const void *key1,const void *key2),void(*destroy)(void *data));
/*集合销毁,定义成链表销毁函数*/
#define set_destroy List_destroy
/*向集合中插入元素*/
int set_insert(Set *set, const void *data);
/*从集合中移除元素*/
int set_remove(Set *set, void **data);
/*求集合的并集*/
int set_union(Set *setu, const Set *set1, const Set *set2);
/*求集合的交集*/
int set_intersection(Set *seti, const Set *set1,const Set *set2);
/*求集合的差集*/
int set_difference(Set *setd, const Set *set1,const Set *set2);
/*判断成员是否属于集合*/
int set_is_member(const Set *set, const void *data);
/*判断子集*/
int set_is_subset(const Set *set1, const Set *set2);
/*判断集合是否相等*/
int set_is_equal(const Set *set1, const Set *set2);
/*集合中元素的个数*/
#define set_size(set) ((set)->size) #endif
下面是各种操作的具体实现:
示例2:集合抽象数据类型的实现
#include <stdlib.h>
#include <string.h>
#include "list.h"
#include "set.h" /*set_init 初始化一个集合*/
void set_init(Set *set,int(*match)(const void *key1,const void *key2), void(*destroy)(void *data))
{
/*调用list_init*/
list_init(set,destroy);
/*单独初始化match成员*/
set->match = match; return;
} /*set_insert 向集合中插入一个成员*/
int set_insert(Set *set,const void *data)
{
/*不能向集合中插入已有成员*/
if(set_is_member(set,data))
return -1;
/*调用list_ins_next插入元素至尾端*/
return list_ins_next(set,list_tail(set),data);
} /*set_remove 移除元素*/
int set_remove(Set *set,void **data)
{
ListElmt *member, *prev;
/*查找要移除的成员*/
prev=NULL;
/*遍历链表*/
for(member=list_head(set); member != NULL; member = list_next(member))
{
if(set->match(*data,(list_data(member)))
break;
prev=member; /*prev刚好指向匹配成功的成员的前一个成员*/
} /*没有找到成员则返回*/
if(member==NULL)
return -1;
/*移除成员*/
return list_rem_next(set,prev,data);
} /*set_union 求解两个集合的并集*/
int set_union(Set *setu,const Set *set1,const Set *set2)
{
ListElmt *member;
void *data; /*初始化一个并集集合*/
set_init(setu,set1->match,NULL); /*将集合1的内容插入并集*/
for(member=list_head(set1);member!=NULL;member=list_next(member))
{
data=list_data(member);
if(list_ins_next(setu,list_tail(setu),data)!=0)
{
set_destroy(setu);
return -1;
}
} /*插入集合2的成员*/
for(member=list_head(set2);member!=NULL;member=list_next(member))
{
if(set_is_member(set1,list_data(member)))
{
continue;
}
else
{
data=list_data(member);
if(list_ins_next(setu,list_tail(setu),data))!=0)
{
set_destroy(setu);
return -1;
}
}
}
return 0;
} /*set_intersection 求解两个集合的交集*/
int set_intersection(Set *seti,const Set *set1,const Set *set2)
{
ListElmt *member;
void *data; /*初始化交集集合*/
set_init(seti,set1->match,NULL); /*同时在两个集合中出现的元素将被插入交集集合中*/
for(member=list_head(set1);member!=NULL;list_next(member))
{
if(set_is_member(set2,list_data(member))
{
data=list_data(member);
if(list_ins_next(seti,list_tail(seti),data))!=0)
{
set_destroy(seti);
return -1;
{
}
}
return 0;
}
/*set_difference 求解两个集合的差集*/
int set_intersection(Set *setd,const Set *set1,const Set *set2)
{
ListElmt *member;
void *data; /*初始化差集集合*/
set_init(setd,set1->match,NULL); /*不同时在两个集合中出现的元素将被插入差集集合中*/
for(member=list_head(set1);member!=NULL;list_next(member))
{
if( ! set_is_member(set2,list_data(member))
{
data=list_data(member);
if(list_ins_next(setd,list_tail(setd),data))!=0)
{
set_destroy(setd);
return -1;
{
}
}
return 0;
} /*set_is_member 判断由data指定的成员是否在由set指定的集合中*/
int set_is_member(const Set *set,void *data)
{
ListElmt *member; for(member=list_head(set);member!=NULL;list_next(member))
{
if(set->match(data,list_data(member))
return 1;
}
return 0;
} /*set_is_subset 判断集合set1是否是集合set2的子集*/
int set_is_subset(const Set *set1,const Set *set2)
{
ListElmt *member; /*首先排除集合1成员数量大于集合2成员数量的情况*/
if(set_size(set1)>set_size(set2))
return 0; /*如果set1的成员不都在set2中,则判断不成立,除此成立*/
for(member=list_head(set1);member!=NULL;list_next(member))
{
if( !set_is_member(set2,list_data(member)))
{
return 0;
}
}
return 1;
} /*set_is_equal 判断两个集合是否相等*/
int set_is_equal(const Set *set1,const Set *set2)
{
/*首先排除两个集合成员数量不相等的情况*/
if(set_size(set1) != set_size(set2))
return 0; /*两个集合成员数量相等,且一个集合是另一个集合的子集时,这两个集合相等*/
return set_is_subset(set1,set2);
}
数据结构 集合_集合(数学)抽象数据类型的C语言实现的更多相关文章
- 集合抽象数据类型的C语言实现
链表是实现集合的一种理想的方式.将List以typedef的方式重命名为Set.这样做能保留链表简洁的特性,还能使集合具有了一些多态的特性. 使用这种方法的最大好处就是可以使用list_next来遍历 ...
- [数据结构]一元n次多项式的抽象数据类型
一.问题描述 一元n次多项式是代数学中经常出现的代数式,对于一元n次多项式的操作有很重要的实际意义.由于一个一元n次多项式最多有n+1项,且互不相关,所以可以用一个线性表来保存一个多项式,从前至后次数 ...
- 基本数据类型-集合(set)_上周内容回顾(字符串_数字_列表_元组_字典_集合)
上周内容回顾 1.字符串 2.数字 除了布尔类型外,int.long.float和complex都可以使用的运算为:加.减.乘.除.整除.幂运算和取余 3.列表和元组 列表的内容可变,可以包含任意对象 ...
- 【Python&数据结构】 抽象数据类型 Python类机制和异常
这篇是<数据结构与算法Python语言描述>的笔记,但是大头在Python类机制和面向对象编程的说明上面.我也不知道该放什么分类了..总之之前也没怎么认真接触过基于类而不是独立函数的Pyt ...
- 用js来实现那些数据结构09(集合01-集合的实现)
说到集合,第一个想到的就是中学学到的那个数学概念:集合.在我们开始集合相关的js实现前,我们有必要来了解一下什么是集合以及集合的数学概念. 好吧,我们一起来复习一下早就被我们遗忘的集合. 集合是由一组 ...
- Java之旅_高级教_集合框架
摘自:http://www.runoob.com/java/java-collections.html Java 集合框架 早在Java2之前,java 就提供了特设类.比如:Dictionary,V ...
- Python基本语法_集合set/frozenset_内建方法详解
目录 目录 前言 软件环境 可变集合Set set函数创建集合 创建空集合 集合元素的唯一性 集合推导式 set类型对象的内置方法 add增加一个元素 remove删除一个元素 pop随机删除并返回一 ...
- redis 系列8 数据结构之整数集合
一.概述 整数集合(intset)是集合键的底层实现之一, 当一个集合只包含整数值元素,并且这个集合元素数量不多时, Redis就会使用整数集合作为集合键的底层实现.下面创建一个只包含5个元素的集合键 ...
- 20_集合_第20天(Map、可变参数、Collections)_讲义
今日内容介绍 1.Map接口 2.模拟斗地主洗牌发牌 01Map集合概述 A:Map集合概述: 我们通过查看Map接口描述,发现Map接口下的集合与Collection接口下的集合,它们存储数据的形式 ...
随机推荐
- 基于FFMPEG的跨平台播放器实现(二)
基于FFMPEG的跨平台播放器实现(二) 上一节讲到了在Android平台下采用FFmpeg+surface组合打造播放器的方法,这一节讲一下Windows平台FFmpeg + D3D.Linux平台 ...
- “华尔街之狼”:ICO是“史上最大骗局”
勘探船进村的那个夏季,父亲从城里带回了那把手电.手电的金属外壳镀了镍,看上去和摸起来一样冰凉.父亲进城以前采了两筐枸杞子,他用它们换回了那把锃亮的东西.父亲一个人哼着<十八摸>上路,鲜红透 ...
- 64、django之模型层(model)--建表、查询、删除基础
要说一个项目最重要的部分是什么那铁定数据了,也就是数据库,这篇就开始带大家走进django关于模型层model的使用,model主要就是操纵数据库不使用sql语句的情况下完成数据库的增删改查.本篇仅带 ...
- ADO.NET生成的数据库连接字符串解析
1.概述 当我们使用ADO.NET数据实体模型生成的时候,在项目目下生成一个.edmx文件的同时,还会在app.config里面出现如下一个代码串: <?xml version="1. ...
- 队列(存储结构数组)--Java实现
/*队列:其实也是一种操作受限的线性表 *特点:先进先出 *队尾指针:负责元素的进队 *队头指针:负责元素的出队 *注意:普通队--容易浪费空间,一般队列使用最多的就是循环队列--指针环绕 *队列的实 ...
- C++虚函数(09)
一旦基类定义了虚函数,该基类的派生类中的同名函数也自动称为虚函数. 虚函数只能是类中的一个成员函数,但不能是静态成员,关键字virtual用于类中该函数的声明中. 关键字virtual指示C++编译器 ...
- LeetCode 170. Two Sum III - Data structure design (两数之和之三 - 数据结构设计)$
Design and implement a TwoSum class. It should support the following operations: add and find. add - ...
- mybatis like 的坑
昨天快要下班的时候组长交代了一个任务,说起来很简单,是这样的: 系统里面有一个字段为name,这个name允许设置为特殊字符,目前根据name模糊匹配,如果遇到特殊字符 比如 "$" ...
- ios 中的 GCD
摘自:http://www.cocoachina.com/swift/20150129/11057.html libdispatch是Apple所提供的在IOS和OS X上进行并发编程的库,而GCD正 ...
- linux进程资源占用高原因分析命令记录
1.查看进程的线程: ps -eLf|egrep 'gateserver|UID' 2.跟踪线程调用: strace -p 15530 3.统计线程中函数的调用小号CPU时间: strace -p 1 ...