有序单链表的合并。已知两个链表head1和head2各自有序,请把它们合并成一个链表并且依然有序,分别使用非递归方法以及递归方法。
解析:
首先介绍非递归方法。因为两个链表head1和head2都是有序的,所以只需要把较短链表的各个元素有序插入到较长链表之中就可以了。
程序代码:
//正向插入节点
node *insert_node(node *head, node *item)
{
node *p = head;
node *q = NULL; //指向p之前的节点
while(p->data < item->data && p != NULL)
{
q = p;
p = p->next;
}
if(p == head) //插入到原头节点之前
{
item->next = p;
return head;
}
//插入到q与p之间
q->next = item;
item->next = p;
return head;
}
int length(node *head)
{
int len = 0;
node *p = head;
while(NULL != p)
{
len++;
p = p->next;
}
return len;
}
//两个有序链表进行合并
node *my_merge(node *head1, node *head2)
{
node *head = NULL; //指向合并后的链表
node *p = NULL;
node *nextP = NULL; //指向p之后
if(NULL == head1) //有一个链表为空,直接返回另一个链表
{
return head2;
}
if(NULL == head2)
{
return head1;
}
//两个链表都不为空
if(length(head1) > length(head2)) //选取较短的链表
{ //这样进行的插入次数要少
head = head1;
p = head2;
}
else
{
head = head2;
p = head1;
}
while(NULL != p)
{
nextP = p->next; //保存p的下一个节点
head = insert_node(head, p);//把p插入到目标链表中
p = nextP; //指向将要插入的下一个节点
}
return head;
}
这里insert_node()函数是有序节点的插入,注意与前面文章中的函数区别,这里它传入的参数是node* 类型。然后再my_merge()函数中循环把短链表中的所有节点插入到长链表中。
接下来介绍递归方法。假设有下面两个链表。
链表1:1 -> 3 -> 5
链表2:2 -> 4 -> 6
递归方法步骤如下:
(1)比较链表1和链表2的第1个节点数据,由于 1 < 2, 因此把结果链表头节点指向链表1中的第1个节点,即数据1所在的节点。
(2)对剩余的链表1(3->5)和链表2再调用(1)的方法,比较得到结果链表的第2个节点,即2与3比较得到2,此时合并后的链表节点为1->2。如此递归直到连个链表的节点都被加到结果链表中,程序代码如下:
//递归方法合并两个有序链表
node *MergeRecursive(node *head1, node *head2)
{
node *head = NULL;
if(NULL == head1)
{
return head2;
}
if(NULL == head2)
{
return head1;
}
if(head1->data < head2->data)
{
head = head1; //指向head1
head->next = MergeRecursive(head1->next, head2);
}
else
{
head = head2;
head->next = MergeRecursive(head1, head2->next);
}
return head;
}
下面是测试程序:
void print(node *head)
{
node *p = NULL;
int index = 0;
if(NULL == head->next)
{
printf("Link is empty!\n");
return ;
}
p = head->next;
while(NULL != p)
{
printf("the %dth node %d\n", ++index, p->data);
p = p->next;
}
}
int main()
{
node *head1 = create();
node *head2 = create();
//node *head = my_merge(head1, head2);
head1 = head1->next; //因为先要两链表其中的一个头给head
node *head = MergeRecursive(head1, head2);
print(head);
return 0;
}