合并两个有序的链表

题目输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。例如输入两个链表分别1,3,5和2,4,6,合并后的链表则是1,2,3,4,5,6.

链表结点定义如下:

typedef struct ListNode
{
	int val;
	struct ListNode *p_next;
}NODE, *PNODE;

拿到这个题目我们就来分析一下:首先分析合并两个链表的过程,我们从头结点开始。假设有两个这样的链表:

                                           

链表1的头结点小于链表2的头结点,因此链表1的头结点将作为合并后的新的头结点,就像下面这样:

                                                  

然后我们继续合并两个链表中剩余的结点,也就是方框中的结点了。剩下的结点分别还是排序的,所以合并这两个链表的步骤和前面是一样的。依旧是比较两个头结点的值,因为链表2的头结点的值小于链表1的头结点的值,所以链表2的头结点将成为剩余链表合并后的新的头结点,我们把它连接在之前确定出来的头结点的后面,如图所示:

                                 

当我们每次得到新的头结点,并连接到新链表的尾部后,剩余的链表依旧是有序的,所以合并的步骤与之前的一样。这是一个典型的递归过程。所以我决定先用递归来实现它。

不过在此之前有一点需要注意的是,当传入的第一个链表为空。,即头结点指针为NULL,我们要把它与链表2合并,显然合并后的结果当然就是链表2了;同理,链表2为空时,合并后的链表为链表1;若两个链表都是空链表,则合并后依旧是一个空链表。既然已经想理清楚了具体的思路和健壮性的考虑,我们可以开始写代码了:

PNODE merge_two_list_recur(PNODE head1, PNODE head2)
{
	PNODE new_head = NULL;

	if (NULL == head1)
		return head2;
	else if (NULL == head2)
		return head1;

	if (head1->val <= head2->val)
	{
		new_head = head1;
		new_head->p_next = merge_two_list_recur(head1->p_next,head2);
	}
	else
	{
		new_head = head2;
		new_head->p_next = merge_two_list_recur(head1, head2->p_next);
	}

	return new_head;
}

最后我们还可以用非递归的方式实现这个算法:

PNODE merge_two_list(PNODE head1, PNODE head2)
{
	PNODE new_head = NULL, tmp = NULL, next = NULL;
	int flag = 0;

	/*if (NULL == head1)
		return head2;
	else if (NULL == head2)
		return head1;
	*/

	while (NULL != head1 && NULL != head2)
	{
		if (head1->val <= head2->val)
		{
			tmp = head1;
			head1 = head1->p_next;
		}
		else
		{
			tmp = head2;
			head2 = head2->p_next;
		}

		if (flag)
		{
			next->p_next = tmp;
			next = next->p_next;
		}
		else			//只进来一次
		{
			new_head = tmp;
			next = new_head;
			flag = 1;
		}
	}

	if (NULL != head1)
	{
		next->p_next = head1;
	}

	else if (NULL != head2)
	{
		next->p_next = head2;
	}

	return new_head;
}

依旧不难,这里就不在赘述了。

时间: 2024-08-27 12:13:21

合并两个有序的链表的相关文章

1.合并两个有序的链表

一.题目 合并两个有序的链表并使新链表也是有序排列. 二.算法实现 1 ListNode* Merge(ListNode* pHead1, ListNode* pHead2) 2 { 3 if (pHead1 == NULL) 4 return pHead2; 5 else if (pHead2 == NULL) 6 return pHead1; 7 ListNode *pNewHead = NULL, *pNode1 = NULL, *pNode2 = NULL; 8 if (pHead1->

Leetcode:Merge Two Sorted Lists 合并两个有序单链表

Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists. 代码如下: * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x

算法题——合并两条有序的链表

题目:给定两个已排序的链表,返回合并后的链表. 思路:将链表L2的每个结点插入到链表L1中,时间复杂度为O(m+n),m.n分别为两条链表的长度. 代码: 1 struct ListNode 2 { 3 int value; 4 ListNode *next; 5 ListNode(int v): value(v), next(NULL) 6 { 7 } 8 }; 9 10 ListNode *mergeSortedList(ListNode *L1, ListNode *L2) 11 { 12

合并两个有序单链表

给出两个有序的单链表,将这两个单链表进行合并,合并出来的链表仍然是有序的. 比如给出链表1:1->3->6->7;链表2:2->4->5->8->9 合并后的链表为:1->2->3->4->5->6->7->8->9 代码展示如下(只给出实现部分) 结构体定义: typedef struct LinkNode { DataType data; struct LinkNode *next; }LinkNode,*pLi

链表:合并两个有序的链表

题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 解题思路 两种解法:递归和非递归 这个题目就是归并排序中的归并操作,将两个有序数组(链表)合并为一个有序的数组. 非递归: 第一个while循环,将 l1 和 l2 进行比较,谁小谁就合并到 listNode,直到 l1 或者 l2 为空 第二个while循环和第三个while循环,将 l1 或者 l2 剩下的节点合并到 listNode 最后返回的是 firstNode.next //头节点

算法题:合并两个有序的链表

说明:本文仅供学习交流,转载请标明出处,欢迎转载! 题目:已知有两个有序的单链表,其头指针分别为head1和head2,实现将这两个链表合并的函数: Node* ListMerge(Node *head1,Node *head2) 这个算法很像我们排序算法中的归并排序,只能说“很像”,因为思想是一样的,但是这个与归并排序还是有区别的,区别如下:      1.归并排序是针对有序数组,而这里是有序链表:        2.归并排序排序的时间复杂度为o(nlogn),而这里的时间复杂度最坏情况下为O

合并两个有序单链表的操作

/*以合并两个2个长度均为n的递增单链表为例 演示连个单链表的合并操作*/ #include<iostream>#include<algorithm>#include<cstring>#include<vector>#include<stdio.h>#include<queue>#include<math.h>#define INF 0x3f3f3f3f#define MAX 1000005#define Temp 100

剑指OFFER——合并两个有序的链表

输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 再做这道题就是想不起来书上怎么做的了,但是最近看STL里面全是这种基础的合并啊,比较啊.就算不会也看会了. 循环我用了4个指针.p和q分别指向两个链表当前需要比较的元素,l和k分别代表“新”的链表的旧节点和新节点,防止断了. 每次新比较的结果给k,l代表之前的节点. 循环: /* struct ListNode { int val; struct ListNode *next; ListNode(int

MergeSortedArray,合并两个有序的数组

问题描述:You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. The number of elements initialized in nums1 and nums2 are m and n respectively. 算法分析:合并两个数组,但是合并后的数组是原来的数组1,不能新建空间,假设数组1有