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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM