思路:链表操作最重要的就是头,合并两个有序链表,合并后的链表头常规操作有两种,一是malloc一个实体头,二是选其中一个链表的头来当新头。用第一种记得函数返回的时候用->next,再释放申请的头,不然会造成内存泄漏。在此用的第二种方法
1,比较两个链表的头节点值,值小的那个链表头当合并后链表的头
2,申请一个尾指针,最开始指向头节点
3,循环比较两个链表的节点值,谁小就接到尾节点上去
4,最后跳出循环,如果有一个链表没有扫描完,把未扫描完的链表直接接到尾节点后面,因为原始链表也是有序的
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2)
{
// write code here
if(l1 == NULL && l2 != NULL)
return l2;
if(l1 != NULL && l2 == NULL)
return l1;
if(l1 == NULL && l2 == NULL)
return NULL;
struct ListNode *pL1 = l1;
struct ListNode *pL2 = l2;
struct ListNode *phead = (pL1->val > pL2->val? pL2:pL1);;
struct ListNode *tail = phead;
//以第一个元素小的为锚点
pL1 = (phead == pL1? pL1->next:pL1);
pL2 = (phead == pL2? pL2->next:pL2);
while(pL1 != NULL && pL2 != NULL)
{
if(pL1->val <= pL2->val)
{
tail -> next = pL1;
pL1 = pL1 -> next;
}
else
{
tail -> next = pL2;
pL2 = pL2 -> next;
}
tail = tail->next;
}
tail->next = (pL1==NULL?pL2:pL1);
return phead;
}
该题还有优化的空间,通过上面的代码可以看到其实可以直接操作指针l1和l2,这样可以节省两个循环指针pL1和pL2的8个字节空间,但是实际项目中的规范让我习惯申请两个临时指针,为了不破坏原链表头(其实这里的操作就已经破坏了原链表)