//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表的實現技術,一般情況下,這個方法都比上面兩種要好。*/
