标签:
题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。例如输入两个链表分别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; }
依旧不难,这里就不在赘述了。
标签:
原文地址:http://blog.csdn.net/qq_33724710/article/details/51362043