问题:合并两个有序的链表,合并后结果任有序
非递归实现:两个指针分别遍历两个链表,然后比较两个指针大小,将小的节点取下放到合并后的新链表中,继续向后移动当前的指针,若两个链表至少有一个表扫描走完,走将对应的另一个表,整体添加合并后的新表中,这样就可以实现链表的合并。
方法一:
ListNode* MergeList1(ListNode*l1, ListNode*l2)
{
if (l1 == NULL)
return l2;
if (l2 == NULL)
return l1;
ListNode*p1 = l1;//指针p1用来遍历链表l1;
ListNode*p2 = l2;//指针p1用来遍历链表l2;
ListNode*newhead = NULL;//表示合并后的头节点
if (l1->_data < l2->_data)//先取l1的节点,然后链上新节点
{
newhead = l1;
p1 = l1->_next;
}
else//表示先取l2的节点
{
newhead = l2;
p2 = l2->_next;
}
ListNode*p = newhead;//指针p永远指向合并后最新的节点
while (p1&&p2)//此时至少有一个链表已经走到尾
{
if (p1->_data < p2->_data)
{
p->_next = p1;
p1 = p1->_next;
}
else
{
p->_next = p2;
p2 = p2->_next;
}
p = p->_next;
}
if (p1)//链表l1没走完
{
p->_next = p1;
}
else if (p2)//链表l2没走完
{
p->_next = p2;
}
return newhead;
}
方法一的特点是非递归,指针使用要小心,代码比较多,时间复杂度O(max(ll1,l2));
方法二:递归实现:
ListNode*MergeList2(ListNode*l1, ListNode*l2)
{
if (l1 == NULL)
return l2;
if (l2 == NULL)
return l1;
ListNode*newhead = NULL;//合并后的头结点
if (l1->_data < l2->_data)
{
newhead = l1;
newhead->_next = MergeList2(l1->_next, l2->_next);
}
else
{
newhead = l2;
newhead->_next = MergeList2(l1->_next, l2->_next);
}
return newhead;
}
将l1和l2比较,结果小的链上新节点,知道走到递归终止条件l1为空,或者是l2为空,这样就可以实现链表的合并了;递归实现,主要是找到递归出口,但这种时间和空间复杂度高,尤其是节点比较多,递归的深度很深时,会不断的压栈,有很大的开销。
方法三:list迭代器
bool Compare(int l1, int l2)//升序
{
return l1 < l2;
}
void Testlist()
{
list<int> l1, l2;
l1.push_back(1);
l1.push_back(3);
l1.push_back(5);
l1.push_back(7);
l2.push_back(2);
l2.push_back(4);
l2.push_back(6);
l2.push_back(8);
l1.merge(l2, Compare);
list<int>::iterator it = l1.begin();
while (it!=l1.end())
{
cout << *it << "->";
++it;
}
cout << endl;
}
通过仿函数比较两个链表的大小,然后调用库里面的merge函数实现合并链表的合并,通过迭代器遍历整个链表。
方法三:主要是对库中list的成员函数要求比较熟悉,同时要掌握迭代器的相关知识。时间复杂度O(1);最高效;
四:完整代码:
struct ListNode
{
ListNode* _next;
int _data;
ListNode(int data)
:_data(data)
{}
};
void CleanList(ListNode*head)
{
ListNode*cur = head;
if (cur == NULL)
{
return;
}
while (cur)
{
ListNode*tmp = cur->_next;
delete cur;
cur = tmp;
CleanList(cur);
}
}
void Printlist(ListNode*head)
{
ListNode *cur = head;
while (cur)
{
cout << cur->_data << "->";
cur = cur->_next;
}
cout << endl;
}
//方法一:非递归实现
ListNode* MergeList1(ListNode*l1, ListNode*l2)
{
if (l1 == NULL)
return l2;
if (l2 == NULL)
return l1;
ListNode*p1 = l1;//指针p1用来遍历链表l1;
ListNode*p2 = l2;//指针p1用来遍历链表l2;
ListNode*newhead = NULL;//表示合并后的头节点
if (l1->_data < l2->_data)//先取l1的节点,然后链上新节点
{
newhead = l1;
p1 = l1->_next;
}
else//表示先取l2的节点
{
newhead = l2;
p2 = l2->_next;
}
ListNode*p = newhead;//指针p永远指向合并后最新的节点
while (p1&&p2)//此时至少有一个链表已经走到尾
{
if (p1->_data < p2->_data)
{
p->_next = p1;
p1 = p1->_next;
}
else
{
p->_next = p2;
p2 = p2->_next;
}
p = p->_next;
}
if (p1)//链表l1没走完
{
p->_next = p1;
}
else if (p2)//链表l2没走完
{
p->_next = p2;
}
return newhead;
}
//方法二:递归的实现
ListNode*MergeList2(ListNode*l1, ListNode*l2)
{
if (l1 == NULL)
return l2;
if (l2 == NULL)
return l1;
ListNode*newhead = NULL;//合并后的头结点
if (l1->_data < l2->_data)
{
newhead = l1;
newhead->_next = MergeList2(l1->_next, l2->_next);
}
else
{
newhead = l2;
newhead->_next = MergeList2(l1->_next, l2->_next);
}
return newhead;
}
//方法三list的迭代器的实现
bool Compare(int l1, int l2)//升序
{
return l1 < l2;
}
void Testlist()
{
list<int> l1, l2;
l1.push_back(1);
l1.push_back(3);
l1.push_back(5);
l1.push_back(7);
l2.push_back(2);
l2.push_back(4);
l2.push_back(6);
l2.push_back(8);
l1.merge(l2, Compare);
list<int>::iterator it = l1.begin();
while (it!=l1.end())
{
cout << *it << "->";
++it;
}
cout << endl;
}
//创建链表l1.
ListNode* CreateList1()
{
ListNode*head;
ListNode*n1 = new ListNode(1);
ListNode*n3 = new ListNode(3);
ListNode*n5 = new ListNode(5);
ListNode*n7 = new ListNode(7);
head = n1;
n1->_next = n3;
n3->_next = n5;
n5->_next = n7;
n7->_next = NULL;
return head;
}
//创建链表l2
ListNode* CreateList2()
{
ListNode*head;
ListNode*n2 = new ListNode(2);
ListNode*n4 = new ListNode(4);
ListNode*n6 = new ListNode(6);
ListNode*n8 = new ListNode(8);
head = n2;
n2->_next = n4;
n4->_next = n6;
n6->_next = n8;
n8->_next = NULL;
return head;
}
void TestListNode1()
{
ListNode*l1 = CreateList1();
ListNode*l2 = CreateList2();
cout << "合并前链表l1" << endl;
Printlist(l1);
cout << "合并前链表l2" << endl;
Printlist(l2);
cout << "非递归的实现" << endl;
ListNode *newhead = MergeList1(l1, l2);
Printlist(newhead);
cout << "递归的实现" << endl;
ListNode*newhead1 = MergeList2(l1, l2);
Printlist(newhead1);
cout << "list迭代器实现" << endl;
Testlist();
CleanList(newhead);
CleanList(newhead1);
}
int main()
{
TestListNode1();
system("pause");
return 0;
}