題目描述:求兩個鏈表入隊並集
將兩個有序鏈表合併爲一個有序鏈表,合併的鏈表無重複元素,其中元素爲原兩個鏈表的並集
示例:
輸入:1->2->4, 1->3->4
輸出:1->2->3->4
思路分析:對list2遍歷,並同時對每個節點數據判斷在list1中是否存在,如果不存在,則將該數據有序插入到list1中,不然則繼續遍歷,直到list2遍歷完,則求並集結束。
/**
* Definition for singly-linked list.
* struct ListNode {
* int data;
* struct ListNode next;
* };
*/
ListNode*combineLinkList(ListNode*list1,ListNode* list2)
{
if (list1 == NULL || list2 == NULL)//如果一個爲NULL,直接返回另一個鏈表
{
return list1 == NULL ? list2 : list1;
}
ListNode*cur = list1;
while (list2!=NULL&&cur!=NULL)
{
if (!Locate_exist_Elem(cur, list2->data))//判斷list2->data在list1中是否存在
{
SortInsertList(cur,list2->data);//插入該元素
}
list2 = list2->next;
}
return list1;
}
Locate_exist_Elem()和SortInsertList()函數的實現代碼可以查看我的github:List.c
類似算法還有求兩個鏈表的交、差集。思想差不多,都可以通過鏈表的基本操作實現。
LeetCode題目描述:合併兩個有序鏈表**
將兩個有序鏈表合併爲一個新的有序鏈表並返回。新鏈表是通過拼接給定的兩個鏈表的所有節點組成的。
示例:
輸入:1->2->4, 1->3->4
輸出:1->1->2->3->4->4
來源:力扣(LeetCode)
思路分析:用三個指針分別記錄新合併鏈表的尾結點和未合併鏈表的頭結點,每次在未合併鏈表中選擇數據較小的節點插入新合併鏈表的尾部,然後將指針分別再次指向新鏈表的尾結點和未合併鏈表的頭結點。(在此過程中兩個爲合併鏈表的節點不能爲空,爲空說明一個鏈表已被完全合併,那麼退出)
最後,將另一個不爲空的鏈表鏈接在新鏈表的尾部即可
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
struct ListNode*cur=(struct ListNode*)malloc(sizeof(struct ListNode));//創建新鏈表頭結點
cur->next=NULL;
struct ListNode*new=cur;
while(l1!=NULL && l2!=NULL)
{
if((l1->val)<(l2->val))
{
cur->next=l1;
l1=l1->next;
}
else
{
cur->next=l2;
l2=l2->next;
}
cur=cur->next;
}
if(l1!=NULL)
{
cur->next=l1;
}
if(l2!=NULL)
{
cur->next=l2;
}
cur=new;
new=new->next;
free(cur);//釋放頭結點
return new;
}