欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

合并两个递增排序的链表,合并后仍递增有序。

程序员文章站 2022-04-21 23:27:42
...

这是面试中经常被提到的问题。下图表示链表1和链表2合并成链表3:

合并两个递增排序的链表,合并后仍递增有序。

1.用递归算法更加简单好理解,即链表1的头结点值小于链表2头结点的值,我们就将链表1作为合并后链表的头结点,在剩余结点中,链表2的头结点值小于链表1头结点的值,我们将链表二的头结点作为合并链表的后续结点,且剩余结点依然是有序的,合并的步骤和之前一样,如下图:

合并两个递增排序的链表,合并后仍递增有序。

递归代码如下:

ListNode* Merge(ListNode* pHead1,ListNode* phead2)
{
	if(pHead1 == NULL)
		return pHead2;
	else if(pHead2 == NULL)
		return pHead1;
	ListNode* pMergedHead = NULL;

	if(phead1 -> m_nValue < pHead2 -> m_nValue)
	{
		pMergedHead = pHead1;
		pMergedHead -> m_pNext = Merge(pHead1 -> m_pNext , pHead2);
	}
	else
	{
		pMergedHead = pHead2;
		pMergedHead -> m_pNext = Merge(pHead1,pHead2 -> m_pNext);
	}
	return pMergedHead;
}

2.用指针分别指向两个链表的第一个节点,比较大小,那个大,将元素尾插进入我所要返回的新链表中去。一次比较循环往复,直至某一个链表为空为止。但有可能会出现一个链表为空,另一个链表不为空。我们就要在最后检测,将不为空链表的全部挂在我要返回元素的后面。因为要不停的给新链表尾插。所以我用一个指针,将新链表的尾部标记。代码如下:

typedef int DataType;

typedef struct ListNode
{
	DataType _data;			//当前节点中所保存的元素
	struct ListNode* _pNext;	//指向链表中下一个结点

}SLinkList, SListNode;

SLinkList* MergeLinkListOP(SLinkList* pHead1, SLinkList* pHead2)
{
	SLinkList* New = NULL;//合并后的链表
	SLinkList* tail = NULL;//标记合并后链表的尾部,方便尾插
	SLinkList* cur1 = pHead1;
	SLinkList* cur2 = pHead2;
	SLinkList* nxt = NULL;//用来保存链表的后续节点
	SLinkList* node = NULL;
	while (cur1 != NULL && cur2 != NULL)
	{
		if (cur1->_data <= cur2->_data)
		{
			node = cur1;//应取链表1的结点
		}
		else
		{
			node = cur2;
		}
		
		nxt = node->_pNext;//保存cur1后面的节点:将cur1指向的结点从链表1上取下来,挂在新链表上,后序的链表应该保存下来,否则程序会奔溃
		if (New == NULL)//合并的链表为空
		{	
			New = node;//将cur1指向的结点挂在新链表上
		}
		else//合并链表不为空
		{	
			tail->_pNext = node;
		}
		node->_pNext = NULL;//尾插,链表的最后一个元素应为空
		tail = node;//保存新链表的最后一个节点
		if (node == cur1)//已经将节点挂在新链表上,循环应该让cur1 和 cur2改变,因此在这里应该让cur前进
		{
			cur1 = nxt;
		}
		else
		{
			cur2 = nxt;
		}
	}	
	if (cur1 == NULL)//一个链表空了,但要判断里另一个链表为不为空
		tail->_pNext = cur2;
	if (cur2 == NULL)
		tail->_pNext = cur1;

	return New;
}


 

相关标签: 程序