(C语言)链表的实现集合的相关操作

集合的特征:确定性/ 互异性/ 无序性。

常见的操作:1、查找集合中是否包含这个数据元素:Contains();

2、添加一个新成员数据,集合中不能存在这个元素。AddMember();

3、删除指定元素, 找到这个元素, 删除;如果没找到,则提示没找到,返回0(表示false)。Delete();

4、合并两个集合,不能有相同的元素。

5、求交集,找相同的元素。

6、求差集,例如:A{1, 2, 3}。B{2,4}。那么A相对B的差集就是{1,3}。

参考代码:

#include<stdio.h>
#include<stdlib.h>

// 利用单链表进行集合操作 
typedef int  elementType;
typedef struct node{
	elementType data;
	struct node *next;
}SetNode; // 集合节点

typedef struct{
	SetNode *first, *last;
}LinkSet;// 链式集合

//判断是否含有指定元素
bool Contains(LinkSet &ls, elementType x){
//	if(ls.first == ls.last){// 判断是否是空表 
//		return 0;
//	}
		// 移动指针 不需要创建的 
		SetNode *p = ls.first->next; 
		while(p != NULL && p->data < x){
			p = p->next;
		} 
		if(p != NULL && p->data == x){
			return 1;
		}
		else return 0;
} 

//链表的插入和删除必然需要找到前驱节点 

//增加一个新成员
int addMember(LinkSet &ls, elementType x){
	//集合中不能有重复元素
	SetNode *p = ls.first->next;
	
	//前驱节点记录下来 
	SetNode *pre = ls.first;
	
	while(p != NULL && p->data < x){
		pre = p; 
		p = p->next;
	} 
	if(p != NULL && p->data == x) return 0;// 存在插入失败 
		
		// 创建一个新节点 
	SetNode *s = (SetNode *)malloc(sizeof(SetNode));
		
	s->data = x;
	s->next = p;// p后面的接在新节点s后面 
	pre->next = s; 
		
		// 假如是插在末尾 
	if(!p) ls.last = s;
		
	return 1; 
} 

// 删除指定节点
int deleteMember(LinkSet &ls, elementType x){
	// 搜索节点 
	SetNode *p = ls.first->next, *pre = ls.first;
	while(p != NULL && p->data < x){
		pre = p; 
		p = p->next;
	} 
	if(p != NULL & p->data == x){
		pre->next = p->next;
		if(p == ls.last) ls.last = pre;
		
		free(p);
		return 1;
	}
	else
		return 0; // 其他情况视为删除失败 :空集合 以及 不包含该元素 
} 

// 合并两个集合 : 相同元素删除
void merge(LinkSet &lsA, LinkSet &lsB, LinkSet &lsC){
	SetNode *pa = lsA.first->next, *pb = lsB.first->next;
	
	SetNode *pc = lsC.first, *p;// 新的存储空间,存储两个链表的结果

	while(pa != NULL && pb != NULL){
		if(pa->data < pb->data){	
			//理解为创建pc->next的这个节点 
			pc->next = (SetNode *)malloc(sizeof(SetNode));
			
			pc->next->data = pa->data;// 放入到pc中去
		
			pa = pa->next; 
		}
		
		else if(pa->data > pb->data){
			pc->next = (SetNode *)malloc(sizeof(SetNode));
			
			pc->next->data = pb->data;// 放入到pc中去
				
			pb = pb->next; 
		}
		else if(pa->data == pb->data){// 重复元素随意放一个, 然后一起移动 
			pc->next = (SetNode *)malloc(sizeof(SetNode));
			
			pc->next->data = pa->data;
			
			pa = pa->next;
			pb = pb->next; 
		}
		// 不断的存储数据 ,pc的位置也要往后移动 
		pc = pc->next;
	} 
	
	// 可能还有集合没有做完
	p = (pa != NULL ) ? pa : pb; 
	
	while(p != NULL){
		pc->next = (SetNode *)malloc(sizeof(SetNode));
			
		pc->next->data = p->data;// 放入到pc中去
			
		pc = pc->next;
		
		p = p->next; 
	} 
	
	// 对于一个链表来说, 一定要收尾
	pc->next = NULL;
	lsC.last = pc; 
} 

void print(LinkSet &ls){
	SetNode *p = ls.first;
	while(p->next != NULL){
		printf("%d ", p->next->data);
		p = p->next;
	}
	
	printf("\n");
}
int main(){
	
	LinkSet la, lb, lc;
	
	// 加一个头结点 
	la.first = (SetNode *)malloc(sizeof(SetNode)); 
	la.first->next =  NULL;
	
	lb.first = (SetNode *)malloc(sizeof(SetNode)); 
	lb.first->next =  NULL;
	
	lc.first = (SetNode *)malloc(sizeof(SetNode)); 
	lc.first->next =  NULL;
	
	addMember(la, 1);
	addMember(la, 2);
	addMember(la, 3);
	addMember(la, 4);
	addMember(la, 5);
	
	// 打印 
	print(la);
	
	printf("%d\n", Contains(la, 5));
	
	printf("%d\n", Contains(la, 6));
	
	
	addMember(lb, 1);
	addMember(lb, 2);
	addMember(lb, 3);
	addMember(lb, 7);
	addMember(lb, 8);
	
	print(lb);
	
	deleteMember(lb, 3);
	
	print(lb);
	
	merge(la, lb, lc);

    print(lc);	

	return 0;	 
}


以上就是这篇的主要内容,欢迎您提出意见。谢谢!让我们共同进步!

猜你喜欢

转载自blog.csdn.net/kobe_jr/article/details/80543611