C 语言用链表实现集合交并差,集合交差并三种操作的C实现

这段时间一直在看C++相关的数据结构,感觉STL库的出现确实给C++实现一些基本的数据结构更加的方便,特别是map、list、set、vector的灵活运用能实现很多强大的数据结构,记得在一本书中曾经读到过“C++中算法的重要性没有C语言中那么明显,而是设计方法的问题”这句话的正确性有待于进一步的考察,但是面向对象中的更多的是依靠继承多态性实现多对象编程,而在C语言中更多的事依靠算法和数据结构。花了一晚上采用C语言实现了一个简单的集合操作,支持集合的创建,元素的查询,删除,支持集合的交集、差集、并集计算。

首先说明一下集合的ADT,肯定有包括基本的创建、删除操作。以及某一个元素的插入和删除操作。集合的一个重要特征就是元素的不重复性。这种方式我在实现的过程中通过链表管理一个集合,按照元素的大小进行排列,之所以排列主要是为了方便删除、查找元素的操作。实质上集合对元素的顺序是没有要求的。

集合的交集:是指两个集合元素相同的部分构成的集合。

集合的差集:是指其中一个集合中除去另一个集合相同元素以后剩余的元素构成的集合。

集合的并集:是指两个集合的所有元素构成的集合。

其中需要注意的就是集合的元素是不能重复的,本来我打算采用二叉查找树的方式实现,因为这种树型结构便于快速的查询,但是我采用元素的升序排序就能避免集合中漫无目的的查询操作。毕竟实现二叉查找树也增加了一个指针成员,而且还需要大量的操作。

简要的说明一下我的过程:

基本的集合结构体:本文引用地址:http://www.eepw.com.cn/article/201612/324526.htm

typedef struct linknode

{

struct linknode *next;

int value;

}Node_t, *Node_handle_t;

typedef struct set

{

unsigned int size;

Node_handle_t head;

}Set;

集合的创建,该函数的实现是集合实现的最复杂的一个函数,之所以这么复杂是因为很多的操作都是基于该函数完成的,当然也可以采用更精细的函数来实现,我开始的想法是将元素插入和创建操作合并,都基于一个函数进行操作,但是写完以后发现函数太长,而且比较烂,不够必将还是完成了一些基本的操作。采用了升序存储的方式,主要是为了后续的查找操作,注意链表的更新操作。

bool create_set(Set **sets, int data)

{

Set * temp = (Set *)malloc(sizeof(Set)/sizeof(char));

Node_t *node = NULL;

Node_t *head = NULL;

if(*sets == NULL)

{

temp->size = 0;

temp->head = NULL;

*sets = temp;

node = (Node_t *)malloc(sizeof(Node_t)/sizeof(char));

if(node != NULL)

{

node->next = NULL;

node->value = data;

/*更新集合指针*/

temp->head = node;

temp->size ++;

*sets = temp;

temp = NULL;

return true;

}

}

else/*已经存在部分集合*/

{

/******************************

采用顺序存储的方式插入新的元素

首先查找是否存在值,有不做任何操作

不存在,则按值大小找到合适的位置

******************************/

/*遍历*/

if((*sets)->head != NULL)

{

/*更新表头*/

if((*sets)->head->value > data)

{

node = (Node_t *)malloc(sizeof(Node_t)/sizeof(char));

if(node == NULL)

return false;

node->next = (*sets)->head;

node->value = data;

(*sets)->head = node;

(*sets)->size ++;

return true;

}

else if((*sets)->head->value == data)

{

return true;

}

/*从下一个节点开始*/

head = (*sets)->head;

node = head;

while(head->next != NULL)

{

/*已经存在*/

if(head->next->value == data)

{

return true;

}

/*找到合适的位置,并插入*/

else if(head->next->value > data)

{

node = (Node_t *)malloc(sizeof(Node_t)/sizeof(char));

if(node == NULL)

return false;

node->value = data;

node->next = head->next;

head->next = node;

(*sets)->size ++;

return true;

}

else

{

head = head->next;

}

}

/*说明以上不存在该值*/

node = (Node_t *)malloc(sizeof(Node_t)/sizeof(char));

if(node == NULL)

return false;

node->value = data;

node->next = NULL;

head->next = node;

(*sets)->size ++;

return true;

}

else

{

node = (Node_t *)malloc(sizeof(Node_t)/sizeof(char));

if(node == NULL)

return false;

node->value = data;

node->next = NULL;

(*sets)->head = node;

(*sets)->size ++;

return true;

}

}

return false;

}

查找、删除元素操作,充分利用了前面的升序存储关系。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值