C语言数据结构之求两个集合的交集(链表)



//1:求两集合的交集(链表)。
#include <stdio.h>  
#include <stdlib.h>  
struct node  
{  
    int data;  
    struct node* next;  
}; 
 
void push(struct node **head_ref, int new_data); //添加数据元素声明 


bool isPresent(struct node *head, int data); //判断是否存在函数声明


/* struct node *getUnion(struct node *head1, struct node *head2)//求并集函数
{  
    struct node *result = NULL;  
    struct node *t1 = head1, *t2 = head2;  
    while(t1 != NULL)  
    {  
        push(&result, t1->data);  
        t1 = t1->next;  
    }  
    while(t2 != NULL)  
    {  
        if(!isPresent(result, t2->data))  
            push(&result, t2->data);  
        t2 = t2->next;  
    }  
  
    return result;  
} */ 


struct node *getIntersection(struct node *head1, struct node *head2)  //求交集函数
{  
    struct node *result = NULL;   
    struct node *t1 = head1;  
    while( t1 != NULL )  
    {  
        if(isPresent(head2, t1->data))  
            push(&result, t1->data);  
        t1 = t1->next;  
    }  
  
    return result;  
}  
void push(struct node**head_ref, int new_data)  //添加数据成员函数
{ 
    struct node* new_node = (struct node*)malloc(sizeof(struct node));  
    new_node->data = new_data;  
    new_node->next = (*head_ref);  
    (*head_ref) = new_node;  
}    
void printList(struct node *node)  //输出链表函数
{  
    while( node != NULL )  
    {  
        printf("%d ", node->data);  
        node = node->next;  
    }  
}  
bool isPresent(struct node *head, int data)  //判断是否存在
{  
    struct node *t = head;  
    while(t != NULL)  
    {  
        if( t->data == data )  
            return 1;  
        t = t->next;  
    }  
    return 0;  
}  
int main()  
{  
   struct node* head1 = NULL;  
    struct node* head2 = NULL;  
    struct node* intersecn = NULL;  
    push (&head1, 20);//链表一添加数据元素  
    push (&head1, 4);  
    push (&head1, 15);  
    push (&head1, 10);    
    push (&head2, 10); //链表二添加数据元素 
    push (&head2, 2);  
    push (&head2, 4);  
    push (&head2, 8);  
intersecn = getIntersection (head1, head2);//取交集元素  
printf ("\n 链表一为 \n");  
    printList (head1);  
printf ("\n 链表二为\n");  
    printList (head2);  
printf ("\n 求交集后 \n");  
    printList (intersecn); 
    printf("\n");   
    return 0;  
}


/*时间复杂度:在这个程序中,链表的并和交操作的时间复杂度都是O(mn),m是链表1的元素个数,n是链表2的元素个素。


方法2(使用归并排序):
        使用这个方法,求2个链表的并集和交集的操作非常相似。首先,将对2个链表进行排序,然后遍历2个链表,得到2个了表
的交集和并集。
下面是具体实现步骤:
用归并排序对第1个链表进行排序,这个操作的时间复杂度为O(mLogm).
用归并排序堆第2个链表进行排序,这个操作的时间复杂度为O(nLogn).
线性遍历2个有序的链表,得到2个链表的交集和并集。这个操作的时间复杂度为O(m+n).[这步类似于求有序数组的交集和并集,后
者之前已经实现过,点击这里查看详细]
这个方法的时间复杂度是O(mLogm+ nLogn),优于第一种方法。


方法3(hash法):
Union(list1, list2)
        首先初始化结果链表为NULL,创建一个空的hash表,遍历两个链表,将链表中的元素插入到hash表,插入元素的时候同时
检查hash表中时候是否已经存在该元素,如果hash表中不存在该元素,则同时将该元素插入到结果链表中,如果hash表中
已经存在,则忽略该元素,继续遍历下一个元素。
InterSection(list1, list2)
        首先初始化结果链表为NULL,创建一个空的hash表,遍历list1,将list1中的每一个元素都插入到hash表中。然后遍历
list2,对于list2中的元素,如果已经存在于hash表中,则将该元素插入到结果链表,如果不存在与hash表中,则忽略
该元素,继续遍历下一个元素。
        这个方法的效率取决与hash表的实现技术,一般情况下,这个方法都比上面两种要好。*/

转载于:https://www.cnblogs.com/zhuhengjie/p/5966950.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值