数据结构实验集合的并交差运算实验报告记录
集合运算器实验报告
实验题目:集合运算器需求分析:完成集合的并交差运算算法设计:交集:A集合与B集合求交集,将A中每个元素在B中比较,如果有则此元素属于A∩B 并集:先复制B到C,将A集合中的每个元素在B中比较,如果没有插入C中,C=AUB 差集:A元素在B中如果没有,插入C,C=A-B储存结构:集合用带头结点链表储存,集合头结点用指针数组储存typedef struct Lnode{int alp;struct Lnode *next;}LNode,*LinkList;LinkList L[10]={NULL};算法分析:以并集为例LinkList BingList(LinkList La,LinkList Lb){//求并集,返回并集地址LNode *p,*q,*s;LinkList Lc;if(!La||!Lb)return NULL;Lc=CopyList(La);//复制A到Cq=Lb->next;for(;q;q=q->next)//对B元素依次扫描{for(p=La->next;p;p=p->next)//判断A中是否有此元素if(p->alp==q->alp)break;if(!p)//若无将此元素插入C{s=(LinkList)malloc(sizeof(LNode));s->next=NULL;s->alp=q->alp;Insert(Lc,s);}}return Lc;}时间复杂度:On=mn (m为A的元素个数,n为B的元素个数)空间复杂度:为链表储存,相对来说比较占空间界面:输入:创造集合时根据提示选择位置,之后没输入一个元素加一个回车,以#表示输入结束显示:可以随时显示所有集合测试:图中集合3为集合1并集合2。
数据结构课设报告_集合的并、交和差运算的程序
操作结果:初始化集合的函数,函数参数为引用类型。
2.Set DealSet(char *s)
初始条件:指针s不为空
操作结果:将字符串处理成集合,生成的集合为函数返回值。
3.void PriSet(Set s)
操作结果:打印集合s。
4.Set Jiao(Set sa,Set sb)
3.void PriSet(Set s):
输出集合s,首先输出左花括号’{’,之后使用for循环遍历整个hash数组,如果hash数组的值为真,则说明该集合包含此项元素,输出该元素加空格,之后再输出右花括号’}’。
4.Set Jiao(Set sa,Set sb)
定义两个形参集合sa和sb,遍历两个集合的hash数组,如果两个hash数组的值同时为真,则说明sa和sb集合都含有该元素,则将该元素加入函数之中定义的Res集合,并将Res集合的元素个数加一。在程序最后返回Res集合的值。
Res.num=0;//元素个数为0
}
Set DealSet(char *s)//将字符串处理成集合
{
Set Res;//函数返回的集合
InitSet(Res);//初始化集合
for (int i=0;i<strlen(s);i++)//遍历整个字符串
{
if (s[i]>='a' && s[i]<='z')//在a到z之间,才符合集合元素范围
5.Set Bing(Set sa,Set sb)
和Jiao()函数类似,同样遍历hash数组,唯一不同的是判断hash数组的语句,只要sa和sb其中有一个的值为真,则加入到Res中。
数据结构课程设计_集合的并、交和差运算
数据结构课程设计学院:信息科学与工程学院专业:计算机科学与技术班级:学号:学生姓名:指导教师:2009 年12 月25 日一、实验内容实验题目:编制一个演示集合的并、交和差运算的程序。
需求分析:1、本演示程序中,集合的元素限定为小写字母字符[“a”…”z”]。
集合输入的形式为一个以“回车符“为结束标志的字符串,串中字符顺序不限。
2、演示程序以用户和计算机的对话方式执行,即在计算机终端上显示“提示信息“之后,由用户在键盘上输入演示程序中规定的运算命令;相应的输入数据和运算结果显示在其后。
3、程序执行的命令包括:1)构造集合1;2)构造在集合2;3)求并集;4)求交集;5)求差集;6)返回;7)结束。
“构造集合1”和“构造集合2”时,需以字符的形式键入集合元素。
二、数据结构设计为了实现上述程序的功能,应以有序链表表示集合。
为此,需要两个抽象数据类型:有序表和集合。
1、有序表的抽象数据类型定义为:readdata(pointer head)初始条件:head是以head为头节点的空链表。
操作结果:生成以head为头节点的非空链表。
pop(pointer head)初始条件:head是以head为头节点的非空链表。
操作结果:将以head为头节点的链表中数据逐个输出。
2、集合的抽象数据类型定义为:and(pointer head1,pointer head2,pointer head3)初始条件:链表head1、head2、head3已存在操作结果:生成一个由head1和head2的并集构成的集合head3。
or(pointer head1,pointer head2,pointer head3)初始条件:链表head1、head2、head3已存在操作结果:生成一个由head1和head2的交集构成的集合head3。
differ(pointer head1,pointer head2,pointer head3)初始条件:链表head1、head2、head3已存在操作结果:生成一个由head1和head2的差集构成的集合head3。
集合的实验报告
集合的实验报告集合的实验报告引言:在数学领域中,集合是一个非常重要的概念。
集合是由一些确定的对象组成的整体,这些对象可以是数字、字母、词语等。
通过对集合的研究,我们可以更好地理解和描述事物之间的关系,从而推导出更多的数学定理和结论。
本实验旨在通过实际操作和观察,加深对集合的理解,并探索集合在不同场景下的应用。
实验一:集合的基本操作实验目的:通过实际操作,了解集合的基本操作,包括集合的构建、元素的添加和删除、集合的并、交、差等操作。
实验步骤:1. 构建集合A和集合B:在实验纸上分别写下集合A和集合B的元素,可以是数字、字母或词语。
2. 添加元素:在集合A中添加一个新的元素,观察集合A的变化。
3. 删除元素:从集合B中删除一个元素,观察集合B的变化。
4. 集合的并:将集合A和集合B合并成一个新的集合C,观察集合C的元素。
5. 集合的交:找出集合A和集合B共有的元素,构建一个新的集合D,观察集合D的元素。
6. 集合的差:从集合A中去除集合B的元素,构建一个新的集合E,观察集合E的元素。
实验结果与讨论:通过实验操作,我们可以发现集合的基本操作是非常简单明了的。
集合的构建只需要将元素写在一起即可,添加和删除元素也只需要在集合中进行相应的操作。
集合的并、交、差等操作则是根据元素的共有性或不同性进行相应的操作。
实验二:集合的应用实验目的:通过实际场景的模拟,探索集合在不同场景下的应用。
实验步骤:1. 场景一:假设我们有一个班级的学生名单,其中包括数学、语文、英语等科目的成绩。
我们可以将数学成绩高于80分的学生构成一个集合A,将语文成绩高于80分的学生构成一个集合B,然后进行集合的交操作,找出既在数学成绩高于80分集合中又在语文成绩高于80分集合中的学生,观察结果。
2. 场景二:假设我们有两个购物清单,一个是水果清单,一个是蔬菜清单。
我们可以将水果清单中的水果构成一个集合A,将蔬菜清单中的蔬菜构成一个集合B,然后进行集合的并操作,找出既在水果清单中又在蔬菜清单中的食物,观察结果。
数据结构实验-集合的并交差运算实验报告
实验报告实验课程:数据结构实验项目:实验一集合的并交差运算专业:计算机科学与技术班级:姓名:学号:指导教师:目录一、问题定义及需求分析(1)实验目的(2)实验任务(3)需求分析二、概要设计:(1)抽象数据类型定义(2)主程序流程(3) 模块关系三、详细设计(1)数据类型及存储结构(2)模块设计四、调试分析(1)调试分析(2)算法时空分析(3)经验体会五、使用说明(1)程序使用说明六、测试结果(1)运行测试结果截图七、附录(1)源代码一、问题定义及需求分析(1)实验目的设计一个能演示集合的并、交、差运算程序。
(2)实验任务1)采用顺序表或链表等数据结构。
2)集合的元素限定为数字和小写英文字母。
(3)需求分析:输入形式为:外部输入字符串;输入值限定范围为:数字和小写英文字母;输出形式为:字符集;程序功能:计算两个集合的交、并、差以及重新输入集合功能;二、概要设计:(1)抽象数据类型定义:线性表(2)主程序流程:调用主菜单函数初始化两个线性表作为集合给两个集合输入数据输出集合数据元素信息另初始化两个线性表创建选择功能菜单界面通过不同选项调用不同功能函数在每个功能函数里面加结束选择功能,实现循环调用功能菜单计算完毕退出程序;(3)模块关系:差运算并运算交运算新建集合结束/返回结束三、详细设计抽象数据类型定义:typedef struct{ElemType *elem;int length;int listsize;}SqList;存储结构:顺序表;模块1-在顺序表的逻辑为i的位置插入新元素e的函数;算法如下:/**在顺序表的逻辑为i的位置插入新元素e的函数**/Status ListInsert_Sq(SqList &L,int i,ElemType e){ElemType *newbase,*p,*q;if(i < 1 || i > L.length + 1) return 0; //i的合法值为(1 <= i <= L.length_Sq(L) + 1)if(L.length >= L.listsize){ //当前储存空间已满,增加分配newbase = (ElemType *)realloc(L.elem,(L.listsize + LISTINCREMENT) * sizeof(ElemType));if(!newbase) exit(-1); //储存分配失败L.elem = newbase; //新基址L.listsize += LISTINCREMENT; //增加储存容量}q = &(L.elem[i - 1]); //q为插入位置for(p = &(L.elem[L.length - 1]); p >= q; --p)(p + 1) = p; //插入位置及之后的元素往右移q = e; //插入e++L.length; //表长加1return 1;}模块二在顺序线性表L中查找第1个与e满足compare()的元素位序,若找到,则返回其在L中的位序,否则返回0算法如下:/**在顺序线性表L中查找第1个与e满足compare()的元素位序,若找到,则返回其在L中的位序,否则返回0**/int LocateElem_Sq(SqList L,ElemType e,Status(* compare)(ElemType,ElemType)){ElemType *p;int i;i = 1; //i的初值为第1个元素的位序p = L.elem; //p的初值为第1个元素的储存位置while(i <= L.length && !(* compare)(*p++,e))++i; //从表L中的第一个元素开始与e比较,直到找到L中与e相等的元素时返回该元素的位置if(i <= L.length) return i; //若i的大小小于表长,则满足条件返回ielsereturn 0; //否则,i值不满足条件,返回0}模块三集合交运算算法如下:/**求集合的交集的函数**/void Mix_Sq(SqList La,SqList Lb,SqList &Lc){int i;ElemType elem;Lc.length = 0; //将表Lc的长度设为0for(i = 1; i <= La.length; i++){ //依次查看表La的所有元素elem = La.elem[i-1]; //将表La中i位置的元素赋值给elemif(LocateElem_Sq(Lb,elem,Equal)) //在表Lb中查找是否有与elem相等的元素ListInsert_Sq(Lc,Lc.length+1,elem); //将表La与Lb 中共同的元素放在Lc中}}模块四集合并运算算法如下:/**求集合的并集的函数**/void Union_Sq(SqList La,SqList Lb,SqList &Lc){int i;ElemType elem;Lc.length=0; //将表Lc的长度初设为0for(i = 0; i < La.length; i++) //先将表La 的元素全部复制到表Lc中Lc.elem[Lc.length++]=La.elem[i];for(i = 1; i <= Lb.length; i++){elem = Lb.elem[i-1]; //依次将表Lb 的值赋给elemif(!LocateElem_Sq(La,elem,Equal)) //判断表La 中是否有与elem相同的值ListInsert_Sq(Lc,Lc.length+1,elem); //若有的话将elem放入表Lc中}}模块五集合的差运算算法如下:/**求集合的差集函数**/void Differ_Sq(SqList La,SqList Lb,SqList &Lc){int i;ElemType elem;Lc.length = 0;for(i = 1; i <= La.length; i++){elem = La.elem[i-1]; //把表La 中第i个元素赋值给elemif(!LocateElem_Sq(Lb,elem,Equal)) //判断elem在表Lb中是否有相同的元素ListInsert_Sq(Lc,Lc.length+1,elem); //若有,则把elem放入表Lc中,否则,就不存放}for(i = 1; i <= Lb.length; i++){elem = Lb.elem[i-1]; //把表Lb 中第i个元素赋值给elemif(!LocateElem_Sq(La,elem,Equal)) //判断elem在表La中是否有相同的元素ListInsert_Sq(Lc,Lc.length+1,elem); //若有,则把elem放入表Lc中,否则,就不存放}}四、调试分析问题分析及解决:首先,在编写程序时没有设置线性表的初始长度,导致集合元素输入错误;然后通过#define LIST_INIT_SIZE 100和#define LISTINCREMENT 10解决;时空分析:int LocateElem_Sq(SqList L,ElemType e,Status(*compare)(ElemType,ElemType))时间复杂度为O(n);Status ListInsert_Sq(SqList &L,int i,ElemType e) 时间复杂度为O(n);void Union_Sq(SqList La,SqList Lb,SqList &Lc) 时间复杂度为O(m*n);void Mix_Sq(SqList La,SqList Lb,SqList &Lc) 时间复杂度为O(m*n);void Differ_Sq(SqList La,SqList Lb,SqList &Lc) 时间复杂度为O(2*m*n);改进设想:当同时求两个以上的结合间的运算是需要先进性两个集合间的运算,然后在于另外的集合进行运算;若要同事进行多个集合的运算需要建立多个顺序表;经验体会:顺序表使用起来比较简单,但长度不可随意变化,适用于大量访问元素,而不适用于大量增添和删除元素;在内存中存储地址连续;五、使用说明第一步:点击运行按钮;第二步: 根据提示输入集合A(可以连续输入,只限输入小写字母和数字);第三步:程序自动显示输入结果;第四步:输入集合B(同第二步);第五步:跳出主菜单界面;第六步:根据选项输入对应运算项的数字序号;第七步:显示运算结果,并可继续进行选择运算还是退出;第八步:若继续运算则返回主菜单,否则退出;第九步:循环第六、七、八步,直至选择退出;六、测试结果输入界面:并运算结果:交运算结果:差运算结果:重新建立集合并运算:七、附录#include<stdio.h>#include<stdlib.h>#define LIST_INIT_SIZE 100//初始表空间大小#define LISTINCREMENT 10//表长增量typedef int Status; /**Status是函数类型**/typedef char ElemType;/*ElemType类型根据实际情况而定,这里假设为char*/typedef struct{ElemType *elem; /**储存空间基地址**/int length; /**当前长度**/int listsize;/**当前分配的储存容量(以sizeof(Elemtype)为单位)**/}SqList;SqList La,Lb,Lc,Ld;/**定义全局变量**//**构造一个空的线性表L**/Status InitList_Sq(SqList &L){L.elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));if(!L.elem) exit(-1); /**储存分配失败**/L.length = 0;L.listsize = LIST_INIT_SIZE;/**初始储存容量**/return 1;}/**在顺序表的逻辑为i的位置插入新元素e的函数**/Status ListInsert_Sq(SqList &L,int i,ElemType e){ElemType *newbase,*p,*q;if(i < 1 || i > L.length + 1)return 0;if(L.length >= L.listsize)//当前储存空间已满,增加分配{newbase=(ElemType*)realloc(L.elem,(L.listsize+LISTINCREMENT )*sizeof(ElemType));if(!newbase) exit(-1);//储存分配失败L.elem = newbase;L.listsize += LISTINCREMENT;//增加储存容量}q = &(L.elem[i - 1]);//q为插入位置for(p = &(L.elem[L.length - 1]); p >= q; --p)*(p + 1) = *p;//插入位置及之后的元素往右移*q = e;//插入e++L.length;return 1;}/**创建一个线性表,输入数据**/void CreateList_Sq(SqList &L){ElemType ch='\0';int inlist =0,j;while((ch) != '\n'){scanf("%c",&ch);//输入数据for(j = 0; j < L.length; j++)if(ch == L.elem[j])//判断表L中是否有与ch相等的元素 {inlist = 1; //若有,则inlist置1break; //跳出本轮循环}elseinlist =0; //否则inlist为0if(!inlist && ch != '\n')//若inlist为0且ch不为”\n” ListInsert_Sq(L,L.length+1,ch);//则将ch存入表L中 }}/*判断两元素是否相等,若相等则返回1;否则返回0*/Status Equal(ElemType a,ElemType b){if(a == b)return 1;//相等,返回1elsereturn 0;//否则,返回0}/*在顺序线性表L中查找第1个与e满足compare()的元素位序,若找到,则返回其在L中的位序,否则返回0*/int LocateElem_Sq(SqList L,ElemType e,Status(* compare)(ElemType,ElemType)){ElemType *p;int i;i = 1;p = L.elem;//p的初值为第1个元素的储存位置while(i <= L.length && !(* compare)(*p++,e))//循环查找表L 找出其中与e相等的元素的位置++i;if(i <= L.length)//若i小于表长return i;//则i满足条件,返回i的值elsereturn 0;//否则返回0}/*销毁线性表的函数*/Status Clear_Sq(SqList &L){ElemType elem;free(L.elem);L.elem = NULL;return 1;}/*打印顺序表函数*/void Print_Sq(SqList L){int i;for(i = 0; i < L.length; i++)printf("%2c",L.elem[i]);//通过for循环将表元素全部输出 if(L.length == 0) printf("空集");//若表长为0,则输出空表 printf("\n\t\t\t此集合中的个数 n = %d\n\n",L.length);}/*求集合的并集的函数*/void Union_Sq(SqList La,SqList Lb,SqList &Lc){int i;ElemType elem;Lc.length=0; //将表Lc的长度初设为0for(i = 0; i < La.length; i++) //先将表La的元素全部复制到表Lc中Lc.elem[Lc.length++]=La.elem[i];for(i = 1; i <= Lb.length; i++){elem = Lb.elem[i-1]; //依次将表Lb 的值赋给elemif(!LocateElem_Sq(La,elem,Equal)) //判断表La 中是否有与elem相同的值ListInsert_Sq(Lc,Lc.length+1,elem); //若有的话将elem放入表Lc中}}/*求集合的交集的函数*/void Mix_Sq(SqList La,SqList Lb,SqList &Lc){int i;ElemType elem;Lc.length = 0; //将表Lc的长度设为0for(i = 1; i <= La.length; i++){ //依次查看表La的所有元素elem = La.elem[i-1]; //将表La中i位置的元素赋值给elemif(LocateElem_Sq(Lb,elem,Equal)) //在表La中查找是否有与elem相等的元素ListInsert_Sq(Lc,Lc.length+1,elem); //将表La与Lb中共同的元素放在Lc中}}/*求集合的差集函数*/void Differ_Sq(SqList La,SqList Lb,SqList &Lc){int i;ElemType elem;Lc.length = 0;for(i = 1; i <= La.length; i++){elem = La.elem[i-1]; //把表La中第i个元素赋值给elemif(!LocateElem_Sq(Lb,elem,Equal)) //判断elem在表Lb中是否有相同的元素ListInsert_Sq(Lc,Lc.length+1,elem);//若有,则把elem放入表Lc中,否则,就不存放}for(i = 1; i <= Lb.length; i++){elem = Lb.elem[i-1]; //把表Lb中第i个元素赋值给elem if(!LocateElem_Sq(La,elem,Equal)) //判断elem在表La中是否有相同的元素ListInsert_Sq(Lc,Lc.length+1,elem); //若有,则把elem放入表Lc中,否则,就不存放}}void Index_Sq(){//主菜单函数char s;int l=1;InitList_Sq(La);//初始化表Laprintf("\n\t\t 请输入集合A:");CreateList_Sq(La);//创建表Laprintf("\t\t\t集合A为");Print_Sq(La);printf("\n\n");InitList_Sq(Lb);//初始化表Lbprintf("\t\t 请输入集合B:");CreateList_Sq(Lb);//创建表Lbprintf("\t\t\t集合B为");Print_Sq(Lb);printf("\n\n");InitList_Sq(Lc);//初始化表LcInitList_Sq(Ld);//初始化表Ldwhile(l){printf("\t\t ******* 请输入您的操作选项 1、2、3、4. ****** \n\n");printf("\t\t 1、进行集合的并运算\n");printf("\t\t 2、进行集合的交运算\n");printf("\t\t 3、进行集合的差运算\n");printf("\t\t 4、重新建立两个集合\n");printf("\t\t\t");scanf("%c",&s);switch(s){case '1' : system("cls");Union_Sq(La,Lb,Lc);//调用集合的并运算函数printf("\t\t\t集合A与集合B的并集为:");print_Sq(Lc);printf("\n");break;case '2' :system("cls");Mix_Sq(La,Lb,Lc);//调用集合的交集运算函数printf("\t\t\t集合A与集合B的交集为:");print_Sq(Lc);printf("\n");break;case '3' : system("cls");Differ_Sq(La,Lb,Lc);//调用集合的差集运算函数 printf("\t\t\t集合A与集合B的差集为:");print_Sq(Lc);printf("\n");break;case '4' :system("cls");Clear_Sq(La);//销毁表LaClear_Sq(Lb);//销毁表LbClear_Sq(Lc);//销毁表LcClear_Sq(Ld);//销毁表Ldgetchar();Index_Sq();//递归调用此函数break;default : printf("\t\t\t#\tenter data error!\n");printf("\n");}printf("\t\t 继续计算请输入1,停止计算请输入0 \n");printf("\t\t\t");scanf("%d",&l);getchar();system("cls");}printf("\n\t\t**************** 谢谢使用!*****************\n");}int main(){printf("\t\t************* 欢迎使用集合操作运算器************\n");Index_Sq();//调用主菜单函数return 0;}。
数据结构实训实验报告
一、实验背景数据结构是计算机科学中一个重要的基础学科,它研究如何有效地组织和存储数据,并实现对数据的检索、插入、删除等操作。
为了更好地理解数据结构的概念和原理,我们进行了一次数据结构实训实验,通过实际操作来加深对数据结构的认识。
二、实验目的1. 掌握常见数据结构(如线性表、栈、队列、树、图等)的定义、特点及操作方法。
2. 熟练运用数据结构解决实际问题,提高算法设计能力。
3. 培养团队合作精神,提高实验报告撰写能力。
三、实验内容本次实验主要包括以下内容:1. 线性表(1)实现线性表的顺序存储和链式存储。
(2)实现线性表的插入、删除、查找等操作。
2. 栈与队列(1)实现栈的顺序存储和链式存储。
(2)实现栈的入栈、出栈、判断栈空等操作。
(3)实现队列的顺序存储和链式存储。
(4)实现队列的入队、出队、判断队空等操作。
3. 树与图(1)实现二叉树的顺序存储和链式存储。
(2)实现二叉树的遍历、查找、插入、删除等操作。
(3)实现图的邻接矩阵和邻接表存储。
(4)实现图的深度优先遍历和广度优先遍历。
4. 算法设计与应用(1)实现冒泡排序、选择排序、插入排序等基本排序算法。
(2)实现二分查找算法。
(3)设计并实现一个简单的学生成绩管理系统。
四、实验步骤1. 熟悉实验要求,明确实验目的和内容。
2. 编写代码实现实验内容,对每个数据结构进行测试。
3. 对实验结果进行分析,总结实验过程中的问题和经验。
4. 撰写实验报告,包括实验目的、内容、步骤、结果分析等。
五、实验结果与分析1. 线性表(1)顺序存储的线性表实现简单,但插入和删除操作效率较低。
(2)链式存储的线性表插入和删除操作效率较高,但存储空间占用较大。
2. 栈与队列(1)栈和队列的顺序存储和链式存储实现简单,但顺序存储空间利用率较低。
(2)栈和队列的入栈、出队、判断空等操作实现简单,但需要考虑数据结构的边界条件。
3. 树与图(1)二叉树和图的存储结构实现复杂,但能够有效地表示和处理数据。
数据结构实验报告:集合的交叉并
《数据结构》实验报告题目:集合的并、交、差专业:信息管理与信息系统班级:17信管3组别:一组长:胡源完成日期:2018年10月23 日评分依据及结果代码分工情况实验报告分工情况一、需求分析1.本演示程序中,集合的元素限定为小写字母和数字,集合的大小小于MAXSIZE=100(可以通过宏定义来动态改变大小)。
集合的输入形式为以一个“回车符”为结束标志的字符串,串中字符顺序不限。
程序能自动过滤出现的重复字符和非法字符,且经过过滤的集合中,数字始终在字母前面。
输出运算结果字符中不含重复字符或非法字符。
2.演示程序以用户和计算机的对话方式执行,即在计算机终端上显示“提示信息”之后,由用户在键盘上输入演示程序中规定的运算命令,相应的输入数据(除去非法字符)和运算结果显示在其后。
3.程序的执行命令包括:1)构造集合1;2)构造集合2;3)求并集;4)求交集;5)求差集;6)程序结束。
“构造集合1”和“构造集合2”时,需要以字符串的形式链入集合元素。
4.测试数据(1)S et1=”abcdefg”,Set1=”123456”(未赋值时的原始集合)Set2∩Set2=”123456abcdefg”, Set2∩Set2=””,Set2-Set2=”abcdefg”(2)S et1=”1314524huyuan”,Set1=”748fuck”Set2∩Set2=”12345678acfhknuy”, Set2∩Set2=” 4u”,Set2-Set2=”1235ahny”(3)S et1=”1314524huyuan数据结构”,Set1=”958abcd考研”Set2∩Set2=”1234589abcdhnuy”, Set2∩Set2=” 5a”,Set2-Set2=”1234hnuy”二、概要设计用有序链表表示集合来使程序达到预期功能。
因此,需要一个抽象数据类型:有序集合。
1.有序集合的抽象数据类型定义为:ADT OrderedList{数据对象:D={a|a为数字(1-9)或字母(a-z)}数据关系:R={<a[i]-1,a[i]>|a[i-1],a[i]∈D,a[i-1]<a[i],i为自然数}}基本操作:InitList(&L)操作结果:构造空的有序链集合LocateElem(L, e, &p)。
实验一之集合并、交、差运算
算法与数据结构实验报告实验一实验名称: 集合的运算问题姓名:学号:专业:软件工程班级:指导教师:日期: 2013年月日一、实验目的学会应用线性表解决集合运算问题,熟练掌握顺序表或是单链表上实现的各种基本操作。
二、实验内容与实验步骤内容:实现集合的差集,交集,并集操作,输出结果。
步骤: 1 定义栈数据类型,采用链式存储结构实现2 链栈基本操作函数原型声明3 初始化栈4 输入栈5 输出栈6 判空栈7 自定义实现进制转换函数8 数据调试9 程序结束三、实验环境操作系统winXP、开发平台:Microsoft Visual C++6.0四、实验过程与分析程序设计过程中忘了考虑到开始报数的数不能超过最大编号;而导致程序的健壮性不足,经修改后,解决了这一问题;五、实验结论六、附录#include<iostream>using namespace std;typedef char ElemType;typedef struct node{ //单链表node* next;ElemType data;}List;void ListInit(List *L){ //初始化链表L->next = (List *)malloc(sizeof(node));L->next = 0;}void ListInsert(List &L,ElemType e) //在链表L的结尾插入元素e{List *p,*q;p = L.next;q = &L;while(p){p = p -> next;q = q -> next;}p = (List *)malloc(sizeof(List));p -> data = e;q -> next = p;p -> next = NULL;}bool ListSearch(List L,ElemType e) //在链表L中查找元素e,查找到返回true,否则返回false {List* p ;p = L.next;while(p){if(p->data == e) return true;else p = p -> next;}return false;}bool ListDelete(List &L,ElemType e) //在链表L删除元素e,先查找e,查找到删除e,并返回true,没找到返回false{List *p,*q;p = L.next; q = &L;while(p){if(p->data == e){q -> next = p -> next;return true;}else{q = p;p = p -> next;}}return false;}void ListCopy(List &L,List L1) //将链表L1赋给L{List *p,*q; p = L1.next; q = &L;while(p){q -> next = (List *)malloc(sizeof(List));q -> next->data = p->data;p = p -> next;q = q -> next;}q -> next = (List *)malloc(sizeof(List));q -> next = NULL;}//下载后去掉字符边框即可void Union(List L1,List L2,List &L) //集合L1并上L2赋给L{List *p;p = L2.next;ListCopy(L,L1);while(p){if(!ListSearch(L,p->data)) ListInsert(L,p->data);p = p->next;}}void Difference(List L1,List L2,List &L) //集合L等于L1与L2的差集{List *p;p = L1.next;while(p){if(!ListSearch(L2,p->data)) ListInsert(L,p -> data);p = p -> next;}}void Intersection(List L1,List L2,List &L) //集合L等于L1与L2的交集{List *p;p = L1.next;while(p){if(ListSearch(L2,p->data)) ListInsert(L,p -> data);p = p -> next;}}void Display(List L) //输出集合的元素{List *p = L.next;while(p){cout<<p->data;p = p->next;}cout<<endl;}int main(){ElemType c;List A,B,C;ListInit(&A);ListInit(&B);cout<<"********************* 集合A和B的创建**********************\n";cout<<"输入集合A的元素:"<<endl;while(scanf("%c",&c)) //集合A的输入{if(c == '\n') break;ListInsert(A,c);}cout<<"输入集合B的元素:"<<endl;while(scanf("%c",&c)) //集合B的输入{if(c=='\n') break;ListInsert(B,c);}cout<<"\n************************* 集合A+B *************************\n";ListInit(&C); //初始化集合CUnion(A,B,C); //集合并cout<<"集合A+B:"<<endl;Display(C);cout<<"\n************************* 集合A-B *************************\n";ListInit(&C);Difference(A,B,C); //集合差A-Bcout<<"集合A-B:"<<endl;Display(C);cout<<"\n************************* 集合B-A *************************\n";ListInit(&C);Difference(B,A,C); //集合差B-Acout<<"集合B-A:"<<endl;Display(C);cout<<"\n************************* 集合A^B *************************\n";ListInit(&C);Intersection(A,B,C); //集合交cout<<"集合A^B:"<<endl;Display(C);cout<<"\n*************************** ****************************\n";cout<<"************************ 程序结束*************************\n";cout<<"*************************** ****************************\n";return 0;}。
数据结构课程设计集合的并、交和差运算 (1)
数据结构课程设计报告设计题目:专业计算机科学与技术班级计091学生张楠学号3090911020指导教师起止时间2011.7.4~2011.7.922011 年夏季学期目录1.实验内容实验题目:编制一个演示集合的并、交运算的程序。
题目:集合运算功能:使用链表来表示集合,完成集合的合并,求交集等操作。
分步实施:1.初步完成总体设计,搭好框架,确定人机对话的界面,确定函数个数;2.完成最低要求:3.进一步要求:要求:1)界面友好,函数功能要划分好2)总体设计应画一流程图3)程序要加必要的注释4)要提供程序测试方案1)程序一定要经得起测试,宁可功能少一些,也要能运行起来,不能运行的程序是没有价值的。
需求分析:1、本演示程序中,集合的元素限定为整形数据。
集合输入的形式为一个以“0“为结束标志。
2、演示程序以用户和计算机的对话方式执行,即在计算机终端上显示“提示信息“之后,由用户在键盘上输入演示程序中规定的运算命令;相应的输入数据和运算结果显示在其后。
3、程序执行的命令包括:1)构造集合1;2)构造在集合2;3)求并集;4)求交集;5)求差集;6)返回;7)结束。
“构造集合1”和“构造集合2”时,需以整形的形式键入集合元素。
二、数据结构设计及流程图为了实现上述程序的功能,应以有序链表表示集合。
为此,需要两个抽象数据类型:有序表和集合。
1、有序表的抽象数据类型定义为:input(linklist l)初始条件:l是以l为头节点的空链表。
操作结果:生成以l为头节点的非空链表。
output(linklist l)初始条件:l是以l为头节点的非空链表。
操作结果:将以l为头节点的链表中数据逐个输出。
2、集合的抽象数据类型定义为:heji(linklist A,linklist B,linklist C)初始条件:链表A、B、C已存在操作结果:生成一个由A和B的并集构成的集合C。
jiaoji(linklist A,linklist B ,linklist ,C)初始条件:链表A、B、C已存在操作结果:生成一个由A和B的交集构成的集合C。
(完整word版)数据结构(C语言版)实验报告集合的交并差
《数据结构与算法》实验报告一、需求分析问题描述:编制一个能演示执行集合的并、交和差运算的程序基本要求:集合元素限定为小写字母[’a’…’z’];演示程序以用户和计算机对话方式执行。
集合的输入形式为一个以“回车符”为结束标志的字符串,串中字符顺序不限,且允许出现重复字符或非法字符,程序运用时自动过滤去,输出的运算结果中将不含重复字符和非法字符。
计算机终端中显示提示信息之后,由用户自行选择下一步命令,相应输入数据和运算结果在其后显示。
数据测试:(1)Set1=”magazine”,Set2=’paper”,Set1∪Set2=”aegimnprz”,Set1∩Set2=”ae”,Set1-Set2="gimnz”;(2) Set1=”012oper4a6tion89”,Set2="error data",Set1∪Set2=”adeinoprt”,Set1∩Set2=”aeort”,Set1—Set2="inp”.二、概要设计运用顺序表1。
定义顺序表typedef struct SET{char *elem;int size;int length;}set;2 基本操作:set InitSet(set s);//初始化集合set Input(set s);//向集合中输入元素set InsertSet(set s, char e);//向集合中插入元素set DelateSet(set s,int n);//从集合中删除元素void display(set s);//显示集合set SetMix(set set1,set set2,set set3);//求集合的交集set check(set s);//检查集合中是否有数字或者重复字母set Sort(set s);//对集合中的元素进行排序三、详细设计1.头文件#include〈stdio.h〉#include〈stdlib.h>#include〈string。
数据结构课程设计-集合的交并差运算
编号:730数据结构与算法课程设计说明书集合的交并差运算学院:海洋信息工程学院专业:网络工程学生姓名:xx学号:xx指导教师:xx2017 年12 月21 日目录目录 (2)概述 (3)程序说明 (3)1 实验内容 (4)1.1实验目的 (4)1.2实验任务 (4)1.3要求 (4)2 数据结构设计及流程图 (5)2.1 抽象数据结构类型定义 (5)2.2本程序包含四个模块 (7)3 测试数据 (8)3.1源程序 (8)3.2测试数据及程序运行情况 (14)4 总结 (15)参考文献 (15)概述本演示程序的编写,主要运用的我们学的第二章《线性表》中的知识。
线性结构的特点是:在数据元素的非空有限集中,(1)存在唯一的一个被称做“第一个”的数据元素;(2)存在唯一的一个被称做“最后一个”的数据元素;(3)除第一个之外,集合中的每个数据元素均只有一个前驱;(4)除最后一个之外,集合中每个数据元素均只有一个后继。
本程序需要两个抽象数据类型:有序表和集合。
而且采用了单链表来实现。
一、程序说明本程序主要利用单链表及函数,实现集合的交集、并集和差集运算。
运行程序说明:菜单执行的命令包括<0-7> :<1>“请输入 A 集合的个数与A集合元素”<2>“请输入 B 集合个数与B集合的元素”<3>“A集合的有序集合”<4>“B集合的有序集合”<5>“AB集合的并集”<6>“AB集合的交集”<7>“AB集合的差集”<0>“退出” 注:展示程序中,集合元素限定为小写字母数据,以“回车键”束标志。
1、实验内容1.1 实验目的:设计一个演示集合的交、并、差的运算程序1.2 实验任务1) 使用单链表来表示集合,完成集合的交集、并集、差等操作。
2) 采用链表等数据结构。
3) 集合的元素限定为数字和小写的英文字母1.3 实验要求:1. 初步完成总体设计,建立头文件,确定函数个数。
基于单链表实现集合的并交差运算实验报告
基于单链表实现集合的并交差运算实验报告一 实验题目: 基于单链表实现集合的并交差运算二 实验要求:2.2:编写一个程序,实现顺序表的各种基本运算(1)初始化单链表h ;(2)依次采用尾插法插入a,b,c,d,e 元素;(3)输出单链表h(4)输出单链表h 的长度(5)判断单链表h 是否为空(6)输出单链表h 的第三个元素(7)输出元素在a 的位置(8)在第4个元素位置上插入f 元素(9)输出单链表h(10)删除L 的第3个元素(11)输出单链表(12)释放单链表2.2:编写一个程序,采用单链表表示集合(集合中不存在重复的元素),并将其按照递增的方式排序,构成有序单链表,并求这样的两个集合的并,交和差。
三 实验内容:3.1 线性表的抽象数据类型:ADT List{数据对象;D=}0,,...,2,1,ElemS et |{≥=∈n n i a a i i数据关系:R1=},...,2,,|,{11n i D a a a a i i i i =∈><--基本操作:InitList(&L)操作结果;构造一个空的线性表LDestroyList(&L)初始条件:线性表L已存在操作结果:销毁线性表LClearList(&L)初始条件:线性表L已存在操作结果:将L置为空表ListEmpty(L)初始条件:线性表已存在操作结果:若L为空表,则返回TRUE,否则返回FALSEListLength(L)初始条件:线性表已存在操作结果:返回L中数据元素的个数GetElem(L,i)初始条件:线性表已存在,1<=i<=ListLength(L)操作结果:用e返回L中第i个数据元素的值LocateElem(L,i,e)初始条件:线性表已存在,用循环遍历整个线性表,如果e与线性表中的元素相同;操作结果:用此时的i+1返回该元素在线性表的位序ListInsert(&L,i,e)初始条件:线性表存在,1<=i<=ListLength(L)+1;操作结果:在L中第i个位置之前插入新的数据元素,e,L的长度加1。
数据结构试验报告-集合的交并差
实验报告:集合的交并差运算题目:编写一个演示集合的交并差运算的计算机程序一、需求分析1.本次实验中要求输入的集合的元素类型为小写字母a到z,集合输入结束的标志是一“回车符”为标志的,集合的输入不限字符输入的顺序且允许重复输入和输入非法字符;2.本次实验中输出的集合中不包含重复的元素,集合中的元素按ASCII从小到大排列输出且将自动过滤输入的非法字符;3.本次实验的程序可以计算用户输入的两个集合的交集、并集和补集;4.本次实验的测试数据有:输入的集合为Set1=”magazine”,Set2=”paper”,输出的集合为Set1=”aegimnz”,Set2=”aepr”, 并集为”aegimnprz”, 交集为”ae”,差集为”gimnz”;输入的集合为Set1=”WE056gyh”,Set2=”asyE”,输出的集合为Set1=”ghy”,Set2=”asy”,并集为”aghsy”,并集为”y”,差集为”aghs”。
二、概要分析为实现上述程序的功能,用有序链表表示集合。
因此,需要有两个抽象数据类型:有序表和集合。
1.有序表的抽象数据类型定义:ADT OrderedList{数据对象:D={ai|ai∈CharSet,i=1,2...,n,n>=0}数据关系:R1={<ai-1,ai>|ai-1,ai∈D,ai-1<ai,i=2...n}基本操作:InitList(&L)操作结果;构造一个空的有序表L。
DestroyList(&L)初始条件:有序表L已存在。
操作结果:销毁有序表L。
ListLength(L)初始条件:有序表L已存在。
操作结果:返回有序表L的长度。
ListEmpty(L)初始条件:有序表L已存在。
操作结果:若有序表L为空表,返回True,否则返回False。
GetElem(L,i,&e)初始条件:有序表L已存在,若1<=i<=Length(L)。
数据结构 求集合并集交集实验报告
实验报告题目:集合的并、交和差运算班级:13信息管理姓名:刘学号:20130403012 完成日期:20,11一、需求分析1[问题描述]编制一个能演示执行集合的并、交和差运算的程序。
2[基本要求](1)集合的元素限定为整数。
(2)用链式存储结构完成。
3.测试数据set1={ 1 2 3 4 5 },set2={ 3 4 5 6 7 }set1∪set2={ 1 2 3 4 5 6 7 };set1∩set2={ 3 4 5 }set1-set2={ 1 2 }二、编码实现1.存储类型typedef struct LNode{int data;struct LNode *next;}LNode,*LinkList;2.部分函数的伪码算法//构造一个集合void CreateList_L(LinkList &L){LinkList p;int n,i;printf("请输入元素个数:\n");scanf("%d",&n);L=(LinkList)malloc(sizeof(LNode));L->next=NULL;printf("请一次输入各个元素:\n");for(i=n;i>0;--i){p=(LinkList)malloc(sizeof(LNode));scanf("%d",&p->data);p->next=L->next;L->next=p;}}//取出数据值int get_data(LinkList h){int t;t=h->data;return t;}//删除与t相同的节点LinkList del(LinkList L1,int t){LinkList p1,p2;p1=L1->next;while(t!=p1->data&&p1->next!=NULL){p2=p1,p1=p1->next;}if(t==p1->data){if(p1==L1->next)L1->next=p1->next;elsep2->next=p1->next;}return L1;}//打印集合void printf_L(LinkList &L){LinkList h;h=L->next;while(h){printf(" %d ",h->data);h=h->next;}}//集合排序void sort(LinkList &L){LinkList p=L->next,q,r;if(p){r=p->next;p->next=NULL;p=r;}while(p){r=p->next;q=L;while(q->next!=NULL&&q->next->data<p->data) q=q->next;p->next=q->next;q->next=p;p=r;}}//集合并集void combine(LinkList &L1,LinkList L2){LinkList p,h;p=L1;while(p->next){p=p->next;}p->next=L2->next;sort(L1);p=L1->next;while(p->next){if(p->data==p->next->data){h=p->next;p->next=h->next;free(h);}elsep=p->next;}}//集合的差void differ(LinkList L1,LinkList L2){int t;LinkList h;h=L2->next;while(h){t=get_data(h);L1=del(L1,t);h=h->next;}}//交集void intersectLink(LinkList L1,LinkList L2) {LinkList p,h;p=L1;while(p->next){p=p->next;}p->next=L2->next;sort(L1);p=L1;while(p->next->next){h=p->next->next;if(p->next->data!=h->data){p->next=h;h=h->next;}elsep=p->next;}p->next=NULL;}三、调试分析1,说实话,自己根本不会做,参考网上的资料都做不出来;2,自己做的程序,没有任何错误,但就是不能运行;3,对链表的认识不够深入,不知道如何构造链表,以及实现各种操作;四、测试结果set1={ 1 2 3 4 5 },set2={ 3 4 5 6 7 }set1∪set2={ 1 2 3 4 5 6 7 };set1∩set2={ 3 4 5 }set1-set2={ 1 2 }五.附录#include<stdlib.h>typedef struct LNode{int data;struct LNode *next;}LNode,*LinkList;//构建集合函数void CreateList_L(LinkList &L){LinkList p;int n,;i;printf("请输入元素个数:\n");scanf("%d",&n);L=(LinkList)malloc(sizeof(LNode));L->next=NULL;printf("请一次输入各个元素:\n");for(i=n;i>0;--i){p=(LinkList)malloc(sizeof(LNode));scanf("%d",&p->data);p->next=L->next;L->next=p;}}//获取数据函数int get_data(LinkList h){int t;t=h->data;return t;}//删除函数LinkList del(LinkList L1,int t){LinkList p1,p2;p1=L1->next;while(t!=p1->data&&p1->next!=NULL){p2=p1,p1=p1->next;}if(t==p1->data){if(p1==L1->next)L1->next=p1->next;elsep2->next=p1->next;}return L1;}//打印函数void printf_L(LinkList &L){LinkList h;h=L->next;while(h){printf(" %d ",h->data);h=h->next;}}//排序void sort(LinkList &L){LinkList p=L->next,q,r;if(p){r=p->next;p->next=NULL;p=r;}while(p){r=p->next;q=L;while(q->next!=NULL&&q->next->data<p->data) q=q->next;p->next=q->next;q->next=p;p=r;}}//并集void combine(LinkList &L1,LinkList L2)LinkList p,h;p=L1;while(p->next){p=p->next;}p->next=L2->next;sort(L1);p=L1->next;while(p->next){if(p->data==p->next->data){h=p->next;p->next=h->next;free(h);}elsep=p->next;}}//求差void differ(LinkList L1,LinkList L2) {int t;LinkList h;h=L2->next;while(h){t=get_data(h);L1=del(L1,t);h=h->next;}}//交集void intersect(LinkList L1,LinkList L2) {LinkList p,h;p=L1;while(p->next){p=p->next;}p->next=L2->next;sort(L1);p=L1;while(p->next->next){h=p->next->next;if(p->next->data!=h->data){p->next=h;h=h->next;}elsep=p->next;}p->next=NULL;}//主函数int main(){LinkList L1,L2;int t;printf("求集合交集请按1\n求集合并集请按2\n请集合之差请按3\n");scanf("%d",&t);while(t!=0){switch(t){case 1:CreateList_L(L1);CreateList_L(L2);intersect(L1,L2);sort(L1);printf_L(L1);break;case 2:CreateList_L(L1);CreateList_L(L2);combine(L1,L2);sort(L1);printf_L(L1);break;case 3:CreateList_L(L1);CreateList_L(L2);differ(L1,L2);sort(L1);printf_L(L1);break;default :printf("error\n");}scanf("%d",&t);}return 0;}11。
数据结构与数据库实验一集合的运算
数据结构与数据库实验仅供参考实验一集合的表示及运算实验名称:集合的表示及运算专业:电气工程姓名:学号:集合的表示及运算一、实验要求1.程序的功能:实现集合的交、并、判断相等运算。
2.输入输出的要求:设计的数据结构应有利于表示任意个数元素组成的集合。
3.测试数据。
(1) {a, b, c}, {b, c, d}(2) {a, b,c}, {x, y}(3) { }, {x, y}(4) {a, x, b}, {a, x, b}二、概要设计1.采用的数据结构的定义及主要功能模块的功能:在本实验中,数据的存储采用数组连续存储方式。
由于本实验相对简单,功能相对较少,只是针对数组进行交并等基础性操作,所以本实验中只采用了函数模板,这样比结构体、类以及类模板都更加简洁、易懂,也更有利于实现对多种数据类型的数据进行操作。
而且,为了满足设计的数据结构应有利于表示任意个数元素组成的集合,在本实验中采用由用户自己输入所需存储空间的最大长度,动态分配所需存储空间。
由于含有动态生成的数据成员,必须自定义析构函数以释放动态分配的内存,本实验中的析构函数为Delete(T*,T*)。
字符串的比较采用string类2、各个函数模板的声明及其功能如下:1、判断集合是否相等的运算:template<typename T>void deng_array(T*A,T*B,int A_mm,int B_mm);//A、B为需要进行判断是否相等的数组,A_mm、B_mm 分别为数组A、B的最大存储空间,由用户在输入数组数据时确定并输入,算法根据用户输入的数据动态建立相应的存储空间。
以下各形式参量的意义均与此相同。
2、集合的交运算:template<typename T>void jiao_array(T*A,T*B,int A_mm,int B_mm);3、集合的并运算:template<typename T>void bing_array(T*A,T*B,int A_mm,int B_mm);4、析构函数:template<typename T>void Delete(T*A,T*B);//释放动态分配的内存5、字符串的交运算template <typename T>string jiao_string(T & A,T &B);6、字符串的并运算template <typename T>string jiao_string(T & A,T &B);7、判断字符串是否相等:采用string中的’=‘if(A==B)cout<<"EQUAL"<<endl;cout<<"NOT EQUAL"<<endl;三、详细设计1、各模块的流程图:1、判断集合是否相等的运算:2、集合的交运算:3、集合的并运算:4、析构函数:释放动态分配的内存:delete[]A;delete[]B;5、字符串的交运算6、字符串的并运算四、调试分析1、在本实验中,集合的数据类型可以实现字符型、整型,用户可根据系统提示进行选择。
滨江学院 数据结构实习报告--集合的并交叉运算报告
集合的并、交和差运算一、需求分析设计目的:通过集合运算的实现,熟练掌握线性表的基本操作在两种存储结构上的实现,其中以各种链表的操作和应用作为重点内容。
1.本演示程序中,集合的元素限制在小写字母‘a’-‘z’之间。
集合的大小不限制,集合的输入形式为一个以“#”为结束标志的字符串,串中字符顺序不限,且允许出现重复字符或非法字符,程序运用时自动过滤去,输出的运算结果中将不含重复字符和非法字符。
2.演示程序以用户和计算机对话的形式进行,即在计算机终端中显示提示信息之后,有用户自行选择下一步命令,相应输入数据和运算结果在其后显示。
3.程序的执行命令有:1)选择操作2)任意键清屏二、概要设计三、详细设计#include <iostream> //C++输入输出流#include <List> //链表类using namespace std;#define DataTpye char//定义数据类型bool IsElementInList(list<DataTpye> aSet, DataTpye iElement)//查看iElement元素是否在aSet集合中{list<DataTpye>::iterator iter;for (iter = aSet.begin(); iter != aSet.end(); iter++)//遍历aSet单链表中的所有元素【后面同理】,直到找到与iElement元素相同的元素,返回true表明存在iElement元素{if (*iter == iElement) //在单链表中找到了与iElement元素相同的元素,此时开始执行if语句块{return true;}}//由于不满足for中的条件表明iElement元素在aSet中不存在return false;}void Trim(list<DataTpye> &aSet)//去除集合aSet中的重复元素{list<DataTpye> newSet;//在这里新创建一个单链表newSet,后面对aSet中的相同元素删除其仅剩一个为止,并放入newSetlist<DataTpye>::iterator iter;for (iter = aSet.begin(); iter != aSet.end(); iter++){if (!IsElementInList(newSet, *iter)&&(*iter>=97&&*iter<=122))//(*iter>=97&&*iter<=122)这是极其关键的一部分,它的作用是删除链表中的数字//在存储的时候数字是以字符的形式存储的,此时通过使用小写英文字母的ASCII码来限制入栈的元素{newSet.push_back(*iter);}}aSet = newSet;//操作进行完成将newSet有重新赋给aSet}void Union(list<DataTpye> set1, list<DataTpye> set2)//实现集合的并集运算,找出Set,Set_2中的所有元素{list<DataTpye> newSet = set1;list<DataTpye>::iterator iter;for (iter = set2.begin(); iter != set2.end(); iter++){if (IsElementInList(newSet, *iter)){continue;//在newSet中查找与iter相同的元素,如果if语句条件成立,表明IsElementInList()操作完成后返回了true//不做处理,跳出循环继续向后查找在newSet中查找与iter相同的元素}else{newSet.push_back(*iter);//if不满足条件表明是在set2中存在的元素而在set1中没有,此时入栈到newSet}}Trim(newSet);newSet.sort();//类中的方法,将单链表中的元素有序排列cout<<"集合的并操作结果是:"<<endl;cout<<"{";for (iter = newSet.begin(); iter != newSet.end(); iter++){cout<<*iter<<" ";}cout<<"}"<<endl;}void Inter(list<DataTpye> set1, list<DataTpye> set2)//实现集合的交集运算,找出Set,Set中的相同元素{list<DataTpye> newSet;list<DataTpye>::iterator iter;for (iter = set1.begin(); iter != set1.end(); iter++){if (IsElementInList(set2, *iter)){//在newSet中查找与iter相同的元素,如果if语句条件成立,表明IsElementInList()操作完成后返回了true//if条件成立找到了set2与set1相同的元素此时入栈到newSetnewSet.push_back(*iter);}else{continue;}}Trim(newSet);newSet.sort();cout<<"集合的交操作结果是:"<<endl;cout<<"{";for (iter = newSet.begin(); iter != newSet.end(); iter++){cout<<*iter<<" ";}cout<<"}"<<endl;}void Differ(list<DataTpye> set1, list<DataTpye> set2)//实现集合的差集运算,其本质是:在Set中找出与Set相同的元素将其删除{list<DataTpye> newSet;list<DataTpye>::iterator iter;for (iter = set1.begin(); iter != set1.end(); iter++){if (IsElementInList(set2, *iter)){//在set2中找出与iter相同的元素,不做入栈continue;}else{newSet.push_back(*iter);//将set1中与set2不相同的元素入栈到newSet,其意义就是作set1-set2}}Trim(newSet);newSet.sort();cout<<"集合的差操作结果是:"<<endl;cout<<"{";for (iter = newSet.begin(); iter != newSet.end(); iter++){cout<<*iter<<" ";}cout<<"}"<<endl;}int main(void){cout<<"输入集合Set1的元素,按'#'结束"<<endl;list<DataTpye> set1, set2;//定义两个单链表set1, set2用来实现测试数据元素的输入list<DataTpye>::iterator iter;DataTpye iIn = -1; //初始化输入的元素while ('#' != iIn) //用【#】来作为结束输入的结束标志{cin>>iIn;set1.push_back(iIn);}set1.pop_back();Trim(set1);set1.sort();cout<<"输入的集合set1是:"<<endl;cout<<"{";for (iter = set1.begin(); iter != set1.end(); iter++){cout<<*iter<<" ";}cout<<"}"<<endl;cout<<"输入集合set2的元素,按'#'结束"<<endl;iIn = -1; //回置数据标志while ('#' != iIn){cin>>iIn;set2.push_back(iIn);}set2.pop_back();Trim(set2);set2.sort();cout<<"输入的集合set2是:"<<endl;cout<<"{";for (iter = set2.begin(); iter != set2.end(); iter++){cout<<*iter<<" ";}cout<<"}"<<endl;here:cout<<"选择操作:1并集,2交集,3差集,0退出"<<endl;cin>>iIn;switch(iIn){case '1':Union(set1, set2);break;case '2':Inter(set1, set2);break;case '3':Differ(set1, set2);break;case '0':return 0 ;default:break;}goto here;}四、调试分析1、本实习作业采用数据抽象的程序设计方法,将程序划分为三个层次:结构体定义、操作函数、主控模块,使得设计思路清晰,实现时调试顺利,各模块具有较好的可重复性,确实得到了一次良好的程序设计训练。
zgy实验三集合的交、并和差运算的实现
实验三集合的交、并和差运算的实现1. 问题描述用有序单链表表示集合,实现集合的交、并和差运算。
2. 基本要求⑴对集合中的元素,用有序单链表进行存储;⑵实现交、并、差运算时,不另外申请存储空间;⑶充分利用单链表的有序性,算法有较好的时间性能。
3.编码zgy1111.h Filestemplate<class T>struct Node{T data;N ode<T> *next;};template<class T>class LinkList{public:L inkList();L inkList(T a[],int n);void Interest(LinkList s1,LinkList s2);v oid Union(LinkList s1,LinkList s2);v oid Compiement(LinkList s1,LinkList s2);v oid PrintList();private:N ode<T> *first;};zgy1234.cpp Files#include<iostream>using namespace std;#include"zgy1111.h"template<class T>LinkList<T>::LinkList(){f irst=new Node<T>;f irst->next=NULL;}template<class T>LinkList<T>::LinkList(T a[],int n){first=new Node<T>;N ode<T> *r=first;f or(int i=0;i<n;i++){Node<T> *s=new Node<T>;s->data=a[i];r->next=s;r=s;}r->next=NULL;}template<class T>void LinkList<T>::Interest(LinkList s1,LinkList s2)//交集{Node<T> *pre=s1.first;N ode<T> *p=s1.first->next;N ode<T> *q=s2.first->next;while (p && q){if (p->data<q->data){pre->next=p->next;pre=p;p=p->next;}else if (p->data>q->data) q=q->next;else{pre=p;p=p->next;q=q->next;}}}template<class T>void LinkList<T>::Union(LinkList s1,LinkList s2)//并集{Node<T> *pre=s1.first,*p=s1.first->next,*q=s2.first->next;while (p && q){if (p->data<q->data){pre=p;p=p->next;}else if (p->data>q->data){pre->next=q;q=q->next;pre->next->next=p;}else{pre=p;p=p->next;q=q->next;}}i f(p==NULL&&q){pre->next=q;}}template<class T>void LinkList<T>::Compiement(LinkList s1,LinkList s2)//差集{Node<T> *pre=s1.first,*p=s1.first->next,*q=s2.first->next;while (p && q){if (p->data<q->data){p=p->next;}else if (p->data>q->data){q=q->next;}else{pre->next=p->next;p=p->next;q=q->next;}}}template<class T>void LinkList<T>::PrintList(){N ode<T> *p=first->next;w hile(p!=NULL){cout<<p->data<<" ";p=p->next;}}主函数#include<iostream>using namespace std;#include"zgy1234.cpp"void main(){s ystem("color b0");//选择系统颜色i nt c;d o{system("CLS");int a[10],b[10];int m,n,k;cout<<"输入数组a的元素个数:";cout<<"依次输入数组a的元素:";for(int i=0;i<m;i++)cin>>a[i];cout<<"输入数组b的元素个数:";cin>>n;cout<<"依次输入数组b的元素:";for(int j=0;j<n;j++)cin>>b[j];LinkList<int> list1(a,m),list2(b,n);cout<<"请选择功能:1.求交集 2.求并集 3.求差集"<<endl;cout<<"请输入:";cin>>k;switch(k){case 1:list1.Interest(list1,list2);cout<<"交集为:";list1.PrintList();cout<<endl;break;case 2:list1.Union(list1,list2);cout<<"并集为:";list1.PrintList();cout<<endl;break;case 3:piement(list1,list2);cout<<"差集为:";list1.PrintList();cout<<endl;break;default:cout<<"输入错误!"<<endl;break;}cout<<" 0.退出 1.重试"<<endl;cout<<"请选择:";cin>>c;}while(c);4.运行与调试a.程序运行结果及测试数据5.实验小结本次实验主要是通过实验过程掌握用有序单链表表示集合,实现集合的交、并和差运算。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构实验集合的并交差运算实验报告记录————————————————————————————————作者:————————————————————————————————日期:实验报告实验课程:数据结构实验项目:实验一集合的并交差运算专业:计算机科学与技术班级:姓名:学号:指导教师:目录一、问题定义及需求分析(1)实验目的(2)实验任务(3)需求分析二、概要设计:(1)抽象数据类型定义(2)主程序流程(3) 模块关系三、详细设计(1)数据类型及存储结构(2)模块设计四、调试分析(1)调试分析(2)算法时空分析(3)经验体会五、使用说明(1)程序使用说明六、测试结果(1)运行测试结果截图七、附录(1)源代码一、问题定义及需求分析(1)实验目的设计一个能演示集合的并、交、差运算程序。
(2)实验任务1)采用顺序表或链表等数据结构。
2)集合的元素限定为数字和小写英文字母。
(3)需求分析:输入形式为:外部输入字符串;输入值限定范围为:数字和小写英文字母;输出形式为:字符集;程序功能:计算两个集合的交、并、差以及重新输入集合功能;二、概要设计:(1)抽象数据类型定义:线性表(2)主程序流程:调用主菜单函数初始化两个线性表作为集合给两个集合输入数据输出集合数据元素信息另初始化两个线性表创建选择功能菜单界面通过不同选项调用不同功能函数在每个功能函数里面加结束选择功能,实现循环调用功能菜单计算完毕退出程序;(3)模块关系:主菜单差运算并运算交运算新建集合结束/返回结束三、详细设计抽象数据类型定义:typedef struct{ElemType *elem;int length;int listsize;}SqList;存储结构:顺序表;模块1-在顺序表的逻辑为i的位置插入新元素e的函数;算法如下:/**在顺序表的逻辑为i的位置插入新元素e的函数**/Status ListInsert_Sq(SqList &L,int i,ElemType e){ElemType *newbase,*p,*q;if(i < 1 || i > L.length + 1) return 0; //i的合法值为(1 <= i <= L.length_Sq(L) + 1)if(L.length >= L.listsize){ //当前储存空间已满,增加分配newbase = (ElemType *)realloc(L.elem,(L.listsize + LISTINCREMENT) * sizeof(ElemType));if(!newbase) exit(-1); //储存分配失败L.elem = newbase; //新基址L.listsize += LISTINCREMENT; //增加储存容量}q = &(L.elem[i - 1]); //q为插入位置for(p = &(L.elem[L.length - 1]); p >= q; --p)(p + 1) = p; //插入位置及之后的元素往右移q = e; //插入e++L.length; //表长加1return 1;}模块二在顺序线性表L中查找第1个与e满足compare()的元素位序,若找到,则返回其在L中的位序,否则返回0算法如下:/**在顺序线性表L中查找第1个与e满足compare()的元素位序,若找到,则返回其在L中的位序,否则返回0**/int LocateElem_Sq(SqList L,ElemType e,Status(* compare)(ElemType,ElemType)){ElemType *p;int i;i = 1; //i的初值为第1个元素的位序p = L.elem; //p的初值为第1个元素的储存位置while(i <= L.length && !(* compare)(*p++,e))++i; //从表L中的第一个元素开始与e比较,直到找到L中与e相等的元素时返回该元素的位置if(i <= L.length) return i; //若i的大小小于表长,则满足条件返回ielsereturn 0; //否则,i值不满足条件,返回0}模块三集合交运算算法如下:/**求集合的交集的函数**/void Mix_Sq(SqList La,SqList Lb,SqList &Lc){int i;ElemType elem;Lc.length = 0; //将表Lc的长度设为0for(i = 1; i <= La.length; i++){ //依次查看表La的所有元素elem = La.elem[i-1]; //将表La中i位置的元素赋值给elemif(LocateElem_Sq(Lb,elem,Equal)) //在表Lb中查找是否有与elem相等的元素ListInsert_Sq(Lc,Lc.length+1,elem); //将表La与Lb中共同的元素放在Lc中}}模块四集合并运算算法如下:/**求集合的并集的函数**/void Union_Sq(SqList La,SqList Lb,SqList &Lc){int i;ElemType elem;Lc.length=0; //将表Lc的长度初设为0for(i = 0; i < La.length; i++) //先将表La的元素全部复制到表Lc中Lc.elem[Lc.length++]=La.elem[i];for(i = 1; i <= Lb.length; i++){elem = Lb.elem[i-1]; //依次将表Lb的值赋给elemif(!LocateElem_Sq(La,elem,Equal)) //判断表La中是否有与elem相同的值ListInsert_Sq(Lc,Lc.length+1,elem); //若有的话将elem放入表Lc中}}模块五集合的差运算算法如下:/**求集合的差集函数**/void Differ_Sq(SqList La,SqList Lb,SqList &Lc){int i;ElemType elem;Lc.length = 0;for(i = 1; i <= La.length; i++){elem = La.elem[i-1]; //把表La中第i个元素赋值给elem if(!LocateElem_Sq(Lb,elem,Equal)) //判断elem在表Lb中是否有相同的元素ListInsert_Sq(Lc,Lc.length+1,elem); //若有,则把elem放入表Lc中,否则,就不存放}for(i = 1; i <= Lb.length; i++){elem = Lb.elem[i-1]; //把表Lb中第i个元素赋值给elemif(!LocateElem_Sq(La,elem,Equal)) //判断elem在表La中是否有相同的元素ListInsert_Sq(Lc,Lc.length+1,elem); //若有,则把elem放入表Lc中,否则,就不存放}}四、调试分析问题分析及解决:首先,在编写程序时没有设置线性表的初始长度,导致集合元素输入错误;然后通过#define LIST_INIT_SIZE 100和#define LISTINCREMENT 10解决;时空分析:int LocateElem_Sq(SqList L,ElemType e,Status(* compare)(ElemType,ElemType))时间复杂度为O(n);Status ListInsert_Sq(SqList &L,int i,ElemType e) 时间复杂度为O(n);void Union_Sq(SqList La,SqList Lb,SqList &Lc) 时间复杂度为O(m*n);void Mix_Sq(SqList La,SqList Lb,SqList &Lc) 时间复杂度为O(m*n);void Differ_Sq(SqList La,SqList Lb,SqList &Lc) 时间复杂度为O(2*m*n);改进设想:当同时求两个以上的结合间的运算是需要先进性两个集合间的运算,然后在于另外的集合进行运算;若要同事进行多个集合的运算需要建立多个顺序表;经验体会:顺序表使用起来比较简单,但长度不可随意变化,适用于大量访问元素,而不适用于大量增添和删除元素;在内存中存储地址连续;五、使用说明第一步:点击运行按钮;第二步: 根据提示输入集合A(可以连续输入,只限输入小写字母和数字);第三步:程序自动显示输入结果;第四步:输入集合B(同第二步);第五步:跳出主菜单界面;第六步:根据选项输入对应运算项的数字序号;第七步:显示运算结果,并可继续进行选择运算还是退出;第八步:若继续运算则返回主菜单,否则退出;第九步:循环第六、七、八步,直至选择退出;六、测试结果输入界面:并运算结果:交运算结果:差运算结果:重新建立集合并运算:七、附录#include<stdio.h>#include<stdlib.h>#define LIST_INIT_SIZE 100//初始表空间大小#define LISTINCREMENT 10//表长增量typedef int Status; /**Status是函数类型**/typedef char ElemType;/*ElemType类型根据实际情况而定,这里假设为char*/ typedef struct{ElemType *elem; /**储存空间基地址**/int length; /**当前长度**/int listsize;/**当前分配的储存容量(以sizeof(Elemtype)为单位)**/}SqList;SqList La,Lb,Lc,Ld;/**定义全局变量**//**构造一个空的线性表L**/Status InitList_Sq(SqList &L){L.elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));if(!L.elem) exit(-1); /**储存分配失败**/L.length = 0;L.listsize = LIST_INIT_SIZE;/**初始储存容量**/return 1;}/**在顺序表的逻辑为i的位置插入新元素e的函数**/Status ListInsert_Sq(SqList &L,int i,ElemType e){ElemType *newbase,*p,*q;if(i < 1 || i > L.length + 1)return 0;if(L.length >= L.listsize)//当前储存空间已满,增加分配{newbase=(ElemType*)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));if(!newbase) exit(-1);//储存分配失败L.elem = newbase;L.listsize += LISTINCREMENT;//增加储存容量}q = &(L.elem[i - 1]);//q为插入位置for(p = &(L.elem[L.length - 1]); p >= q; --p)*(p + 1) = *p;//插入位置及之后的元素往右移*q = e;//插入e++L.length;return 1;}/**创建一个线性表,输入数据**/void CreateList_Sq(SqList &L){ElemType ch='\0';int inlist =0,j;while((ch) != '\n'){scanf("%c",&ch);//输入数据for(j = 0; j < L.length; j++)if(ch == L.elem[j])//判断表L中是否有与ch相等的元素{inlist = 1; //若有,则inlist置1break; //跳出本轮循环}elseinlist =0; //否则inlist为0if(!inlist && ch != '\n')//若inlist为0且ch不为”\n”ListInsert_Sq(L,L.length+1,ch);//则将ch存入表L中}}/*判断两元素是否相等,若相等则返回1;否则返回0*/Status Equal(ElemType a,ElemType b){if(a == b)return 1;//相等,返回1elsereturn 0;//否则,返回0}/*在顺序线性表L中查找第1个与e满足compare()的元素位序,若找到,则返回其在L中的位序,否则返回0*/int LocateElem_Sq(SqList L,ElemType e,Status(* compare)(ElemType,ElemType)) {ElemType *p;int i;i = 1;p = L.elem;//p的初值为第1个元素的储存位置while(i <= L.length && !(* compare)(*p++,e))//循环查找表L找出其中与e相等的元素的位置++i;if(i <= L.length)//若i小于表长return i;//则i满足条件,返回i的值elsereturn 0;//否则返回0}/*销毁线性表的函数*/Status Clear_Sq(SqList &L){ElemType elem;free(L.elem);L.elem = NULL;return 1;}/*打印顺序表函数*/void Print_Sq(SqList L){int i;for(i = 0; i < L.length; i++)printf("%2c",L.elem[i]);//通过for循环将表元素全部输出if(L.length == 0) printf("空集");//若表长为0,则输出空表printf("\n\t\t\t此集合中的个数n = %d\n\n",L.length);}/*求集合的并集的函数*/void Union_Sq(SqList La,SqList Lb,SqList &Lc){int i;ElemType elem;Lc.length=0; //将表Lc的长度初设为0for(i = 0; i < La.length; i++) //先将表La的元素全部复制到表Lc中Lc.elem[Lc.length++]=La.elem[i];for(i = 1; i <= Lb.length; i++){elem = Lb.elem[i-1]; //依次将表Lb的值赋给elemif(!LocateElem_Sq(La,elem,Equal)) //判断表La中是否有与elem 相同的值ListInsert_Sq(Lc,Lc.length+1,elem); //若有的话将elem放入表Lc中}}/*求集合的交集的函数*/void Mix_Sq(SqList La,SqList Lb,SqList &Lc){int i;ElemType elem;Lc.length = 0; //将表Lc的长度设为0for(i = 1; i <= La.length; i++){ //依次查看表La的所有元素elem = La.elem[i-1]; //将表La中i位置的元素赋值给elemif(LocateElem_Sq(Lb,elem,Equal)) //在表La中查找是否有与elem相等的元素ListInsert_Sq(Lc,Lc.length+1,elem); //将表La与Lb中共同的元素放在Lc 中}}/*求集合的差集函数*/void Differ_Sq(SqList La,SqList Lb,SqList &Lc){int i;ElemType elem;Lc.length = 0;for(i = 1; i <= La.length; i++){elem = La.elem[i-1]; //把表La中第i个元素赋值给elemif(!LocateElem_Sq(Lb,elem,Equal)) //判断elem在表Lb中是否有相同的元素ListInsert_Sq(Lc,Lc.length+1,elem);//若有,则把elem放入表Lc中,否则,就不存放}for(i = 1; i <= Lb.length; i++){elem = Lb.elem[i-1]; //把表Lb中第i个元素赋值给elemif(!LocateElem_Sq(La,elem,Equal)) //判断elem在表La中是否有相同的元素ListInsert_Sq(Lc,Lc.length+1,elem); //若有,则把elem放入表Lc中,否则,就不存放}}void Index_Sq(){//主菜单函数char s;int l=1;InitList_Sq(La);//初始化表Laprintf("\n\t\t 请输入集合A:");CreateList_Sq(La);//创建表Laprintf("\t\t\t集合A为");Print_Sq(La);printf("\n\n");InitList_Sq(Lb);//初始化表Lbprintf("\t\t 请输入集合B:");CreateList_Sq(Lb);//创建表Lbprintf("\t\t\t集合B为");Print_Sq(Lb);printf("\n\n");InitList_Sq(Lc);//初始化表LcInitList_Sq(Ld);//初始化表Ldwhile(l){printf("\t\t ******* 请输入您的操作选项1、2、3、4. ****** \n\n");printf("\t\t 1、进行集合的并运算\n");printf("\t\t 2、进行集合的交运算\n");printf("\t\t 3、进行集合的差运算\n");printf("\t\t 4、重新建立两个集合\n");printf("\t\t\t");scanf("%c",&s);switch(s){case '1' : system("cls");Union_Sq(La,Lb,Lc);//调用集合的并运算函数printf("\t\t\t集合A与集合B的并集为:");print_Sq(Lc);printf("\n");break;case '2' :system("cls");Mix_Sq(La,Lb,Lc);//调用集合的交集运算函数printf("\t\t\t集合A与集合B的交集为:");print_Sq(Lc);printf("\n");break;case '3' : system("cls");Differ_Sq(La,Lb,Lc);//调用集合的差集运算函数printf("\t\t\t集合A与集合B的差集为:");print_Sq(Lc);printf("\n");break;case '4' :system("cls");Clear_Sq(La);//销毁表LaClear_Sq(Lb);//销毁表LbClear_Sq(Lc);//销毁表LcClear_Sq(Ld);//销毁表Ldgetchar();Index_Sq();//递归调用此函数break;default : printf("\t\t\t#\tenter data error!\n");printf("\n");}printf("\t\t 继续计算请输入1,停止计算请输入0 \n");printf("\t\t\t");scanf("%d",&l);getchar();system("cls");}printf("\n\t\t**************** 谢谢使用!*****************\n");}int main(){printf("\t\t************* 欢迎使用集合操作运算器************\n");Index_Sq();//调用主菜单函数return 0;}。