码迷,mamicode.com
首页 > 其他好文 > 详细

求链表的并集和交集

时间:2015-05-12 10:58:08      阅读:120      评论:0      收藏:0      [点我收藏+]

标签:

给定2个链表,求这2个链表的并集(链表)和交集(链表)。不要求并集(链表)和交集(链表)中的元素有序。

如,输入:

List1: 10->15->4->20

List2: 8->4->2->10

输出:

交集(链表):4->10

并集(链表):2->8->20->4->15->10

方法一(简单、直观的方法):

        下面是得到2个链表的并集和交集的简单算法。

        InterSection(list1,list2): 初始化结果链表为空,遍历链表1,在链表2中查找它的每一元素,如果链表2中也有这个元素,则将该元素插入到结果链表中。

        Union(list1,list2): 初始化结果链表为空,将链表1中的所有元素都插入到结果链表中。遍历链表2,如果结果链表中没有该元素,则插入,否则跳过该元素。

 

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.   
  4. /*Link list node*/  
  5. struct node  
  6. {  
  7.     int data;  
  8.     struct node* next;  
  9. };  
  10.   
  11. /* A utility function to insert a node at the begining of a linked list */  
  12. void push(struct node **head_ref, int new_data);  
  13.   
  14. /* A utility function to chec if given data is present in a list */  
  15. bool isPresent(struct node *head, int data);  
  16.   
  17. /* Function to get union of two linked lists head1 and head2*/  
  18. struct node *getUnion(struct node *head1, struct node *head2)  
  19. {  
  20.     struct node *result = NULL;  
  21.     struct node *t1 = head1, *t2 = head2;  
  22.   
  23.     //Insert all elements of list1 to result list  
  24.     while(t1 != NULL)  
  25.     {  
  26.         push(&result, t1->data);  
  27.         t1 = t1->next;  
  28.     }  
  29.   
  30.     //Insert those elements of list2 which are not present in result list  
  31.     while(t2 != NULL)  
  32.     {  
  33.         if(!isPresent(result, t2->data))  
  34.             push(&result, t2->data);  
  35.         t2 = t2->next;  
  36.     }  
  37.   
  38.     return result;  
  39. }  
  40.   
  41. /* Function to get intersection of two linked lists head1 and head2 */  
  42. struct node *getIntersection(struct node *head1, struct node *head2)  
  43. {  
  44.     struct node *result = NULL;   
  45.     struct node *t1 = head1;  
  46.   
  47.     //Traverse list1 and search each element of it in list2. If the element  
  48.     //is present in list2, then insert the element to result  
  49.     while( t1 != NULL )  
  50.     {  
  51.         if(isPresent(head2, t1->data))  
  52.             push(&result, t1->data);  
  53.         t1 = t1->next;  
  54.     }  
  55.   
  56.     return result;  
  57. }  
  58.   
  59. /* A utility function to insert a node at the begining of a linked list */  
  60. void push(struct node**head_ref, int new_data)  
  61. {  
  62.     /*allocate node*/  
  63.     struct node* new_node = (struct node*)malloc(sizeof(struct node));  
  64.   
  65.     /* put in the data */  
  66.     new_node->data = new_data;  
  67.   
  68.     /*link the old list off the new node*/  
  69.     new_node->next = (*head_ref);  
  70.   
  71.     /* move the head to point to the new node*/  
  72.     (*head_ref) = new_node;  
  73. }  
  74.   
  75. /*A utility function fto print a linked list*/  
  76. void printList(struct node *node)  
  77. {  
  78.     while( node != NULL )  
  79.     {  
  80.         printf("%d ", node->data);  
  81.         node = node->next;  
  82.     }  
  83. }  
  84.   
  85. /*A utility function that returns true  if data is present in  
  86.   linked list else reurn false */  
  87. bool isPresent(struct node *head, int data)  
  88. {  
  89.     struct node *t = head;  
  90.     while(t != NULL)  
  91.     {  
  92.         if( t->data == data )  
  93.             return 1;  
  94.         t = t->next;  
  95.     }  
  96.     return 0;  
  97. }  
  98.   
  99. /* Drier program to test above function*/  
  100. int main()  
  101. {  
  102.     /* Start with the empty list */  
  103.     struct node* head1 = NULL;  
  104.     struct node* head2 = NULL;  
  105.     struct node* intersecn = NULL;  
  106.     struct node* unin = NULL;  
  107.   
  108.     /*create a linked lits 10->15->5->20 */  
  109.     push (&head1, 20);  
  110.     push (&head1, 4);  
  111.     push (&head1, 15);  
  112.     push (&head1, 10);  
  113.   
  114.     /*create a linked lits 8->4->2->10 */  
  115.     push (&head2, 10);  
  116.     push (&head2, 2);  
  117.     push (&head2, 4);  
  118.     push (&head2, 8);  
  119.   
  120.     intersecn = getIntersection (head1, head2);  
  121.     unin = getUnion (head1, head2);  
  122.   
  123.     printf ("\n First list is \n");  
  124.     printList (head1);  
  125.   
  126.     printf ("\n Second list is \n");  
  127.     printList (head2);  
  128.   
  129.     printf ("\n Intersection list is \n");  
  130.     printList (intersecn);  
  131.   
  132.     printf ("\n Union list is \n");  
  133.     printList (unin);  
  134.   
  135.     printf("\n");   
  136.     return 0;  
  137. }  

 

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

 

 

方法2(使用归并排序):

        使用这个方法,求2个链表的并集和交集的操作非常相似。首先,将对2个链表进行排序,然后遍历2个链表,得到2个了表的交集和并集。

下面是具体实现步骤:

  1. 用归并排序对第1个链表进行排序,这个操作的时间复杂度为O(mLogm).[点击这里查看详细]

  2. 用归并排序堆第2个链表进行排序,这个操作的时间复杂度为O(nLogn).

  3. 线性遍历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表的实现技术,一般情况下,这个方法都比上面两种要好。

原文地址:http://www.geeksforgeeks.org/archives/18615?utm_source=rss&utm_medium=rss&utm_campaign=union-and-intersection-of-two-linked-lists

求链表的并集和交集

标签:

原文地址:http://www.cnblogs.com/bendantuohai/p/4496559.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!