面试题—数据结构之单链表详述(基本篇4)---有序单链表的合并

来源:互联网 发布:如何防止网络渗透策反 编辑:程序博客网 时间:2024/05/18 01:57

          有序单链表的合并。已知两个链表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;          //指向head1head->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;//因为先要两链表其中的一个头给headnode *head = MergeRecursive(head1, head2);print(head);return 0;}