用单链表实现集合的操作
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
pre = p;
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>::Subtraction(Node<T> *A,Node<T> *B){
q = q->next;}
else{
pre->next = p->next;
p = pre->next;
q = q->next;
}
}
}
template<class T>
void LinkList<T>::PrintList(){ //遍历输出所有元素
Node<T> *p;
p=first->next;
《数据结构》课设计报告 2012—2013 学年第一学期
课程名称
数据结构
设计题目 用单链表实现集合的操作
专业班级
姓名
学号
指导教师
一.实验目的
掌握单链表的算法,插入、删除、遍历等。
二.实验内容
(1)对集合中的元素用有序单链表进行存储; (2) 实现交、并、差等基本运算时,Hale Waihona Puke Baidu能另外申请存储空间; (3)充分利用单链表的有序性,要求算法有较好的时间性能。
cin>>m;
}while(m<1||m>5);
return m;
}
int a[]={5,4,3,2,1},b[]={6,4,2};
int n = 5,m = 3;
LinkList<int> SL(a,n); LinkList<int> sl(b,m);
LinkList<int> s(a,n); LinkList<int> S(b,m);
代码:
#include<iostream> using namespace std; template<class T> struct Node{
T data; Node<T> *next; }; template <class T> class LinkList{ public:
LinkList(T a[],int n);
Node<T> *pa,*pb; pa=A->next; pb=B->next; while(pa!=NULL && pb!=NULL){
if(pa->data==pb->data){ pa=pa->next;
pb=pb->next;
}
else
break;
}
if(pa==NULL && pb==NULL)
//判断是否相等 //求交集
//求并集 //求差集
void PrintList();
void Show(int i);
private:
Node<T> *first;
};
template<class T>
LinkList<T>::LinkList(T a[],int n){
Node<T> *s;
first = new Node<T>;
1、若 p->data>q->data,说明还未找到,需在表 B 中继续查找; 2、若 p->data<q->data,说明表 B 中无此值,处理表 A 中下一结点; 3、若 p->data=q->data,,说明找到了公共元素。 (3)求集合 A 和 B 的并集,集合 A∪B 中包含所有或属于集合 A 或属于集合 B 的元素。因此,对单链表 B 中的每一个元素 x,在单链表 A 中进行查找,若存在 和 x 不同的元素,则将该结点出入到单链表 A 中。 (4)求集合 A 和 B 的差集。根基集合的运算规则,集合 A-B 中包含所有属于集 合 A 而不属于集合 B 的元素。因此,对单链表 B 中的每个元素 x 在单链表 A 中进 行查找,若存在和 x 相同的结点,则将该结点从链表 A 中删除。 在主函数中,首先建立两个有序单链表表示集合 A 和 B,然后依次调用相应函数 实现集合的判等、交、并和差等运算,并输出运算结果。
LinkList<int> l(a,n); LinkList<int> L(b,m);
static bool bl = true; template<class T> void LinkList<T>::Show(int i){
switch(i){ case 1:{
Node<T> *pa,*pb; pa= s.first; pb= S.first; s.PrintList(); S.PrintList(); while(0){
Node<T> *pre,*p,*q,*pra;
pre = A; pra = B; p = A->next; q = B->next;
while(p!=NULL && q!=NULL){
if(p->data < q->data){
pre = p;
p = p->next;
}
else if(p->data > q->data){
first->next=NULL;
for(int i=0;i<n;i++){
s = new Node<T>;
s->data=a[i];
s->next=first->next;
first->next=s;
}
}
template <class T>
LinkList<T>::~LinkList(){
Node<T> *p,*q;
三.设计与编码
集合是由互不相同的元素构成的一个整体,在集合中,元素之间可以没有 任何关系,所以,集合也可以作为线性表的处理。用单链表实现集合的操作,需 要注意集合中元素的唯一性,即在单链表中不存在值相同的结点。 (1)判断 A 和 B 是否相等。两个集合相等的条件是不仅长度相同,而且各个对 应的元素也相等。由于用单链表表示集合,所以只要同步搜啊秒两个单链表,若 从头至尾每个对应的元素都相等,则表明两个集合相等。 (2)求集合 A 和 B 的交集。根据集合的运算规则,集合 A∩B 中包含所有既属于 集合 A 又属于集合 B 的元素,因此,需要查找单链表 A 和 B 中的相同元素并保留 在单链表 A 中。由于用有序单链表表示集合,因此判断某元素是否在 B 中不需要 遍历表 B,而是从上次搜索到的位置开始,若在搜索过程中,遇到一个其值比该 元素大的结点,便可断定该元素不在单链表中,为此,需要用两个指针 p、q 分 别指向当前被比较的两个结点,会出现以下三种情况:
if(p->data < q->data){
pre->next = p->next;
p = pre->next;}
else if(p->data > q->data){
q = q->next;}
else{
pre = p;
p = p->next;
q = q->next;
}
}
}
template<class T>
//工作指针 p 初始化
while(p != NULL){
cout<<p->data;
p = p->next;
}
cout<<endl;
}
int menu(){
//菜单函数
int m;
do { cout<<"请输入对应数字(1、判断是否相等 2、求交集 3、求并集 4、求差集 5、结
束运行)"<<endl;
//建立有 n 个元素的单链表
~LinkList(); int Ifdeng(Node<T> *A, Node<T> *B); void Interest(Node<T> *A, Node<T> *B); void Sum(Node<T> *A, Node<T> *B); void Subtraction(Node<T> *A, Node<T> *B);
//求并集
void LinkList<T>::Sum(Node<T> *A,Node<T> *B){
Node<T> *pre,*p,*q;
pre = A; p = A->next;
q = B->next;
while(p!=NULL && q!=NULL){
if(p->data < q->data){
return 1;
else
return 0;
}
template<class T>
//交集
void LinkList<T>::Interest(Node<T> *A,Node<T> *B){
Node<T> *pre,*p,*q;
pre = A;p =A ->next;q = B->next;
while(p!=NULL && q!=NULL){
p = first; while(p) {
//工作指针 p 初始化 //释放单链表的每一个结点的存储空间
q = p;
//暂存被释放结点
p = p->next; //工作指针 p 指向被释放结点的下一个结点,使单链表不断开
delete q;
}
}
template<class T> //判断是否相等 int LinkList<T>::Ifdeng(Node<T> *A,Node<T> *B) {
} } void main(){
cout<<"集合 a[]={5,4,3,2,1}"<<endl; cout<<"集合 b[]={3,1}"<<endl;
cout<<endl; while(bl == true){
int i=menu(); SL.Show(i); } }
运行后结果如下:
四.总结与心得
主要利用点链表实现,首先得建立单链表,注意利用单链表的有序性指针 的使用也非常重要,包括头指针的使用注意*的使用,注意指针 p 的初始化,得 建立析构函数释放单链表的每一个结点的存储空间。调试时找出错误逐个找出其 错误,然后研究解决。
通过这次课程设计,我们对 C 语言以及数据结构有了更深刻的了解,增强 了程序的编写能力,巩固了专业知识,对程序的模块化观念也又模糊逐渐变的清 晰了。在程序的运行与调试过程中出现了很多错误,通过反复地复习课本上的相 关知识,不停地修改与调试,我们终于完成了这段程序。在调试过程中,我们认 识到了数据结构的灵活性与严谨性,同一个功能可以由不同的语句来实现,但编 写程序时要特别注意细节方面的问题,因为一个小小的疏忽就能导致整个程序不 能运行。我们也认识到了自己的薄弱之处,如对链表相关知识的欠缺,文件运用 的不熟练,在以后的学习中我们要集中精力、端正态度,争取把知识学得更扎实、 更全面
cout<<"相等"<<endl; } cout<<"不相等"<<endl; } break; case 2:{ Node<T> *p,*q; p = SL.first; q = sl.first; SL.PrintList(); sl.PrintList(); SL.Interest(p,q); SL.PrintList(); cout<<endl; cout<<"已求交集"<<endl;} break; case 3:{ Node<T> *p,*q; p = s.first; q = S.first; s.PrintList(); S.PrintList(); s.Sum(p,q); s.PrintList(); S.PrintList(); cout<<"已求并集"<<endl;} break; case 4:{ Node<T> *p,*q; p = l.first; q = L.first; l.PrintList();L.PrintList(); l.Subtraction(p,q); l.PrintList(); cout<<"已求差集"<<endl;} break; case 5:{ bl = false; } break;