鏈表常見算法題一:實現兩個鏈表的並集、合併兩個有序鏈表

題目描述:求兩個鏈表入隊並集

將兩個有序鏈表合併爲一個有序鏈表,合併的鏈表無重複元素,其中元素爲原兩個鏈表的並集
示例:
輸入: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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章