集合的链接存储结构和操作实现

       集合的顺序存储结构是通过数组实现的,二集合的链接存储结构是通过存储节点之间的链接实现的,链接形成的结果称为链接表,通常使用单链表;当集合利用单链表存储时,集合中每个元素对应单链表中的一个结点,把这个元素存储到相应结点的值域中。由于集合中元素是无序的,所以在单链表中可以按任何次序链接。区别于数组结构,当向表示集合的单链表中插入一个元素结点时,为操作简单,把它插入到表头。即插入到 第一个节点之前使它成为新的表头节点,而原来的表头节点称为第2个结点,此时只改变新插入节点的指针域,使其指向原来的表头结点,在修改表头指针,使其指向新插入的节点,完成插入操作。当从链表中删除一个结点时,就是把该结点的指针域得值(即后一结点的地址)赋值给其前一个结点的指针域即可,若本身为表头节点,则应该把该结点的指针域的值赋值给表头指针。

//表示集合单链表的结构体
struct SNode{
	ElemType date;//存储元素值的结点值域 
	SNode* nest;//为存储下一个结点地址的指针域 
}; 

       由于单链表中的结点通常是靠动态分配产生的,不需要事先分配存储空间,所以存储一个单链表只需要存储他的表头指针即可。有表头指针就能够访问该单链表。假定表头指针用HT表示,则HT应定义为

SNode* HT;//集合单链表的表头指针
HT----->[a1][-]--->[a2][-]--->...---->[ai][-]--->[a1+1][-]--->..--->[an][^]

 1:初始化集合为空

void InitSet(SNode*& HT){
	HT=NULL:
}

2:清除集合中所有元素并释放占有的动态存储空间:

void ClearSet(SNode*& HT){
	SNode *p=HT,*q;//p指向HT单链表 
	while(p!=NULL){//回收HT集合中的每个结点 
		q=p->next;//q指向p的后继结点;
		delete p;
		p=q; 
	}
	HT=NULL:
}

3:求出集合中元素个数:

int LenthSet(SNode* HT){
	int n=0;
	while(HT!=NULL){
		n++;
		HT=HT->next;
	}
	return n;
}

4:判断集合是否为空

bool EmptySet(SBode* HT){
	return HT=NULL;
}

5:判断一个元素是否属于集合

bool InSet(SNode* HT,ElemType item){
	while(HT!=NULL){
		if(HT->date==item)return true;
		else HT=HT->next; 
	}
	return false;
}

6:输出集合中所有元素

void OutputSet(SNode* HT){
	while(HT!=NULL){
		cout<<HT->date<<" ";
		HT=HT->next;
	}
	cout<<endl;
}

7:从集合中查找一个元素

bool FindSet(SNode* HT,ElemType& item){
	while(HT!=NULL){
		if(HT->date==item)break;
		else HT=HT->next;
	}
	if(HT!=NUll){
		item=HT->next;
		return true;
	}else return false;
}

8:修改集合中的一个指定元素

bool ModifySet(SNode* HT,const ElemType& item){
	while(HT!=NULL){
		if(Ht->date==item)break;
		else HT=HT->next;
	}
	if(HT!=NULL){
		HT->date=item;
		return true;
	}else return false;
}

9:向集合插入一个元素

bool InsertSet(SNode*& HT,ElemType item){
	//建立值为item的新节点
	SNode* tp=new SNode;
	tp->date=item;
	//从单链表中顺序查找是否存在值为item的结点
	SNode* p=HT;
	while(p!=NULL){
		if(p->date==item)break;
		else p=p->next;
	} 
	//若不存在则把新节点插入到表头并返回真,否则不插入返回值。
	if(p==NULL){
		tp->next=HT;
		HT=tp;
		return true;
	}else return false;
}

10:从集合中删除一个元素

bool DeleteSet(SNode*& HT,ElemType& item){
	//从单链表中顺序查找是否存在值为item的结点
	SNode *cp=HT,*ap=NULL;
	while(cp!=NULL){
		if(cp->date==item)break;
		else {
			ap=cp;
			cp=cp->next;
		}
	} 
	//若不存在则返回假,表示删除失败
	if(cp==NULL)return false;
	//由item带回待测删除节点cp的完整值,若不需要带回可设item为值参 
	item=cp->date;
	//从单链表中删除已找到的cp结点,对是否有表头应做不同处理; 
	if(ap==NULL)HT=cp->next;
	else ap->next=cp->next;
	delete cp;
	return true; 
}

11:求两个集合的并集

void UnionSet(SNode* HT1, SNode* HT2, SNode*& HT){
	//置并集的表头指针HT为空
	HT=NULL;
	//把HT1集合单链表复制到HT集合单链表中
	SNode* p=HT1;
	while(p!=NULL){
		SNode* newp=new SNode;
		newp->date=p->date;
		newp->next=p->next;
		p=p->next;
	}
	//把HT2集合单链表中的每个元素插入到HT集合单链表中
	p=HT2;
	while(p!=NULL){
		InsertSet(HT,p->date);
		p=p->next;
	} 
}

12:求两个集合的交集

void InterseSet(SNode* HT1, SNode*HT2, SNode*& HT){
	HT=NULL;
	ElemType x;
	SNode* p=HT2;
	while(p!=NULL){
		x=p->date;
		bool b=FindSet(HT1,x);
		if(b) InsertSet(HT,x);
		p=p->next;
	}
}

13:求两个集合的差集

void DifferenceSet(SNode* HT1, SNode* HT2, SNode*& HT){
	HT=NULL;
	ElemType x;
	SNode* p=HT1;
	while(p!=NULL){
		x=p->date;
		bool b=FindSet(HT2,x);
		if(!b)InsertSet(HT,x);
		p=p->next;
	}
}

指针比较难理解一直不是太会,在上面的程序中有一个特殊的符号*&这个符号的含义是SNode * & HT ; 中SNode * 是个整体,表示变量类型是SNode类指针, &HT中的&表明引用实参,即代表实参的一个别名。SNode * &HT ; 中SNode * 是个整体,表示变量类型是SNode类指针, &HT中的&表明引用实参,即代表实参的一个别名。 操作引用变量就相当于操作实参变量;

慢慢理解,继续努力;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值