合并两个有序的链表

来源:互联网 发布:js给div赋值 编辑:程序博客网 时间:2024/05/19 22:28

题目输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。例如输入两个链表分别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;}

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


1 0
原创粉丝点击